c#数据绑定不更新控件

本文关键字:控件 更新 数据绑定 | 更新日期: 2023-09-27 18:14:11

我正在c#紧凑框架上玩数据绑定。我开发了一个简单的表单,有一个文本框和一个标签。我想更改绑定到Textbox (bindModelTextBox)的数据,并通过绑定到相同数据的标签(bindmodelellabel)显示这些更改。下面是代码:

public partial class CreateShipment : Form {
    //simple bean. Just one property: id, a string
    private BasicShipmentBean toBindBasicShipment = null;
    public CreateShipment() {
        InitializeComponent();
        BindingSource bsProva = new BindingSource();
        toBindBasicShipment = new BasicShipmentBean();
        toBindBasicShipment.id = "boo";
        bsProva.Add(toBindBasicShipment);
        bindModelLabel.DataBindings.Add("Text", bsProva, "id", true, DataSourceUpdateMode.OnPropertyChanged);
        bindModelTextBox.DataBindings.Add("Text", bsProva, "id", true, DataSourceUpdateMode.OnPropertyChanged);
        bindModelTextBox.LostFocus += textLoseFocus;
    }
    ...
    private void textLoseFocus(object sender, System.EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("focus lost. "+toBindBasicShipment.id);
    }

当文本框失去焦点时,我可以看到bean中的数据被更新,但是,标签仍然显示bean的原始id值。我错过了什么?

c#数据绑定不更新控件

您需要在BasicShipmentBean类上实现INotifyPropertyChanged。我忘记了我最初在哪里找到这个,但这里是一个ObservableObject基类,实现了INotifyPropertyChanged,我使用我所有的数据源。

public abstract class ObservableObject : INotifyPropertyChanged
{
    #region Debugging Aides
    /// <summary>
    /// Warns the developer if this object does not have
    /// a public property with the specified name. This 
    /// method does not exist in a Release build.
    /// </summary>
    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public virtual void VerifyPropertyName(string propertyName)
    {
        // Verify that the property name matches a real,  
        // public, instance property on this object.
        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        {
            string msg = "Invalid property name: " + propertyName;
            if (this.ThrowOnInvalidPropertyName)
                throw new Exception(msg);
            else
                Debug.Fail(msg);
        }
    }
    /// <summary>
    /// Returns whether an exception is thrown, or if a Debug.Fail() is used
    /// when an invalid property name is passed to the VerifyPropertyName method.
    /// The default value is false, but subclasses used by unit tests might 
    /// override this property's getter to return true.
    /// </summary>
    protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
    #endregion // Debugging Aides
    #region INotifyPropertyChanged Members
    /// <summary>
    /// Raises the PropertyChange event for the property specified
    /// </summary>
    /// <param name="propertyName">Property name to update. Is case-sensitive.</param>
    public virtual void RaisePropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);
        OnPropertyChanged(propertyName);
    }
    /// <summary>
    /// Raised when a property on this object has a new value.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
    #endregion // INotifyPropertyChanged Members
}

然后,你需要为BasicShipmentBean中的id在setter中引发OnPropertyChanged事件,例如:

private string _id;
public string id
{
    get { return _id; }
    set
    {
        if (value != _id)
            {
                _id = value;
                OnPropertyChanged("id");
            }
    }
}

Compact Framework中的数据绑定比WPF中的数据绑定要繁琐一些,但是大部分实现都非常相似。