走進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     }

雙向綁定效果,如下所示:

備注

以上就是數據綁定的簡單介紹,旨在拋磚引玉,共同學習,一起進步。

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

君問歸期未有期,巴山夜雨漲秋池。何當共剪西窗燭,卻話巴山夜雨時。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM