【问题标题】:BindingSource ListChanged event fires on position changes位置更改时触发 BindingSource ListChanged 事件
【发布时间】:2016-12-28 05:15:15
【问题描述】:

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

但在我的示例中,事件会在每次位置更改时触发。 Form 有一个 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;
}

当我使用“文本”属性绑定控件时,不会发生 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 却没有?

提前致谢, 克里斯蒂安

【问题讨论】:

    标签: c# data-binding user-controls


    【解决方案1】:

    为什么 Text 属性按预期工作,而 MyProperty 却没有?

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

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

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

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

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

    【讨论】:

    • 感谢 Ivan 的精彩回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 2021-05-18
    • 2010-09-22
    • 1970-01-01
    相关资源
    最近更新 更多