zoukankan      html  css  js  c++  java
  • wpf中数据绑定和INotifyPeropertyChanged的理解

    原创:转载请注明出处。

    先说数据绑定:

    XAML代码:

    <Window x:Class="数据绑定和INotifyPropertyChanged.Window1" Loaded="Window_Loaded"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="数据绑定和INotifyPropertyChanged" Height="300" Width="300">
        <Grid>
            <Label Height="28" Margin="15,35,0,0" Name="lbAge" VerticalAlignment="Top" HorizontalAlignment="Left" Width="42">年龄:</Label>
            <Label Height="28" HorizontalAlignment="Left" Margin="15,83,0,0" Name="lbName" VerticalAlignment="Top" Width="42">姓名:</Label>
            <TextBox Height="23" Margin="79,37,79,0" Name="TxtAge" VerticalAlignment="Top" Text="{Binding Name}"/>
            <TextBox Height="23" Margin="79,83,79,0" Name="TxtName" VerticalAlignment="Top" Text="{Binding Age}"/>
        </Grid>
    </Window>

    C#代码:

    步骤如下:

    先定义一个类

     1 public class Person:INotifyPropertyChanged
     2     {
     3         private string _name;
     4 
     5         public string Name
     6         {
     7             get { return _name; }
     8             set { _name = value; }
     9         }
    10 
    11         private int _age;
    12 
    13         public int Age
    14         {
    15             get { return _age; }
    16             set { _age = value; }
    17         }
    18     }

    然后在后台写代码:

     1 private Person p1;
     2 
     3         public Person P1
     4         {
     5             get { return p1; }
     6             set { p1 = value; }
     7         }
     8         public Window1()
     9         {
    10             InitializeComponent();
    11         }
    12 
    13         private void Window_Loaded(object sender, RoutedEventArgs e)
    14         {
    15             p1 = new Person();
    16             p1.Name = "aaa";
    17             p1.Age = 15;
    18 
    19             TxtAge.DataContext = p1;
    20             TxtName.DataContext = p1;
    21         }
    

    注意:

    这里牵扯到一个很重要的东西,“数据上下文”,即DataContext,必须把界面控件的DataContext和类的实例绑定起来,这样界面才会显示类中属性的值。
    要想控件获得类中的属性值并显示,控件必须绑定类中的属性。

    接下来说一下INotifyPropertyChanged,这个是MVVM的基础,也是数据双向绑定很重要很关键的部分。通过他,类的属性值改变才会改变UI界面显示的值。(有一个很重要的知识点:事件,这个不懂得赶紧去学下再来接着往下看)。

    上代码,这个代码是数据绑定部分代码的基础上进一步完善。

    XMAL代码:

     1 <Window x:Class="数据绑定和INotifyPropertyChanged.Window1" Loaded="Window_Loaded"
     2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4     Title="数据绑定和INotifyPropertyChanged" Height="300" Width="300">
     5     <Grid>
     6         <Label Height="28" Margin="15,35,0,0" Name="lbAge" VerticalAlignment="Top" HorizontalAlignment="Left" Width="42">年龄:</Label>
     7         <Label Height="28" HorizontalAlignment="Left" Margin="15,83,0,0" Name="lbName" VerticalAlignment="Top" Width="42">姓名:</Label>
     8         <TextBox Height="23" Margin="79,37,79,0" Name="TxtAge" VerticalAlignment="Top" Text="{Binding Name}"/>
     9         <TextBox Height="23" Margin="79,83,79,0" Name="TxtName" VerticalAlignment="Top" Text="{Binding Age}"/>
    10         <Button Height="23" HorizontalAlignment="Left" Margin="30,0,0,80" Name="BtnAgePP" VerticalAlignment="Bottom" Width="75" Click="BtnAgePP_Click">Age++</Button>
    11         <Button Height="23" Margin="132,0,71,80" Name="BtnDisplayAge" VerticalAlignment="Bottom" Click="BtnDisplayAge_Click">显示年龄</Button>
    12     </Grid>
    13 </Window>

    C#代码:

     1 private Person p1;
     2 
     3         public Person P1
     4         {
     5             get { return p1; }
     6             set { p1 = value; }
     7         }
     8         public Window1()
     9         {
    10             InitializeComponent();
    11         }
    12 
    13         private void Window_Loaded(object sender, RoutedEventArgs e)
    14         {
    15             p1 = new Person();
    16             p1.Name = "aaa";
    17             p1.Age = 15;
    18 
    19             TxtAge.DataContext = p1;
    20             TxtName.DataContext = p1;
    21         }
    22 
    23         private void BtnDisplayAge_Click(object sender, RoutedEventArgs e)
    24         {
    25             MessageBox.Show(p1.Age.ToString());
    26             MessageBox.Show(p1.Name);
    27         }
    28 
    29         private void BtnAgePP_Click(object sender, RoutedEventArgs e)
    30         {
    31             p1.Age++;
    32             p1.Name = "ccc";
    33         }

    类:person也要改,

     1 public class Person:INotifyPropertyChanged
     2     {
     3         private string _name;
     4 
     5         public string Name
     6         {
     7             get { return _name; }
     8             set { _name = value; if (PropertyChanged != null) { PropertyChanged(this,new PropertyChangedEventArgs("Name")); } }
     9         }
    10 
    11         private int _age;
    12 
    13         public int Age
    14         {
    15             get { return _age; }
    16             set { _age = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Age")); } }
    17         }
    18 
    19         #region INotifyPropertyChanged 成员
    20 
    21         public event PropertyChangedEventHandler PropertyChanged;//数据绑定会监听这个PropertyChanged事件
    22 
    23         #endregion
    24     }

    有没有注意到类Person有什么变化,对,Person类实现了INotifyPropertyChanged接口。
    解释一下:

    1、Person类实现INotifyPropertyChanged接口,这个接口只有一个PropertyChanged事件成员。

    看源码:

    1     // 摘要:
    2     //     向客户端发出某一属性值已更改的通知。
    3     public interface INotifyPropertyChanged
    4     {
    5         // 摘要:
    6         //     在更改属性值时发生。
    7         event PropertyChangedEventHandler PropertyChanged;
    8     }

    2、数据绑定会检测Person类是否实现了INotifyPropertyChanged接口,
    3、如果Person类实现了INotifyPropertyChanged接口,那就监听PropertyChanged事件。

    4、如果Property改变了,那么就产生PropertyChanged事件,即PropertyChanged!=null。

    5、向前端UI发送属性值改变的额通知,控件绑定了属性,控件收到属性改变的通知,就把自身的值也改变 。

    补充:在数据绑定的时候,是一个一个控件绑定的,当控件少的时候这没问题,但是控件多的话,就要重复写很多次的datacontext了。这时候,可以用this.DataContext来统一指定当前窗口的所有控件的数据上下文。

    譬如,本文中的例子可以变成this.DataContext = p1。这样的话,DataContext就可以作用到全部的控件,而不需要一个一个去指定了。

    当然,也可以在this的DataContext指定后,给某个控件指定DataContext,这样子特定的控件就有它自己的DataContext了。

  • 相关阅读:
    Activiti系列——如何在eclipse中安装 Activiti Designer插件
    C语言 二维数组与指针笔记
    Ubuntu linux设置从当前目录下加载动态库so文件
    Ubuntu14.04安装nfs服务器
    Ubuntu14.04 搭建FTP服务器
    Linux备忘命令
    Java实现对xml文件的增删改查
    Java利用jacob实现打印Excel文件
    git操作列表
    swiper 窗口宽度变化,页面宽度高度变化 导致自动滑动 解决方案
  • 原文地址:https://www.cnblogs.com/dotnetHui/p/8403519.html
Copyright © 2011-2022 走看看