走进WPF之数据绑定

在软件三层架构中,数据需要在业务逻辑层,显示层,数据处理层来回传递,在WPF中,Binding是可以实现数据关联在一起的桥梁,所谓“一桥飞架南北,天堑变通途”。有了Binding,后台可以专心处理程序与算法,前台可以专注于UI设计。本文以一些简单的小例子,简述数据绑定的相关内容,仅供学习分享使用,如有不足之处,还请指正。

控件之间的绑定

通过绑定两个控件,可以实现数据的实时同步,且不需要写后台代码。本例Slider源控件,TextBox为目标控件,通过Text="{Binding ElementName=one, Path=Value,Mode=TwoWay,FallbackValue=0,UpdateSourceTrigger=PropertyChanged}" 实现数据的双向绑定。 如下所示:

 示例源码

控件之间数据绑定的固定格式为{Binding ElementName=源, Path=属性,Mode=方式,FallbackValue=默认值,UpdateSourceTrigger=触发方式}。其中有些可以省略,如下所示:

 1 <Window x:Class="WpfApp2.B1Window"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp2"
 7         mc:Ignorable="d"
 8         Title="数据绑定基础示例" Height="450" Width="600">
 9     <StackPanel>
10         <Slider x:Name="one" Orientation="Horizontal" Minimum="0" Maximum="100" Height="25" Margin="5" Value="10" Foreground="AliceBlue" Background="LightSalmon" IsSnapToTickEnabled="True" ></Slider>
11         <TextBox x:Name="two"  Text="{Binding ElementName=one, Path=Value,Mode=TwoWay,FallbackValue=0,UpdateSourceTrigger=PropertyChanged}" Padding="5" Margin="5" FontSize="20"></TextBox>
12     </StackPanel>
13 </Window>

控件与资源的绑定

控件绑定资源,即可达到资源的一次定义,多次复用。通过Text="{Binding Source={StaticResource zero}}"进行绑定资源,如下所示:

 

 示例源码

控件与资源之间,通过{Binding Source={StaticResource 资源名}}的方式进行绑定,如果资源还有其他属性,则需要指定Path对应的属性名,若纯文本内容,则不需要指定Path。如下所示:

 1 <Window x:Class="WpfApp2.B2Window"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp2"
 7         xmlns:sys="clr-namespace:System;assembly=mscorlib"
 8         mc:Ignorable="d"
 9         Title="资源绑定示例" Height="250" Width="400" Background="AliceBlue">
10     <Window.Resources>
11         <sys:String x:Key="zero">静夜思</sys:String>
12         <sys:String x:Key="one">床前明月光,疑似地上霜。</sys:String>
13         <sys:String x:Key="two">举头望明月,低头思故乡。</sys:String>
14     </Window.Resources>
15     <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" >
16         <TextBlock x:Name="title"  Text="{Binding Source={StaticResource zero}}" Margin="5" Padding="5" FontSize="20" TextAlignment="Center"></TextBlock>
17         <TextBlock x:Name="first"  Text="{Binding Source={StaticResource one}}" Margin="5" Padding="5" FontSize="20"></TextBlock>
18         <TextBlock x:Name="after" Text="{Binding Source={StaticResource two}}" Margin="5" Padding="5" FontSize="20"></TextBlock>
19     </StackPanel>
20 </Window>

DataContext

DataContext是指数据上下文,在WPF中,每一个控件都可以设置DataContext。通过上下文,可以自动匹配属性进行绑定。

XAML中设置DataContext

1. 设置资源x:Key="student",定义一个学生对象,如下所示:

 1     <Window.Resources>
 2         <Style TargetType="TextBlock">
 3             <Setter Property="HorizontalAlignment" Value="Center"></Setter>
 4             <Setter Property="VerticalAlignment" Value="Center"></Setter>
 5             <Setter Property="FontSize" Value="16"></Setter>
 6         </Style>
 7         <Style TargetType="TextBox">
 8             <Setter Property="VerticalAlignment" Value="Center"></Setter>
 9             <Setter Property="FontSize" Value="16"></Setter>
10         </Style>
11         <local:Student x:Key="student" Name="张三" Age="18" Sex="男" Classes="三班" >
12             
13         </local:Student>
14     </Window.Resources>

2. 将资源赋值给DataContext,并在控件上绑定属性,如下所示:

 1    <Grid DataContext="{StaticResource student}">
 2         <Grid.ColumnDefinitions>
 3             <ColumnDefinition Width="1*"></ColumnDefinition>
 4             <ColumnDefinition Width="3*"></ColumnDefinition>
 5         </Grid.ColumnDefinitions>
 6         <Grid.RowDefinitions>
 7             <RowDefinition></RowDefinition>
 8             <RowDefinition></RowDefinition>
 9             <RowDefinition></RowDefinition>
10             <RowDefinition></RowDefinition>
11         </Grid.RowDefinitions>
12         <TextBlock Margin="5" Padding="5">姓名:</TextBlock>
13         <TextBox Grid.Row="0" Grid.Column="1" x:Name="txtName" Margin="5" Padding="5" Text="{Binding Name}"></TextBox>
14 
15         <TextBlock Grid.Row="1" Grid.Column="0" Margin="5" Padding="5">年龄:</TextBlock>
16         <TextBox Grid.Row="1" Grid.Column="1" x:Name="txtAge" Margin="5" Padding="5" Text="{Binding Age}"></TextBox>
17 
18         <TextBlock Grid.Row="2" Grid.Column="0" Margin="5" Padding="5">性别:</TextBlock>
19         <TextBox Grid.Row="2" Grid.Column="1" x:Name="txtSex" Margin="5" Padding="5" Text="{Binding Sex}"></TextBox>
20         
21         <TextBlock Grid.Row="3" Grid.Column="0" Margin="5" Padding="5">班级:</TextBlock>
22         <TextBox Grid.Row="3" Grid.Column="1" x:Name="txtClassses" Margin="5" Padding="5" Text="{Binding Classes}"></TextBox>
23         
24     </Grid>

经过以上两步,就可以实现数据的绑定,示例效果如下:

 

 代码设置DataContext

DataContext不仅可以通过XAML进行赋值,也可以通过C#代码设定,如下所示:

1 Student s = new Student()
2 {
3      Name="李四",
4      Age=22,
5      Sex="",
6      Classes="4班"
7 };
8 //one是grid的Name
9 this.one.DataContext = s;

示例效果与XAML一致,如下所示:

 注意:要实现DataContext数据绑定,有以下两点要求:

  1. 数据源对象的属性不能是private修饰。
  2. 绑定的名称必须和属性名保持一致,如不一致,则绑定失效。

双向绑定

普通的对象只能实现一次的单向绑定,如果要实现双向绑定,需要实现通知接口【System.ComponentModel.INotifyPropertyChanged】并在属性变更时进行通知,如下所示:

 1     public class Person:INotifyPropertyChanged
 2     {
 3         private string name;
 4         public string Name
 5         {
 6             get
 7             {
 8                 return name;
 9             }
10             set
11             {
12                 name = value;
13                 OnPropertyChanged("Name");
14             }
15         }
16 
17         private int age;
18 
19         public int Age
20         {
21             get { return age; }
22             set
23             {
24                 age = value;
25                 OnPropertyChanged("Age");
26             }
27         }
28 
29         private string sex;
30 
31         public string Sex
32         {
33             get { return sex; }
34             set
35             {
36                 sex = value;
37                 OnPropertyChanged("Sex");
38             }
39         }
40 
41         private string classes;
42 
43         public string Classes
44         {
45             get { return classes; }
46             set
47             {
48                 classes = value;
49                 OnPropertyChanged("Classes");
50             }
51         }
52 
53         public event PropertyChangedEventHandler PropertyChanged;
54 
55         protected void OnPropertyChanged(string propertyName)
56         {
57             if (PropertyChanged != null) {
58                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
59             }
60         }
61     }

在初始化时对DataCotext进行赋值,然后在变更事件中,更改属性值,则页面绑定的值也会随着改变。如下所示:

 1     /// <summary>
 2     /// B4Window.xaml 的交互逻辑
 3     /// </summary>
 4     public partial class B4Window : Window
 5     {
 6         private Person person;
 7         public B4Window()
 8         {
 9             InitializeComponent();
10             person = new Person()
11             {
12                 Name = "李四",
13                 Age = 22,
14                 Sex = "",
15                 Classes = "4班"
16             };
17             //one是grid的Name
18             this.one.DataContext = person;
19         }
20 
21         private void btnUpdate_Click(object sender, RoutedEventArgs e)
22         {
23             this.person.Name = "王五";
24             this.person.Age = 18;
25             this.person.Sex = "";
26             this.person.Classes = "6班";
27 
28         }
29     }

双向绑定效果,如下所示:

备注

以上就是数据绑定的简单介绍,旨在抛砖引玉,共同学习,一起进步。

夜雨寄北【作者】李商隐 【朝代】唐

君问归期未有期,巴山夜雨涨秋池。何当共剪西窗烛,却话巴山夜雨时。

posted @ 2021-11-16 23:44  老码识途呀  阅读(1732)  评论(1编辑  收藏  举报