BindingSource ListChanged 事件在位置更改时触发

BindingSource ListChanged event fires on position changes

来自微软: "BindingSource.ListChanged Event occurs when the underlying list changes or an item in the list changes"。

但在我的示例中,事件会在每次位置更改时触发。表单有一个 UserControl、一个 BindingSource 和一个 Button。

用户控件有一个 TextBox 和两个属性:

    /// <summary>
    /// Is working: ListChanged is not fired
    /// </summary>
    public override string Text
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }

    /// <summary>
    /// Is not working: ListChanged is fired on Position changes
    /// </summary>
    public string MyProperty
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }

窗体上的按钮更改了 BindingSource 的位置:

void next_Click(object sender, EventArgs e)
{
    bindingsource.Position += 1;
}

当我使用 "Text" 属性 绑定控件时,ListChanged 事件没有发生,正如预期的那样:

myusercontrol1.DataBindings.Add("Text", bindingsource, "name");

但是当我使用 "MyProperty" 属性 绑定控件时,ListChanged 事件会在位置更改时触发:

myusercontrol1.DataBindings.Add("MyProperty", bindingsource, "name");

我尝试了不同的 DataSorces,如本例所示:

public Example()
{
    InitializeComponent();

    string xml = @"<states>"
        + @"<state><name>Washington</name></state>"
        + @"<state><name>Oregon</name></state>"
        + @"<state><name>Florida</name></state>"
        + @"</states>";
    byte[] xmlBytes = Encoding.UTF8.GetBytes(xml);
    MemoryStream stream = new MemoryStream(xmlBytes, false);
    DataSet set = new DataSet();
    set.ReadXml(stream);

    bindingsource.DataSource = set;
    bindingsource.DataMember = "state";
    bindingsource.ListChanged += BindingNavigator_ListChanged;

    myusercontrol1.DataBindings.Add("MyProperty", bindingsource, "name");
}

如何使用 MyProperty 并避免在位置更改时触发 ListChanged 事件?为什么 Text 属性 按预期工作但 MyProperty 不是?

提前致谢, 克里斯蒂安

Why Text property is working as expected but MyProperty is not?

都是关于更改通知的。您可能知道,Windows 表单数据绑定支持两种类型的源对象更改通知 - 实现 INotifyPropertyChanged 或提供 {PropertyName}Changed 命名事件的对象。

现在看看你的用户控件。首先,它没有实现 INotifyPropertyChanged。但是, 有一个名为 TextChanged 事件,因此当您将数据绑定到 Text 属性 时,BindingSource 将使用该事件开火 ListChanged。但是,当您绑定到 MyProperty 时,由于没有名为 MyPropertyChanged 的事件,因此当 Position(因此当前对象)变化。

话虽如此,将以下内容添加到您的用户控件中:

public event EventHandler MyPropertyChanged
{
    add { textBox1.TextChanged += value; }
    remove { textBox1.TextChanged -= value; }
}

并且数据绑定到您的 属性 将按预期工作。