Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 绑定到引用,而不是对象_C#_Winforms_Data Binding - Fatal编程技术网

C# 绑定到引用,而不是对象

C# 绑定到引用,而不是对象,c#,winforms,data-binding,C#,Winforms,Data Binding,假设您有一个对象,具有一个属性,您将控件绑定到该对象。像这样: MyClass MyObject = new MyClass(); MyObject.MyProperty = "Hello StackOverflow!"; MyTextBox.DataBindings.Add("Text", MyObject, nameOf(MyObject.MyProperty); 然后将MyObject更改为MyClass的新实例,如下所示: MyObject = new MyClass(); MyObj

假设您有一个对象,具有一个属性,您将控件绑定到该对象。像这样:

MyClass MyObject = new MyClass();
MyObject.MyProperty = "Hello StackOverflow!";
MyTextBox.DataBindings.Add("Text", MyObject, nameOf(MyObject.MyProperty);
然后将
MyObject
更改为
MyClass
的新实例,如下所示:

MyObject = new MyClass();
MyObject.MyProperty = "I've made a new instance of my class...";

然后
MyTextBox
仍将绑定到
MyClass
的实例,其中
MyProperty
设置为“Hello StackOverflow!”。是否要设置数据绑定,使其与类的新实例保持一致?我知道我可以简单地再次设置数据绑定,但有时这并不像本例中那样简单。

数据绑定支持源属性的属性路径。因此,只要将
MyObject
变量放入另一个可用于数据绑定的对象中,并将其作为属性公开,就可以指定属性名,该属性名引用保存该值的属性,然后是点,然后是实际需要的属性

例如,假设您有一个属性值为
MyClass
Model
类:

class Model : INotifyPropertyChanged
{
    private MyClass _myClass;
    public MyClass MyClass
    {
        get { return _myClass; }
        set { _UpdateField(ref _myClass, value); }
    }
}
(以上假设有一个助手方法
\u UpdateField()
,该方法根据需要处理更新字段和引发
PropertyChanged
事件。)

然后您可以这样定义绑定:

Model model = new Model(); // initialized somewhere you can access this reference later
model.MyClass.MyProperty = "Hello StackOverflow!";
MyTextBox.DataBindings.Add("Text", model,
    nameof(Model.MyClass) + "." +  nameof(MyClass.MyProperty);
然后,当您想要更新
MyClass
对象时,您可以更改
model.MyClass
属性值。绑定将相应地更新目标值


下面是一个完整的示例(除了*.Designer.cs文件…只需确保表单上有一个带有默认名称的
标签和
按钮,并订阅
按钮。单击下面代码中的处理程序的
事件):

公共部分类表单1:表单
{
专用只读C2[]\u rgc2=
{
新C2{Text=“First C2”},
新C2{Text=“Second C2”},
};
私有只读C1_C1=新C1();
私有布尔开关=假;
公共表格1()
{
初始化组件();
label1.DataBindings.Add(“Text”、c1,nameof(c1.C2)+“+nameof(C2.Text));
_UpdateC2();
}
私有void_UpdateC2()
{
_c1.C2=_rgc2[_toggle?1:0];
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
_切换=!\u切换;
_UpdateC2();
}
}
C1类:NotifyPropertyChangedBase
{
私人指挥与控制;
公共指挥与控制
{
获取{return}
集合{u UpdateField(ref{u c2,value);}
}
}
C2类:NotifyPropertyChangedBase
{
私有字符串_文本;
公共字符串文本
{
获取{return\u text;}
设置{u UpdateField(ref{u text,value);}
}
}
类NotifyPropertyChangedBase:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的void\u UpdateField(参考T字段,T新值,
Action onChangedCallback=null,
[CallerMemberName]字符串propertyName=null)
{
if(EqualityComparer.Default.Equals(字段,newValue))
{
返回;
}
T oldValue=字段;
字段=新值;
onChangedCallback?.Invoke(oldValue);
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}

否。您绑定的是对象而不是变量名。是的,绑定到viewmodel的属性。将viewmodel作为绑定的源,并为其提供属性的路径。确保viewmodel正确推进InotifyProperty更改。
public partial class Form1 : Form
{
    private readonly C2[] _rgc2 =
    {
        new C2 { Text = "First C2" },
        new C2 { Text = "Second C2" },
    };

    private readonly C1 _c1 = new C1();

    private bool _toggle = false;

    public Form1()
    {
        InitializeComponent();
        label1.DataBindings.Add("Text", _c1, nameof(C1.C2) + "." + nameof(C2.Text));
        _UpdateC2();
    }

    private void _UpdateC2()
    {
        _c1.C2 = _rgc2[_toggle ? 1 : 0];
    }

    private void button1_Click(object sender, EventArgs e)
    {
        _toggle = !_toggle;
        _UpdateC2();
    }
}

class C1 : NotifyPropertyChangedBase
{
    private C2 _c2;

    public C2 C2
    {
        get { return _c2; }
        set { _UpdateField(ref _c2, value); }
    }
}

class C2 : NotifyPropertyChangedBase
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set { _UpdateField(ref _text, value); }
    }
}

class NotifyPropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void _UpdateField<T>(ref T field, T newValue,
        Action<T> onChangedCallback = null,
        [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, newValue))
        {
            return;
        }

        T oldValue = field;

        field = newValue;
        onChangedCallback?.Invoke(oldValue);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}