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

时间:2016-08-21 16:09:29

标签: c# data-binding user-controls

来自微软: “当基础列表发生更改或列表中的项目发生更改时,会发生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;
}

当我使用“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不是?

提前致谢, 克里斯蒂安

1 个答案:

答案 0 :(得分:2)

  

为什么文字属性按预期工作,但 MyProperty 不是?

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

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

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

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

和绑定到您的媒体资源的数据将按预期工作。