• 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

       

        作者: 淘米部落

  • 相关阅读:
    Static了解和复习继承。
    复习篇1.对象和封装
    第一章笔记
    A + B Problem II
    Number Sequence
    Fibonacci Again
    8615 快乐
    8635 气球
    大牛之路II
    8617 阶乘数字和
  • 原文地址:https://www.cnblogs.com/tmywu/p/1793257.html
Copyright © 2020-2023  润新知