c# - 引用并存储动态创建的控件中的数据?

标签 c# sqlite dynamic user-controls

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

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

https://www.dropbox.com/s/o2pub6orww24w25/tasklist.png (这是为了更清楚而截图)

现在我想要做的是将每行的值(行定义为:文本框、日期、状态)保存到 SQLite 数据库中。

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

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

问题 b) 我如何告诉我的程序每一行都是一组新数据?换句话说,如何为每一行运行新的插入命令? -我想将其作为 for-each-textbox 循环来执行,但这不是每次都会获取第一个动态日期吗?

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

代码:

添加控件:

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 网站中研究找到 Control.Find 函数]

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 参数始终包含对引发事件的任何控件的引用,在本例中是单击了哪个图片框!

编辑:至于您的其他问题,我假设您稍后需要对控件进行操作,因此我建议您存储对所有控件(或至少是您需要的控件)的引用,如下所示:

// 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 ) );
}

然后您可以使用该列表中的项目与您的行进行交互。您可能还想添加索引或对原始数据结构的引用。另外,您可能需要考虑是否真的应该像这样自己创建控件,或者实际上使用某种表格/网格控件来托管它们!

或者也许只是将所有这些控件包装在一个 UserControl 中,其中包含所有逻辑!

关于c# - 引用并存储动态创建的控件中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24813848/

相关文章:

C,具有多个动态分配数组的结构是否需要为每次分配调整大小?

C - 没有函数指针的动态函数调用

c# - 在C#.NET Dim语句中创建共鸣板不会变成蓝色

C# smtp.google.com 无法解析

c# - 为什么相同的 DateTime 值会为不同的用户产生不同的显示时间?

c# - SOA问题: Exposing Entities

android - 如何在 android 中使用 ViewFlipper 显示来自 sqlite 的内容

sql - SQL查询排除记录

sqlite - SQLite 实现中 xamarin.forms 中的 FileNotFoundException

c++ - C++ 中矩阵类的性能