Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从动态创建的控件中引用和存储数据?_C#_Sqlite_Dynamic_User Controls - Fatal编程技术网

C# 从动态创建的控件中引用和存储数据?

C# 从动态创建的控件中引用和存储数据?,c#,sqlite,dynamic,user-controls,C#,Sqlite,Dynamic,User Controls,我有一个问题,我已经研究了几天了,我只是想不出一个合乎逻辑的方式来做我想做的事 我有一个有任务列表的应用程序。它从三个控件开始:一个文本框,一个日期时间选择器和一个图片框,点击后可以改变图像。然后,用户可以按一个图像,该图像将在下面添加另一行控件(它从已创建的控件中获取动态控件的属性): (这是一个屏幕截图,让它更清晰) 现在我要做的是将每一行(一行定义为:Textbox、Date、Status)的值保存到SQLite数据库中 对于第一行很容易,因为它有一个唯一的设计名称(并且是一个“静态”控件

我有一个问题,我已经研究了几天了,我只是想不出一个合乎逻辑的方式来做我想做的事

我有一个有任务列表的应用程序。它从三个控件开始:一个文本框,一个日期时间选择器和一个图片框,点击后可以改变图像。然后,用户可以按一个图像,该图像将在下面添加另一行控件(它从已创建的控件中获取动态控件的属性):

(这是一个屏幕截图,让它更清晰)

现在我要做的是将每一行(一行定义为:Textbox、Date、Status)的值保存到SQLite数据库中

对于第一行很容易,因为它有一个唯一的设计名称(并且是一个“静态”控件)。 但是,当我尝试保存动态控件中的值时,问题出现了:

问题a)我无法引用动态控件,因为“它在当前上下文中不存在”-创建控件的函数有一个公共访问修饰符,所以我认为应该这样做-没有。我也试过:
Panel1.pb.blah
但它仍然无法识别控件

问题b)我如何告诉我的程序每一行都是一组新的数据?换句话说,如何为每一行运行新的insert命令-我想这样做是为了每个文本框循环一次,但这不是每次都会拾取第一个动态日期吗

我还考虑过使用tag属性并将其设置为计数器变量,以便对行中的控件进行分组。(计数器是一个整数,每次添加新行时递增。)但是我不能这样做,因为图片框使用tag属性作为其函数的一部分,在单击时更改图像(更改多次)

代码:

添加控件:

public void pictureBox1_Click(object sender, EventArgs e)
    {
        //TextBox Control
        int tbh = tasktb.Location.Y + (counter*25);
        int tbsh = tasktb.Size.Height;
        int tbsw = tasktb.Size.Width;
        TextBox tb = new TextBox();
        tb.Location = new Point(9, tbh);
        tb.Size = new System.Drawing.Size(tbsw, tbsh);
        tb.Tag = counter.ToString();
        //Date Time Control
        int dth = duedatedb.Location.Y + (counter * 25);
        int dtsh = duedatedb.Size.Height;
        int dtsw = duedatedb.Size.Width;
        DateTimePicker dtp = new DateTimePicker();
        dtp.Location = new Point(300, dth);
        dtp.Size = new Size(dtsw, dtsh);
        dtp.Format = System.Windows.Forms.DateTimePickerFormat.Short;
        //Picture Box Control
        int stsh = status.Location.Y + (counter * 25);
        int stssh = status.Size.Height;
        int stssw = status.Size.Width;
        PictureBox pb = new PictureBox();
        pb.Location = new Point(429, stsh);
        pb.Size = new Size(stssw, stssh);
        pb.Image = Red;
        pb.Click += new System.EventHandler(pb_Click);


        panel1.Controls.Add(tb);
        panel1.Controls.Add(dtp);
        panel1.Controls.Add(pb);
        ++counter;
    }
尝试引用该控件:(为了在单击时更改图像)[在MSDN网站中查找该控件。查找函数]

public void pb_Click(object sender, EventArgs e)
    {
        PictureBox pb = (panel1.Controls.Find("pb",false)); 
        if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
        else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
        else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
    }
这里最基本的问题是问题a,如果你们能看到我在这方面出了什么问题,我就可以离开并尝试编写一些代码来解决问题b。 (我已经将问题b包括在这篇文章中,以征求您对最佳方法的建议。-目前我没有任何线索!)


谢谢你的帮助!非常感谢

ControlCollection.Find
查找具有指定名称的控件,但尚未设置任何名称。代码中的变量名不相关。因此,要么:

pb.Name = "pb";
但这意味着您最终会有几个同名的项目。因此,如果您想更改单击的PictureBox的图片,只需执行以下操作:

public void pb_Click(object sender, EventArgs e)
{
    PictureBox pb = (PictureBox)sender;
    if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
    else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
    else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
}
sender
参数始终包含对引发事件的控件的引用,在本例中,无论单击哪个picturebox

编辑:至于你的另一个问题,我假设你以后需要对控件做一些事情,所以我建议你存储对所有控件(或者至少是你需要的控件)的引用,类似这样:

// helper class
private class Entry
{
    public TextBox TextBox { get; private set; }
    public DateTimePicker DateTimePicker { get; private set; }
    public PictureBox PictureBox { get; private set; }

    public Entry( TextBox tb, DateTimePicker dtp, PictureBox pb )
    {
        this.TextBox = tb;
        this.DateTimePicker = dtp;
        this.PictureBox = pb;
    }
}

// member field
private List<Entry> m_Entries = new List<Entry>();

// at the end of pictureBox1_Click
public void pictureBox1_Click(object sender, EventArgs e)
{
    ....
    m_Entries.Add( new Entry( tb, dtp, pb ) );
}
//助手类
私人班级入学
{
公共文本框文本框{get;private set;}
公共日期时间选择器日期时间选择器{get;private set;}
公共PictureBox PictureBox{get;private set;}
公共输入(文本框tb、日期时间选择器dtp、PictureBox pb)
{
this.TextBox=tb;
this.DateTimePicker=dtp;
这个.PictureBox=pb;
}
}
//成员字段
私有列表m_条目=新列表();
//在图片的末尾单击
public void pictureBox1\u单击(对象发送方,事件参数e)
{
....
m_条目。添加(新条目(tb、dtp、pb));
}
然后可以使用该列表中的项目与行进行交互。您可能还希望添加索引或对原始数据结构的引用。此外,您可能还想考虑是否真的应该自己创建控件,或者实际使用某种表/网格控件来承载它们


或者干脆将所有这些控件封装在一个
UserControl
中,包含逻辑和全部

太棒了,编译得很完美。感谢You@BlakeWills你必须给男人+1并接受答案。我正要建议完全相同的事情,如果我可以(没有足够的代表在这个帐户上这样做!)&我会接受答案