【问题标题】:WinForms DataBinding with DataGridViewWinForms DataBinding 与 DataGridView
【发布时间】:2012-12-30 21:40:57
【问题描述】:

虽然我会发布这个,因为我花了几个小时试图解决这个问题,但我一无所获。首先,我完全意识到 WinForms 中的数据绑定并不是最好的。也就是说,它在大多数情况下都有效。

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

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

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

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

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

如果有任何不清楚的地方,我深表歉意,我已尽力解释混乱的情况。

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

【问题讨论】:

  • 我不知道是不是只有我,但我不明白是否所有绑定的对象都实现了INotifyPropertyChanged
  • 是的,所有被数据绑定的对象都实现了 INotifyPropertyChanged

标签: c# winforms data-binding datagridview


【解决方案1】:

这段代码对我来说很好用

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 实现

【讨论】:

  • 我基本上有相同的场景,唯一的区别是我没有将网格上的数据源设置为绑定列表,而是将其设置为 BindingSource,因为 BindingSource 的其他部分用于其他元素的形式。另外,我试图限制表单中的代码数量,因为它不适用于单元测试。不过谢谢你的建议。
  • 好的,我为 BindingSource 编辑了我的示例。我不知道您是否编码,但我发现您的 Children 属性是 BindingList 或 ObservableCollection 很重要,因为您不仅要通知 Children 分配,还要通知添加
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
相关资源
最近更新 更多