数据绑定更新父表单上的变量

时间:2016-01-14 15:36:21

标签: c# winforms data-binding

我希望能够将对象列表传递给子窗体,将其绑定到某些控件,从这些控件编辑列表的属性,然后仅在用户单击时将此修改后的列表传回父窗体好。如果用户转义或单击取消,则我不希望原始列表更新。

好的,所以我从父母那里打开一个子表单,将列表传递给该表单,如下所示:

List<Names> nameList = new List<Names>();
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
    using (Form2 fm2 = new Form2(nameList))
    {
        fm2.ShowDialog();
        if (fm2.NameListProperty != null)
        {
            nameList = fm2.NameListProperty;
        }            
    }
}

在我的子表单Form2上,我将列表绑定到ListBox和TextBox:

List<Names> nameList = new List<Names>();

public List<Names> NameListProperty { get; set; }

public Form2(List<Names> nameListPassed)
{
    InitializeComponent();

    nameList = nameListPassed;

    BindingSource bs = new BindingSource();
    bs.DataSource = nameList;
    listBoxNames.DataSource = bs;
    listBoxNames.DisplayMember = "FullName";                
    txtSurname.DataBindings.Add("Text", bs, "Surname", true, DataSourceUpdateMode.OnPropertyChanged);       
}

然后,当用户单击“确定”按钮时,该属性将设置为已修改的nameList。如果用户未单击“确定”,即转义或单击“取消”,则不会设置该属性并保持为null,并且不应将其分配回父窗体Form1上的主名称列表。

private void btnOK_Click(object sender, EventArgs e)
{
    NameListProperty = nameList;
    this.Close();
}

但是,问题是无论用户如何关闭子表单,父表单上的列表都会更新。用于将列表传递回父表单的属性已过时,因为无论如何父表单上的列表都会更新。我想我的问题是如何阻止这种情况发生,以便我可以选择是否将子表单中的更改传递回父表单。

1 个答案:

答案 0 :(得分:2)

List<Names>reference typeNames类也是nameList.ToList()。当您将此类列表传递给另一个表单时,会自动反映添加,删除或元素更新,因为它是同一个列表/对象实例。

为了实现所需的行为,您需要传递列表的克隆。请注意,仅使用var nameListCopy = nameList.Select(n => new Names { Property1 = n.Property1, Property2 = n.Property2, // ... the rest of the properties }).ToList(); using (Form2 fm2 = new Form2(nameListCopy)) // ... 是不够的,因为它会创建浅层副本,而您确实需要深层副本。一种可能的方法是使用这样的东西

Names

如果您的class Names { // ... public Names Clone() { return (Names)this.MemberwiseClone(); } } 是简单数据类(不包含可变引用类型属性/字段),则可以使用以下

var nameListCopy = nameList.Select(n => n.Clone()).ToList();

然后

list = [one, two, three]
for item in list:
    def item():
         some_stuff()