当对象为 null 时,绑定控件不会更新其值

Bound control doesn't update its value when object is null

我对映射到自定义 class 的文本框的数据绑定属性有疑问,在大多数情况下它可以正常工作;当我更新绑定对象中的值时,更改会出现在文本框文本 属性 中,如果我将对象 属性 设置为空,则它会被正确格式化为“-No Data-”,但是当我将 object 设置为 null 时,文本框中的文本值保持不变。

我有 2 个 classes

Class1
Class2

Class1 通过以下方式实现 INotifyPropertyChanged:

public class Class1: INotifyPropertyChanged
{
   private string _serial;

   public event PropertyChangedEventHandler PropertyChanged;
   protected void OnPropertyChanged(string propertyName = null)
   {
       if (PropertyChanged != null)
       {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
       }
   }

   [DisplayName("Serial Number")]
   public string SerialNumber
   {
     get { return _serial; }
     set
     {
       _serial = value;
       OnPropertyChanged("SerialNumber");
     }
   }
 }

Class2 继承自 Class1:

public class Class2: Class1
{
  //My props & methods, etc.
}

在我的表单中,我按以下方式绑定文本框文本 属性:

Class2 myobject = new Class2();

myobject.SerialNumber = "1234";

//I only need the textbox to display, not update the datasource
//so i use DataSourceUpdateMode.Never
mytextbox.DataBindings.Add("Text", myobject, "SerialNumber",true,DataSourceUpdateMode.Never,"-No Data-");

稍后如果我在对象中进行以下分配,就会发生这种情况:

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject.SerialNumber = "456"; //mytextbox Text changes to "456"

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject.SerialNumber = null;  //mytextbox Text changes to "-No Data-"

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject = null;               //mytextbox Text remains "123" <-this is the problem

文本框文本是否应该更改为“-无数据-”,因为整个对象都是空的?

我是否缺少正确显示所需数据的内容?

"myobject = null"行并没有销毁对象,对象仍然存在。你只是没有参考它。您应该清除文本框的数据绑定。

在正常情况下,您应该有一些带有 "myobject" 属性 的 ViewModel class(实现 INotifyPropertyChanged),这个 ViewModel class 应该绑定到查看,并且 "myobject" 属性 应该绑定到文本框。清除 "myobject" 属性 后,UI 中的值就会消失。

当您设置 myobject = null 时,您的应用将尝试获取 null 的序列号 属性。如果无法获得 属性,它如何比较并判断不同?我想如果你从不让你的对象为空的话它会起作用。

而不是

myobject = null; 

这样做

myobject = new Class2();

将 myobject 设置为 null 只会删除该变量名对该对象的引用。实际实例化的对象仍然绑定在 DataBindings 中,因此为了更改该对象的值,您需要通过 textbox.DataBindings["SerialNumber"].

从那里访问它

当然,如果您将SerialNumber 设置为null,那就另当别论了。然后它可能会为您显示“-No Data-”作为 null 的默认值。

如果您希望删除对该对象的绑定,则需要对 DataBindings 集合调用 Remove 方法,例如

private void RemoveSerialNumberBinding()
{
   Binding serialNumberBinding = textBox1.DataBindings["SerialNumber"];
   textBox1.DataBindings.Remove(serialNumberBinding);
}

https://msdn.microsoft.com/en-us/library/system.windows.forms.controlbindingscollection.remove%28v=vs.110%29.aspx

myobject 作为数据源传递给 DataBindings.Add 意味着对象不会改变,只会改变属性。

如果您确实需要稍后绑定不同的对象或将其设置为 null,而不是编写特殊函数来执行此操作,您需要使用允许更改 "current" 的中间数据源目的。最简单的方法是在 BindingSourceBindingList<T> 中使用单个项目列表。

这里有一个 BindingSource 的例子:

表单成员:

BindingSource dataSource = new BindingSource { DataSource = typeof(Class2) };
Class2 selectedObject;
Class2 SelectedObject
{
    get { return selectedObject; }
    set
    {
        selectedObject = value;
        dataSource.Clear();
        dataSource.Add(value);
    }
}

绑定(在constructor/load事件中初始化一次):

mytextbox.DataBindings.Add("Text", dataSource, "SerialNumber", true, DataSourceUpdateMode.Never, "-No Data-");
// similar for other controls

数据操作:

SelectedObject = new Class2 { SerialNumber = "1234" }; //mytextbox Text is "1234"
SelectedObject.SerialNumber = "123"; //mytextbox Text is "123"
SelectedObject.SerialNumber = "456"; //mytextbox Text is "456"
SelectedObject.SerialNumber = null;  //mytextbox Text is "-No Data-"
SelectdObject.SerialNumber = "123";  //mytextbox Text is "123"
SelectedObject = null;               //mytextbox Text is "-No Data-"
SelectedObject = new Class2 { SerialNumber = "2345" }; //mytextbox Text is "2345"