绑定UserControl不更新数据源

时间:2012-01-11 21:10:42

标签: c# winforms data-binding

我有一个UserControl,上面有一个Textbox,Button和一个Tooltip控件。它确实实现了 INotifyPropertyChanged 我试图覆盖 Text 属性并添加我自己的属性,但是在所有情况下控件都从绑定数据源中读取,但从不更新数据资源。更改文本时会引发我的事件。一些代码如下。所有其他标准控件都运行正常。当用户输入或更改值时,我需要什么才能让控件更新数据源?

public partial class UrlControl : UserControl, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [Bindable(true)]
    [Browsable(true)]
    public string Url
    {
        get
        {
            return url.Text;
        }
        set
        {
            if (value != url.Text)
            {
                url.Text = value;
                OnPropertyChanged("Url");
            }
        }
    }
    protected virtual void OnPropertyChanged(string propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

这是表单设计者的绑定代码。

this.urlControl1.DataBindings.Add(new System.Windows.Forms.Binding("Url", this.customerBindingSource, "First", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

}

2 个答案:

答案 0 :(得分:4)

INotifyPropertyChanged用于数据源。它允许您的数据源通知绑定控件和其他侦听器的属性更改。但是,控件本身使用不同的机制。这有点奇怪:您使用命名约定<PropertyName>Changed在控件上创建事件。当属性值更改时,您将引发关联事件。

示例:

public string Url
{
    get { return url.Text; }
    set 
    { 
        if (value != url.Text) 
        { 
            url.Text = value; 
            OnUrlChanged(); // raise event
        }
    }
}

public event EventHandler UrlChanged;

private void OnUrlChanged()
{
    // raise the UrlChanged event
    if (UrlChanged != null)
        UrlChanged(this, new EventArgs());
}

这就是你需要做的一切。数据绑定精灵将在创建绑定时看到该事件并将其连接起来。

以下是MSDN上的主题:How to: Apply the PropertyNameChanged Pattern

答案 1 :(得分:1)

这对于从数据源读取值非常有用。

但是,在将值写入数据源时,您似乎直接从Url文本框存储并获取url值。但是,在UI中更改文本框的文本时,您不会提出属性更改通知。要解决此问题,请在文本框中添加TextChanged事件处理程序,可以简单地调用:

void url_TextChanged(object sender, EventArgs e)
{
    OnPropertyChanged("Url");
    OnUrlChanged(); // See additional note below
}

作为一方,虽然实现INotifyPropertyChanged 应该工作......但是当涉及到Windows窗体绑定时,您还可以创建一个事件,其属性名称后缀为“已更改”,并且绑定应该注意:

public event EventHandler UrlChanged;

protected virtual void OnUrlChanged()
{
    var handler = UrlChanged;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}

[Bindable(true)]
[Browsable(true)]
public string Url
{
    get
    {
        return url.Text;
    }
    set
    {
        if (value != url.Text)
        {
            url.Text = value;
            OnPropertyChanged("Url");
            OnUrlChanged();
        }
    }
}