c# - 如何拥有与 OnPropertyChanged 一起使用的 UserControl 的可绑定(bind)属性

标签 c# .net winforms data-binding user-controls

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

我知道需要针对属性创建绑定(bind),我正在这样做。

我假设我的用户控件必须实现一个接口(interface),或者属性需要用一些属性或类似的东西来装饰。但我的研究却一无所获。

这应该如何实现?目前我正在通过在属性更改时调用我的用户控件中的 OnValidating() 来完成此操作,但这似乎不正确。

如果我在用户控件上将 CausesValidation 设置为 true,我可以进行验证,但这对我来说不是很有用。我需要在更改时验证每个子属性。

请注意,这是 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 实例)。为此,我在更改属性后在用户控件中调用 OnValidating()。如果我不这样做,我必须等到焦点更改触发验证,这相当于“OnValidation”更新模式,而不是所需的“OnPropertyUpdate”验证模式。我只是不喜欢在更改属性值后调用 OnValidating() 是正确的做法,即使它(有点)有效。

我假设调用 OnValidating() 不是是执行此操作的正确方法吗?如果是这样,我如何将 ControlProperty 更改通知数据源?

最佳答案

我想我已经弄明白了。我不明白更改通知是如何从控件发送到绑定(bind)数据源的。

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

根据我的拼凑,控件可以通过两种方式通知数据源属性已更改。

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

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

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

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

public event EventHandler ControlPropertyChanged

如果我的属性名为 Foo,它将是 FooChanged .

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

For change notification to occur in a binding between a bound client and a data source, your bound type should either:

Implement the INotifyPropertyChanged interface (preferred).

Provide a change event for each property of the bound type.

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

关于c# - 如何拥有与 OnPropertyChanged 一起使用的 UserControl 的可绑定(bind)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6589012/

相关文章:

c# - 在 SortedDictionary 中找到第一个未使用的键的快速方法?

.net - 对于无效的文件名应该抛出哪个异常?

c# - 如何检查 DateTime 是否为空

c# - FXCop 自定义规则未出现在规则集中

.net - PowerShell等效于curl HTTP POST的文件传输

vb.net - 格式化文本框以始终显示 $ 符号

javascript - 将javascript变量获取到web浏览器控件winforms中

c# - Winforms 毫不客气地以 "unhandled exception"退出

c# - 在 WPF 中实现暂停

c# - 以编程方式向面板添加标签