我真的爱上了整个.Net数据绑定方案......但显然还有一些问题。假设我的类有一个名为Susan
的double类型的成员变量。那么似乎没有立即将Susan
绑定到文本框SusanText
的方法,因为绑定看起来像这样
SusanText.DataBindings.Add("Text",datasource,"Property")
并且Susan
不是属性。所以我可以让Susan
成为一个公共财产,但那有点臭...如果我想隐藏Susan
怎么办? (我想我可以使Susan
成为某个内部类的私有实例的公共属性......但这需要很多工作才能实现一点点。)但是,我遇到了更大的问题,所以对于争论的缘故让我们继续这样做:
private double Susan_;
public double Susan{ get; set;}
...
SusanText.DataBindings.Add("Text",this,"Susan")
然后一切似乎都按预期工作。如果我改变SusanText
,Susan
会相应改变。但是,当我直接改变Susan
时,问题就出现了。我希望SusanText
能够自动更新。所以我怀疑我需要使Susan
成为实现某种IBindable接口的double的子类,这样如果Susan
被数据绑定到SusanText
,则会注册相应的事件并Susan
如果她被修改,将通知其他人。
让Susan
做我想让她做的最简单的方法是什么?
谢谢!
答案 0 :(得分:3)
DataBinding期望它所绑定的类引发INotifyPropertyChanged
以指示某个值已被更改并需要重新读取;不幸的是,实现这一点仍然需要一些手动编码(或类似PostSharp到IL编织必要的代码)。
因此,为了支持数据绑定,您不能使用自动实现的属性,也不能直接绑定到字段 - 也不会让您有机会提出必要的事件(绑定将起作用,但值不会更新)什么时候改变了。)
DataBinding的另一个缺点是它不考虑线程。如果后台线程修改了数据绑定值,那么数据绑定将尝试进行跨线程调用以更新UI - 这很糟糕。我发现最好的解决方法是让可绑定类包含其UI Synchronization Context
的实例,这样可以确保在UI线程上调用UI的更新。
using System.ComponentModel;
namespace MyWebGrocer.Uma.UI
{
public class BoundClass : INotifyPropertyChanged
{
private string _Name;
private int _Age;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
OnPropertyChanged("Name");
}
}
public int Age
{
get
{
return _Age;
}
set
{
_Age = value;
OnPropertyChanged("Age");
}
}
protected void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
我知道这一切听起来令人沮丧 - 数据绑定的这些缺点是通过艰难的方式学到的。然而,在它们表现为更大的问题之前,最好早点意识到并补偿这些问题。
答案 1 :(得分:0)
很难在不知道代码如何组合的情况下告诉您最简单的方法。如果你在代码中设置绑定,看起来你仍然在努力工作。
这是最简单的方法:
namespace MyProject
{
public sealed class ViewModel : DependencyObject //handles all databinding voodoo
{
public string Susan
{
get { return (string)GetValue(SusanProperty); }
set { SetValue(SusanProperty, value); }
}
public static readonly DependencyProperty
SusanProperty = DependencyProperty.Register
("Susan", typeof(string),
typeof(ViewModel));
}
}
并在xaml中:
<Window.DataContext>
<ViewModel xmlns="clr-namespace:MyProject" />
</Window.DataContext>
<Grid>
<TextBox Text="{Binding Susan}" />
</Grid>