如何使用与OnPropertyChanged一起使用的UserControl的可绑定属性

我有一个简单的usercontrol(WinForms)与一些公共属性。 当我使用此控件时,我想数据绑定到DataSourceUpdateMode设置为OnPropertyChanged的那些属性。 数据源是一个实现INotifyPropertyChanged的类。

我知道需要为属性创建绑定,我正在这样做。

我假设我的usercontrol必须实现一个接口,或者属性需要用某些属性进行修饰,或者沿着那些行进行修饰。但是我的研究空白了。

该如何实现? 目前我正在通过在属性更改时在我的usercontrol中调用OnValidating()来实现它,但这似乎不正确。

如果我在用户控件上将CausesValidation设置为true,我可以进行validation,但这对我来说并不是很有用。 我需要validation每个子属性的变化。

请注意,这是WinForms的情况。

编辑:显然我没有解释的天赋,所以希望这将澄清我在做什么。 这是一个简短的例子:

// I have a user control public class MyControl : UserControl { // I'm binding to this property public string ControlProperty { get; set; } public void DoSomething() { // when the property value changes, the change should immediately be applied // to the bound datasource ControlProperty = "new value"; // This is how I make it work, but it seems wrong OnValidating(); } } // the class being bound to the usercontrol public class MyDataSource : INotifyPropertyChanged { private string sourceProperty; public string SourceProperty { get { return sourceProperty; } set { if (value != sourceProperty) { sourceProperty = value; NotifyPropertyChanged("SourceProperty"); } } } // boilerplate stuff public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string info) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public class MyForm : Form { private MyControl myControl; public MyForm() { // create the datasource var dataSource = new MyDataSource() { SourceProperty = "test" }; // bind a property of the datasource to a property of the usercontrol myControl.DataBindings.Add("ControlProperty", dataSource, "SourceProperty", false, DataSourceUpdateMode.OnPropertyChanged); // note the update mode } } 

(我使用BindingSource尝试了这个,但结果是一样的。)

现在我想要发生的是,当MyControl.ControlProperty的值发生变化时,更改会立即传播到数据源(MyDataSource实例)。 为了实现这一点,我在更改属性后在usercontrol中调用OnValidating()。 如果我不这样做,我必须等到焦点更改触发validation,这相当于“OnValidation”更新模式,而不是所需的“OnPropertyUpdate”validation模式。 我只是不想在更改属性值之后调用OnValidating()是正确的事情,即使它(种类)有效。

假设调用OnValidating() 不是正确的方法,我是否正确? 如果是这样,我如何通知ControlProperty更改的数据源?

我想我已经搞清楚了。 我不明白如何将更改通知从控件发送到绑定数据源。

是的,调用OnValidating()是错误的方法。

从我拼凑到的内容来看,控件可以通过两种方式通知数据源属性已更改。

一种方法是控件实现INotifyPropertyChanged。 我以前从未在控制端做过这个,我认为只有绑定的数据源端必须实现它。

当我在我的用户控件上实现INotifyPropertyChanged,并在适当的时候引发了PropertyChanged事件时,它工作正常。

第二种方法是控件为每个属性引发特定的更改事件。 事件必须遵循命名约定: Changed

例如,对于我的例子,它将是

public event EventHandler ControlPropertyChanged

如果我的财产被称为Foo,那将是FooChanged

我没有注意到MSDN 文档的相关部分,它说:

要在绑定客户端和数据源之间的绑定中发生更改通知,您的绑定类型应该是:

实现INotifyPropertyChanged接口(首选)。

为绑定类型的每个属性提供更改事件。

第二种方式是所有现有的WinForms控件如何工作,所以这就是我现在正在做的事情。 我在我的数据源上使用了INotifyPropertyChanged,但是我在我的控件上引发了Changed事件。 这似乎是传统方式。

实现INotifyPropertyChanged接口非常简单。 这是一个示例,显示具有单个公共字段的对象…

 public class Demo : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(info)); } private string _demoField; public string DemoField { get {return demoField; } set { if (value != demoField) { demoField = value; NotifyPropertyChanged("DemoField"); } } } } 

然后,您将创建一个Binding实例,以将控件属性绑定到源实例(Demo的实例)上的属性(DemoField)。