Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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_User Controls - Fatal编程技术网

C#中的数据绑定-属性名称作为字符串

C#中的数据绑定-属性名称作为字符串,c#,winforms,data-binding,user-controls,C#,Winforms,Data Binding,User Controls,阅读之后,我非常确定如何将类的属性绑定到UserControl中的文本框。不过,我还是很不习惯通过字符串访问属性。与该类型的任何连接,甚至该属性的存在(在两侧)都将丢失。 我对这种态度的主要问题是: 智能感知停止工作->容易出错,不太方便 无论在那里写的是什么,都不会被检查,直到它被调用->错误可能会一直被忽略,直到最糟糕的时刻 是否有其他方法来创建表示一个类的UserControl,该类连接到该类的实例并与之保持同步?(除了通过事件手动执行之外) (除了通过事件手动执行之外) 必须澄清的是

阅读之后,我非常确定如何将类的属性绑定到UserControl中的文本框。不过,我还是很不习惯通过字符串访问属性。与该类型的任何连接,甚至该属性的存在(在两侧)都将丢失。
我对这种态度的主要问题是:

  • 智能感知停止工作->容易出错,不太方便
  • 无论在那里写的是什么,都不会被检查,直到它被调用->错误可能会一直被忽略,直到最糟糕的时刻
是否有其他方法来创建表示一个类的UserControl,该类连接到该类的实例并与之保持同步?(除了通过事件手动执行之外)

(除了通过事件手动执行之外)

必须澄清的是,单向和双向数据绑定确实取决于事件。请阅读

也就是说,您可以在代码中不使用表示属性名称的硬编码字符串进行数据绑定

一种方法是通过自定义属性。可以在数据模型中修饰某些属性,以便用户控件绑定到这些属性。这样,当在用户控件中设置了
数据源
时,通过反射,您可以在
数据源
对象中搜索自定义的
属性
装饰属性并绑定到它们:

public class MyDataModelObject
{
    public int NotBindableProperty { get; }

    [MyBindableAttribute]
    public string BindableStringProperty
    {
        get {...}
        set {...}
    }
}

没有理由强迫您使用字符串,这只是基本的
NotifyPropertyChanged
事件机制。例如,提供了一个简单的包装器,该包装器将Linq`Expression>作为参数,并使用反射来获取属性名称(但要小心;我在一个实例中看到,在短时间内多次更新的属性上使用该包装器会导致性能问题)

您可以自己轻松编写这样的包装器,而无需像这样使用整个Prism框架:

class NotificationObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    protected virtual void OnPropertyChanged( ProeprtyChangedEventArgs e )
    {
        PropertyChanged( this, e );
    }

    protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression )
    {
        // you'll want to add some error checking here
        var name = ((MemberExpression)propertyExpression).Member.Name;
        OnPropertyChanged( new PropertyChangedEventArgs( name ) );
    }
}
现在,如果你重构属性
Foo
,你就不必担心更新字符串了。但这并不能解决另一方面的问题。DependencyProperty可以,但您在内部有字符串问题,哪个IMP更可取,因为它只是一个位置(类中)的副本,而不是外部n个副本。这并不完美,但有帮助

class Whatever : NotificationObject
{
    private string _foo = String.Empty;
    public string Foo
    {
        get { return _foo ?? String.Empty; }
        set
        {
            if( !_foo.Equals( value ) )
            {
                _foo = value;
                RaisePropertyChanged( this.Foo );
            }
        }
    }
}