2013-01-16 48 views
3

我虽然我会发布这个花费了几个小时试图解决后,我无处可去。首先,我完全知道WinForms中的数据绑定并不是最好的。这表示它在大多数情况下都能正常工作。WinForms DataBinding与DataGridView

在我的场景中,我有一个绑定源,它是我的窗体的主人。用于此绑定源的对象也具有一些简单属性和两个绑定列表作为属性。这个类和绑定列表的类类型都实现INotifyPropertyChanged。在我的表单中,我有两个DataGridView用于显示绑定列表属性的内容。

这也是通过设计时的数据绑定完成的。我有两个绑定源,每个使用主绑定源作为数据源,然后使用各自的绑定列表属性作为数据成员。

到目前为止,我会认为这是相当标准的。

要更新这些列表中的内容,我有按钮来显示创建一个新项目的表单,然后使用BindingList.Add()将其添加到列表中。

现在在代码中,如果您调试,项目在列表中,但是,网格不会更新。 但是,如果我将列表框添加到只使用其中一个列表绑定源的窗体,那么两个网格都会按预期方式开始刷新。

我很抱歉,如果有任何不清楚的地方,我尽量以最好的方式解释一下这个令人困惑的情况。

任何想法都会有帮助,因为我真的不想使用隐藏列表框。

+0

我不知道这是否只是我或没有,但我没有,如果所有的理解对象绑定实现*** INotifyPropertyChanged *** – alexb

+0

是的,所有正在数据绑定的对象实现INotifyPropertyChanged –

回答

3

此代码工作正常,我

BindingList<Foo> source; // = ... 
private void Form1_Load(object sender, EventArgs e) 
{ 
    this.dataGridView1.DataSource = new BindingSource { DataSource = source }; 
    this.dataGridView2.DataSource = new BindingSource { DataSource = source, DataMember = "Children" }; 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    source.Add(new Foo { X = Guid.NewGuid().ToString() }); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    source[0].Children.Add(new FooChild { Y = Guid.NewGuid().ToString() }); 
} 

与模型

public class Foo : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    string x; 
    public string X 
    { 
     get { return x; } 
     set 
     { 
      x = value; 
      this.NotifyPropertyChanged(); 
     } 
    } 

    BindingList<FooChild> children; 
    public BindingList<FooChild> Children 
    { 
     get { return children; } 
     set 
     { 
      children = value; 
      this.NotifyPropertyChanged(); 
     } 
    } 
} 

public class FooChild : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    string y; 
    public string Y 
    { 
     get { return y; } 
     set 
     { 
      y = value; 
      this.NotifyPropertyChanged(); 
     } 
    } 
} 

两个网格得到刷新。

我希望这有助于你

编辑

我改变了Form1_Load的 IMPL

+0

我基本上有相同的情况,唯一的区别是,而不是设置数据源网格作为绑定列表,我将其设置为BindingSource,因为BindingSource的其他部分用于表单的其他元素。此外,我试图限制表单中的代码量,因为它在单元测试中效果不佳。但谢谢你的建议。 –

+0

好的,我编辑了BindingSource的示例。我不知道你是否编码,但我觉得你的Children属性是BindingList或ObservableCollection很重要,因为你不仅要通知儿童指定,而且还要添加 – alexb