来自微软: “当基础列表发生更改或列表中的项目发生更改时,会发生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不是?
提前致谢, 克里斯蒂安
答案 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; }
}
和绑定到您的媒体资源的数据将按预期工作。