阅读this后,我非常确定如何将类的属性绑定到UserControl中的TextBox。我仍然对通过字符串访问属性感到非常不舒服。与该财产的类型甚至存在的任何联系(双方)都将丢失 我对这种态度的主要问题是:
是否有其他方法可以创建一个UserControl来表示一个连接到该类实例并与之保持同步的类? (除了用事件手动完成)
答案 0 :(得分:0)
(除了用事件手动完成)
必须澄清的是,单向和双向数据绑定确实取决于事件。请阅读How to: Implement Property Change Notification
也就是说,您可以在不对代码中的属性名称进行硬编码的情况下进行数据绑定。
一种方法是通过自定义属性。您可以在数据模型中装饰您希望用户控件绑定到的某些属性。这样,当您在用户控件中设置DataSource
时,通过反射,您可以在DataSource
对象中搜索自定义Attribute
装饰属性并绑定到它们:
public class MyDataModelObject
{
public int NotBindableProperty { get; }
[MyBindableAttribute]
public string BindableStringProperty
{
get {...}
set {...}
}
}
答案 1 :(得分:0)
没有理由你被迫使用字符串,这只是基本的NotifyPropertyChanged
事件机制。例如,Prism Framework提供了一个简单的包装器,它采用了Linq`表达式>作为参数并使用反射来获取属性名称(请注意;我在一个实例中看到这会导致在短时间内多次更新的属性上使用时出现性能问题。)
您可以轻松自己编写这样的包装器,而无需像这样使用整个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 ) );
}
}
现在您可以通过传递属性来使用它:
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 );
}
}
}
}
现在,如果您重构属性Foo
,您也不必担心更新字符串。但这并不能解决另一方面的问题。 DependencyProperty会,但你在内部有字符串问题,IMP更可取,因为它只是一个地方(在类中)的重复,而不是外部的 n 重复数。它并不完美,但它有所帮助。
答案 2 :(得分:0)
您还可以查看此项目notifypropertyweaver,它可以帮助您避免魔术字符串,并提供更酷的东西。