WPF新手之将如何将一个成员变量或自定义类绑定到控件

 我来答
百度网友2a24b9d7ab9
推荐于2016-06-04 · 超过69用户采纳过TA的回答
知道答主
回答量:120
采纳率:0%
帮助的人:128万
展开全部
①绑定到某个控件的依赖属性DependencyProperty ②绑定到定义了INotifyPropertyChanged的类(ObservableCollection就是实现了该接口) 先看DependencyProperty。可以把任何一个CLR对象绑定为DependencyProperty。在VS2010下输入propdp,按Tab,会生成一个模板public int MyProperty { get { return (int)GetValue(MyPropertyProperty); } set { SetValue(MyPropertyProperty, value); } } // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new UIPropertyMetadata(0));MyProperty就是你要绑定的成员,修改它之后按Tab,后面的自动都会改变,如:public string Test { get { return (string)GetValue(TestProperty); } set { SetValue(TestProperty, value); } } // Using a DependencyProperty as the backing store for Test. This enables animation, styling, binding, etc... public static readonly DependencyProperty TestProperty = DependencyProperty.Register("Test", typeof(string), typeof(ownerclass), new UIPropertyMetadata(0));这里的ownerclass是拥有此成员的类名(如:class ownerclass {//...})。最后一个参数VS自动生成的有问题,因为它放入了一个参数0。实际上应该是UIPropertyMetadata(Object, PropertyChangedCallback, CoerceValueCallback, Boolean),用于设置UI中的数据更改后回调的函数。一般删除之或者用默认构造函数就行。如果需要它,一个简单的定义如下: public static readonly DependencyProperty IsNetworkChangedProperty = DependencyProperty.Register("IsNetworkChanged", typeof(bool), typeof(MainWindow), new UIPropertyMetadata(false, new PropertyChangedCallback(MainWindow.OnIsNetworkChanged))); private static void OnIsNetworkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //MessageBox.Show(d.GetType().ToString()); }注意这里是静态函数,由DependencyObject d来得到具体的通知对象。 然后在控件中进行绑定,如<TextBlock Text="{Binding ElementName=MainWin, Path=Test}"/>,对Test变量的使用一如普通变量。 注意:①使用DependencyProperty比INotifyPropertyChanged的方法性能要高。因为它用Hash实现,不需要反射,而且是WPF系统中相当底层的一个基类 ②DependencyObjects are not marked as serializable ③The DependencyObject class overrides and seals the Equals() and GetHashCode() methods ④A DependencyObject has thread affinity –it can only be accessed on the thread on which it was created。(这一点很重要,特别是当程序中用到注册事件时,因为这些往往要开新线程。比如我的这个软件中,将bool型IsNetworkAvailabe用DependencyProperty绑定到控件,然后注册事件NetworkAvailabilityChanged,在NetworkAvailabilityChangedEventHandler中更新IsNetworkAvailabe值,这样就会抛出异常)在需要多线程 中操作的绑定变量,则需要用INotifyPropertyChanged再看如何用INotifyPropertyChanged:这里要将待绑定的变量包装在一个类中: class MyTest : INotifyPropertyChanged { private string test; public string Test { get { return this.test; } set { if (this.test != value) { this.test = value; this.NotifyPropertyChanged("Test"); } } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } 其中test就是我们要绑定的变量。(绑定一个变量写这么多一堆,有点不值,我另开一篇,做一个snippet模板,用来快速生成)。 绑定时不知为何上面的绑定方法不灵了,于是换成代码绑定吧: MyTest Test; public MainWindow() { InitializeComponent(); this.Test = new MyTest(); Test.test = "thy"; TestBox.DataContext = this.Test; } 最终,在我的应用场景中,这两者都没能有用,我注册了事件NetworkAvailabilityChanged,在其中去修改一个绑定到ListBox的ObservableCollection,让其实现UI自动更新。但是总是会引起异常,我想可能是跨线程的原因吧。于是我试着用DependencyProperty绑定一个变量,在NetworkAvailabilityChanged事件中修改,还是不行,INotifyPropertyChanged也一样,BackgroundWorker也不行。最终没辙,在MainWindow中开了一个DispatcherTimer来轮询一个普通的bool变量: private DispatcherTimer _timer = new DispatcherTimer(DispatcherPriority.ContextIdle); _timer.Interval = TimeSpan.FromMilliseconds(100); _timer.Tick += new EventHandler(_timer_Tick); _timer.Start(); 虽说比较丑,但没法子啊,没这么多精力再去整了,先让它工作起来吧。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式