WPF List数据与UI更新 同步研究

    WPF中UI的界面元素去绑定一个List对象数据列表,当源数据列表变更,UI元素如何获取变更通知呢?本文就这一系列问题展开阐述。

 

    第一个问题:线程问题

    我们知道不管WINFORM程序还是WPF程序,其UI有主线程控制,当我们开另外的线程去操作UI会抛出异常(由于其他线程拥有此对象无法访问)。

    解决办法,通过Dispatcher属性的Invoke方法更新UI:   

    

 
  
1 new Thread(() => {
2 this .Dispatcher.Invoke( new Action(() => {
3 // your Method
4   }));
5 }).Start();

    WPF的Window没有Invoke方法,我们需通过Dispatcher属性调用Invoke方法。

 

    使用DispatcherTimer类做定时器时更新UI的解决办法:

 

1  private   delegate   void  UpdateTimer(); 
2  private   void  UpdateTimerCallback() 
3 
4  // DO 
5 
6  void  timer_Elapsed( object  sender, System.Timers.ElapsedEventArgs e) 
7  {
8  Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,  new  UpdateTimer(UpdateTimerCallback)); 
9  }

 

    

 

    OK,通过以上方法你会发现UI是可以更新了,但是我绑定了一个LIST在一个UI元素上,LIST在不断变更UI上并没有变更啊,这会是什么问题呢?

    

    第二个问题 数据更新

    我们可以通过多种形式将数据对象绑定给WPF中的元素,这里不做展开介绍,我们取WPF数据绑定中比较常用的DataContext共享源用做举例阐述

    

 
  
1 < Stackpanel DataContext = " {Binding views} " >
2 < ListBox x:Name = " Listdata " ItemsSource = " {Binding} " Style = " {x:Null} " >
3 < ListBox.ItemTemplate >
4 ......

    数据源更新了UI并没有改变,这是因为DataContext做的是一次性绑定,数据不会变更;

    WPF的数据基本绑定概念

    

    一次性绑定的写法:

    1.属性="{Binding 数据源的属性}";

    2.在代码层制定空间的.DataContext属性为某数据源即可,数据源应该是一个对象;

    数据流概念:

    

    要让UI变更必须使用单向绑定,查阅相关资料下面是单向绑定的阐述:

    单向绑定的用意在于访问的时候如果数据变更了,那么界面也随之变更;

    单向绑定三步曲:

    1.数据源实现INotifyPropertyChanged接口;

    2.同时指定数据源的绑定模式,例:Mode=OneWay or Mode=TwoWay...

    3.="{Binding 数据源的属性,Mode=OneWay}"

    

 
  
1 public class View : INotifyPropertyChanged {
2 public event PropertyChangedEventHandler PropertyChanged;
3 private string subject;
4 private string location;
5 private string name;
6 private string start;
7 private string end;
8 private string date;
9
10 public string Subject {
11 get { return subject; }
12 set {
13 if (value == subject) return ;
14 subject = value;
15 this .FirePropertyChanged( " Subject " );
16 }
17 }
18
19 public string Location {
20 get { return location; }
21 set {
22 if (value == location) return ;
23 location = value;
24 this .FirePropertyChanged( " Location " );
25 }
26 }
27
28 public string Name {
29 get { return name; }
30 set {
31 if (value == name) return ;
32 name = value;
33 this .FirePropertyChanged( " Name " );
34 }
35 }
36
37 public string Start {
38 get { return start; }
39 set {
40 if (value == start) return ;
41 start = value;
42 this .FirePropertyChanged( " Start " );
43 }
44 }
45
46 public string End {
47 get { return end; }
48 set {
49 if (value == end) return ;
50 end = value;
51 this .FirePropertyChanged( " End " );
52 }
53 }
54
55 public string Date {
56 get { return date; }
57 set {
58 if (value == date) return ;
59 date = value;
60 this .FirePropertyChanged( " Date " );
61 }
62 }
63
64 private void FirePropertyChanged( string propertyName) {
65 if ( this .PropertyChanged != null ) {
66 this .PropertyChanged( this , new PropertyChangedEventArgs(propertyName));
67 }
68 }

     

    通过以上步骤你会发现一行数据中的个各列数据可以更新变更了,但是如果往LIST中增加行数据UI还是不会显示;

 

    第三个问题 数据同步

    先来看下WPF的数据触发概念:

    

    再次搜索解决办法,原来WPF在.NET 4中提供了ObservableCollection类来处理数据更新的问题,这样就不用自己写代码来实现同步了,ObservableCollection类可以可靠的绑定控件与其数据源保持一致;新建类来实现ObservableCollection<T>:

    

 
  
1 public class ViewList : ObservableCollection < View > {
2
3 }

 

 

    如果想深入了解 ObervableCollection 类可参考MSDN相关章节;

 

    通过上述步骤的操作就很容易的完成了UI与LIST数据源的同步更新。

 

    

    转载时,请注明本文来源:www.cnblogs.com/tmywu

   

    作者: 淘米部落

 

转载于:https://www.cnblogs.com/tmywu/archive/2010/08/05/1793257.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值