• 属性通知之INotifyPropertyChanged


    为什么后台绑定的值改变了前台不发生变化了?

    针对这个初学者很容易弄错的问题,这里介绍一下INotifyPropertyChanged的用法

    INotifyPropertyChanged:用于绑定属性更新

     1   /// <summary>
     2     /// 实体基类,实现了属性通知
     3     /// </summary>
     4     public class BaseEntity : INotifyPropertyChanged
     5     {
     6         public event PropertyChangedEventHandler PropertyChanged;
     7 
     8         /// <summary>
     9         /// 触发属性通知
    10         /// 这里用了一个特性的小技巧,就是CallMemberName
    11         /// 通过反射来获取调用者的名称,从而避免每一次调用方法都需要将属性名称传入方法
    12         /// </summary>
    13         /// <param name="propertyName"></param>
    14         [NotifyPropertyChangedInvocator]
    15         protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    16         {
    17             var handler = PropertyChanged;
    18             if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    19         }
    20     }

    学生类继承自实体基类,通过继承的OnPropertyChanged方法来通知属性已经发生改变

     1     /// <summary>
     2     /// 学生类
     3     /// </summary>
     4     public class Student : BaseEntity
     5     {
     6         private string _name;
     7 
     8         /// <summary>
     9         /// 名字
    10         /// </summary>
    11         public string Name
    12         {
    13             get { return _name; }
    14             set
    15             {
    16                 _name = value;
    17                 OnPropertyChanged();
    18             }
    19         }
    20 
    21         private int _age;
    22 
    23         /// <summary>
    24         /// 年龄
    25         /// </summary>
    26         public int Age
    27         {
    28             get { return _age; }
    29             set
    30             {
    31                 _age = value;
    32                 OnPropertyChanged();
    33             }
    34         }
    35 
    36         private double _score;
    37 
    38         /// <summary>
    39         /// 分数
    40         /// </summary>
    41         public double Score
    42         {
    43             get { return _score; }
    44             set
    45             {
    46                 _score = value;
    47                 OnPropertyChanged();
    48             }
    49         }
    50     }

    在ViewModel中声明一个Student,并且生成相应事件

      public class MainWindowViewModel
        {
            public Student LiLei { get; set; }
    
            public MainWindowViewModel()
            {
                InitStudentInfo();
                StartUpdateScore();
            }
    
            //初始化学生信息
            private void InitStudentInfo()
            {
                LiLei = new Student
                {
                    Name = "李雷",
                    Age = 14,
                    Score = 91.5
                };
            }
    
            //开始更新分数
            private void StartUpdateScore()
            {
                //定义一个定时器,改变分数值,若小于100分,那么增加,否则将到达一个特定分数
                var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
                timer.Tick += (sender, e) =>
                {
                    if (LiLei.Score < 99)
                    {
                        LiLei.Score++;
                    }
                    else
                    {
                        LiLei.Score = 89.5;
                    }
                };
                timer.Start();
            }
        }

    前台Xaml

     1  <Grid>
     2         <StackPanel>
     3             <TextBlock>
     4                 <Run Text="姓名:"/>
     5                 <Run Text="{Binding LiLei.Name}"/>
     6             </TextBlock>
     7             <TextBlock>
     8                 <Run Text="年龄:"/>
     9                 <Run Text="{Binding LiLei.Age}"/>
    10             </TextBlock>
    11             <TextBlock>
    12                 <Run Text="分数:"/>
    13                 <Run Text="{Binding LiLei.Score}"/>
    14             </TextBlock>
    15         </StackPanel>
    16     </Grid>

    后台绑定

    1     public MainWindow()
    2         {
    3             InitializeComponent();
    4             this.DataContext = new MainWindowViewModel();
    5         }

    效果图:

    一个简单是示意例子,其实在大部分的Mvvm框架中,都有一些类是实现了属性通知的,会有相应的方法可以调用,一般不用自己去实现INotifyPropertyChanged接口

  • 相关阅读:
    codevs 3049 舞蹈家怀特先生
    洛谷P2530 [SHOI2001]化工厂装箱员
    洛谷P2736 “破锣摇滚”乐队 Raucous Rockers
    Phalanx
    Treats for the Cows
    Very Simple Problem
    Alice and Bob
    FatMouse and Cheese
    Tickets
    Piggy-Bank
  • 原文地址:https://www.cnblogs.com/XzcBlog/p/4680126.html
Copyright © 2020-2023  润新知