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

标签 c# data-binding user-controls

来自微软: “当基础列表更改或列表中的项目更改时,会发生 BindingSource.ListChanged 事件”。

但在我的示例中,每次位置更改都会触发该事件。该表单有一个 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”属性绑定(bind)控件时,ListChanged 事件不会按预期发生:

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

但是当我使用“MyProperty”属性绑定(bind)控件时,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 窗体数据绑定(bind)支持两种类型的源对象更改通知 - 实现 INotifyPropertyChanged 的​​对象或提供 {PropertyName}Changed 命名事件的对象。

现在看看您的用户控件。首先,它没有实现 INotifyPropertyChanged。但是,有一个事件名为 TextChanged ,因此当您将数据绑定(bind)到 Text 属性时,BindingSource 将使用该事件来触发 ListChanged。但是,当您绑定(bind)到 MyProperty 时,由于没有名为 MyPropertyChanged 的事件,数据绑定(bind)基础结构会尝试使用 ListChanged 事件来模拟它。 位置(因此当前对象)发生变化。

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

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

与您的属性的数据绑定(bind)将按预期工作。

关于c# - BindingSource ListChanged 事件在位置更改时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39066217/

相关文章:

c# - mysqldatareader连接已关闭

c# - 矩形不改变颜色WPF

wpf - 将 ListBoxItem 的 IsSelected 属性绑定(bind)到对象源的属性

c# - FormatterServices.GetUninitializedObject 如何在内部工作?

c# - 使用 TFS 2012 构建服务器构建 VS2017 项目

wpf - 用于数据绑定(bind)的 IntelliSense 不起作用

c# - 如何在 ASP.NET 中添加运行时的用户控件?

c# - wpf强制构建可视化树

javascript - 用户控制范围内的全局 JS 变量?

c# - Blazor (.net 7) 中的三种依赖注入(inject)语法有区别吗?