WPF數據綁定Binding(二)
1.UI控件直接的數據綁定
UI對象間的綁定,也是最基本的形式,通常是將源對象Source的某個屬性值綁定 (拷貝) 到目標對象Destination的某個屬性上。源屬性可以是任意類型,但目標屬性必須是依賴屬性(Dependency Property)。通常情況下我們對於UI對象間的綁定源屬性和目標屬性都是依賴屬性 (有些屬性不是) ,因為依賴屬性有垂直的內嵌變更通知機制,WPF可以保持目標屬性和源屬性的同步。
布局文件綁定源碼:
<StackPanel Orientation="Vertical"> <Slider Name="slider1" Margin="10 10 10 0" Minimum="9" Maximum="50" Value="12" TickFrequency="5"></Slider> <TextBlock Name="txtB_info" Text="上海世博會" Margin="10 10 10 0" FontSize="{Binding ElementName=slider1, Path=Value}"></TextBlock> <TextBox Name="txt_fontSize" Text="{Binding ElementName=slider1, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="10 10 10 0"></TextBox> <TextBox Margin="10 10 10 0"></TextBox> </StackPanel>
1.1 C#后台源碼進行數據綁定源碼:
1. 調用FrameworkElement 或FrameworkContentElement對象的SetBinding方法
2. 調用BindingOperations.SetBinding靜態方法
//綁定對象 Binding binding = new Binding(); //設置綁定數據源對象 binding.ElementName = "slider1"; //設置數據流的方向 binding.Mode = BindingMode.TwoWay; //設置源屬性 binding.Path = new PropertyPath("Value"); //進行數據綁定 txtB_info.SetBinding(TextBlock.FontSizeProperty, binding); //第二中綁定方式 BindingOperations.SetBinding(txt_fontSize, TextBox.TextProperty, binding);
1.2 C#后台清除綁定的數據
當你在應用程序中某個地方添加了綁定,而在某個時候又不想這個綁定在接下來繼續有效時,你可以有兩種方式來斷開這個綁定:
1. 用BindingOperations.ClearBinding靜態方法。
例如BindingOperations.ClearBinding(currentTextBlock, TextBlock.TextProperty); BindingOperations同時還提供了ClearAllBindings方法,只需要傳入要清除綁定的目標對象的名稱,它就會將所有這個對象的綁定移除。
2.簡單的將目標屬性設置為一個新的值。
這個簡單的方法同樣有效,可以斷開與前邊設置的binding的連接。簡單的設置為任何值即可:如:currentTextBlock.Text = “it’s a new value.”;
//清除txtB_info的數據綁定 綁定數據流向 如果為Mode=TwoWay 側不能清除綁定 //只要Mode的值不是TwoWay txtB_info.FontSize = 15; //最好使用下面的方式清除數據綁定 BindingOperations.ClearBinding(txt_fontSize, TextBox.TextProperty); //清除所有綁定 BindingOperations.ClearAllBindings(txt_fontSize);
效果圖:
1.3 Binding對象的屬性說明
序號 屬性名 描述
1 Converter 轉換器,將綁定的內容轉換成自己需要的內容。自定義轉換類 必須繼承於:IValueConverter接口
2 ElementName 綁定的源對象,本人理解 專程用於UI控件之間屬性的綁定
3 FallbackValue 綁定無法返回有效值時的默認顯示值
4 Mode 綁定方式,枚舉類型 Default OneWay TwoWay OneTime OneWayToSource
5 Path 屬性 路徑,用來指定要綁定數據源的路徑,其性質是一個屬性,該屬性該當是依靠屬性,
也即便能夠告終積極更新機制的【單個類實現INotifyPropertyChanged、集合要 實現INotifyCollectionChanged接口】
6 RelativeSource 常用於自身綁定或者數據模板中來指定綁定的源對象及控件模塊中的綁定。
7 Source 源對象,控件或自定義對象等。
8 StringFormat 格式化表達式
9 UpdateSourceTrigger 在雙向綁定時TwoWay 或 OneWayToSource 時。用來確定屬性更改的時機。
UpdateSourceTrigger枚舉類型:Default,PropertyChanged,LostFocus,Explicit。
10 ValidationRules 驗證規則.可以被設置為一個或多個派生自ValidationRule的對象,
每個規則都會檢查特定的條件並更具結果來標記數據的有效性
1.4 Mode 五種綁定方式 Default OneWay TwoWay OneTime OneWayToSource
1. Default 默認的,一般來說,對於用戶可以設置的(如TextBox.Text屬性)是雙向的,而其他則是單向的。
2. OneWay 單向綁定 當源屬性變化時更新目標屬性。
3. TwoWay 雙向綁定 數據源和目標都會隨之改變,但是更加消耗系統資源。
4. OneTime 只綁定一次,以后數據源的改變都不會改變目標屬性值。(如果用C#代碼后台調用:
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtB_info, TextBlock.FontSizeProperty);//方式二
//BindingExpression bindingExpression=txtB_info.GetBindingExpression(TextBlock.FontSizeProperty);//方式二
bindingExpression.UpdateSource();)
5. OneWayToSource 反向綁定,目標屬性的改變 及時更新數據源。
1.5 UpdateSourceTrigger 四種用來確定屬性更改的時機,對於 Model=TwoWay 及 OneWayToSource是源數據改變時機。
1.Default 由不同控件控制. 例如 TextBox, 當 LostFocus 事件觸發時,目標綁定發生變化.
2.PropertyChanged 意味着當目標控件值發生變化時,源數據立馬更新.例如, TextBox是目標綁定,當輸入字符時, 源數據也發生變化.
這就意味着當你輸入字符的時候,TextBox的數據Text也在改變 源數據也在改變。 這是比較消耗系統資源,更新的頻率比較快。
3.LostFocus 當目標控件失去焦點后,源數據發生變化。
4.Explicit 當UpdateSourceTrigger 設置為 Explicit, 數據源不會自動更新,只有在后代碼里面顯示的觸發。
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtB_info, TextBlock.FontSizeProperty);//方式一
//BindingExpression bindingExpression=txtB_info.GetBindingExpression(TextBlock.FontSizeProperty);//方式二
bindingExpression.UpdateSource();
2.UI屬性綁定數據對象。
2.1 UI屬性直接綁定實例對象 2.2 UI屬性直接綁定靜態對象 2.3 UI屬性綁定資源中的對象。
前台布局代碼
<Window x:Class="WPFBindingDemo.RelativeSourceWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFBindingDemo" Title="RelativeSourceWindow" Height="300" Width="500"> <Window.Resources> <local:Student x:Key="stuKey" StudentID="20110702" Name="王六" EntryDate="2011-09-01" Credit="80.5"/> </Window.Resources> <StackPanel Orientation="Vertical"> <GroupBox Header="綁定實例對象"> <StackPanel Orientation="Horizontal" Name="stackPanel1"> <TextBlock Text="學號:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入學日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="學分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="綁定靜態對象"> <StackPanel Orientation="Horizontal" DataContext="{x:Static local:GlobalData.student}"> <TextBlock Text="學號:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入學日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="學分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="綁定資源中的對象"> <StackPanel Orientation="Horizontal" DataContext="{StaticResource ResourceKey=stuKey}"> <TextBlock Text="學號:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入學日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="學分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="修改綁定對象的值"> <StackPanel Orientation="Horizontal" ButtonBase.Click="StackPanel_Click"> <Button Name="btn_new" Content="修改實體對象值" Margin="10 0 0 0"></Button> <Button Name="btn_static" Content="修改靜態對象值" Margin="20 0 0 0"></Button> <Button Name="btn_resource" Content="修改資源中對象的值" Margin="20 0 0 0"></Button> </StackPanel> </GroupBox> </StackPanel> </Window>
輔助 Student類
public class Student { public Student() { } private int studentID; /// <summary> /// 學號 /// </summary> public int StudentID { get { return studentID; } set { studentID = value; } } private string name; /// <summary> /// 姓名 /// </summary> public string Name { get { return name; } set { name = value; } } private DateTime entryDate; /// <summary> /// 入學日期 /// </summary> public DateTime EntryDate { get { return entryDate; } set { entryDate = value; } } private double credit; /// <summary> /// 學分 /// </summary> public double Credit { get { return credit; } set { credit = value; } } }
Xaml 后台代碼:
public RelativeSourceWindow() { //對靜態對象進行賦值 Student stu = new Student { StudentID = 20130602, Name = "李四", EntryDate = DateTime.Parse("2012-09-15"), Credit = 40.5 }; GlobalData.student = stu; InitializeComponent(); //實例對象數據源 stackPanel1.DataContext = new Student() { StudentID=20130501, Name="張三", EntryDate=DateTime.Parse("2013-09-01"), Credit=0.0}; } private void StackPanel_Click(object sender, RoutedEventArgs e) { Button btn = e.OriginalSource as Button; if (btn != null) { switch (btn.Name) { case "btn_new": { Student stu = (Student)stackPanel1.DataContext; stu.Name = "張三三"; stu.Credit = 34.5; } break; case "btn_static": { GlobalData.student.Name = "李四四"; GlobalData.student.EntryDate = DateTime.Now; } break; case "btn_resource": { Student stu = (Student)this.FindResource("stuKey"); stu.Name = "王六六"; stu.StudentID = 20140025; } break; default: break; } } }
全局靜態變量:
public class GlobalData { public static Student student = null; }
效果截圖:
2.4 實現
積極更新機制的【單個類實現INotifyPropertyChanged、集合要 實現INotifyCollectionChanged接口】 Student 要實現 INotifyPropertyChanged 接口。
修改后 Student 類
public class Student:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName); handler(this, e); } } public Student() { } private int studentID; /// <summary> /// 學號 /// </summary> public int StudentID { get { return studentID; } set { if (studentID == value) return; studentID = value; OnPropertyChanged("StudentID"); } } private string name; /// <summary> /// 姓名 /// </summary> public string Name { get { return name; } set { if (name == value) { return; } name = value; OnPropertyChanged("Name"); } } private DateTime entryDate; /// <summary> /// 入學日期 /// </summary> public DateTime EntryDate { get { return entryDate; } set { if (entryDate == value) return; entryDate = value; OnPropertyChanged("EntryDate"); } } private double credit; /// <summary> /// 學分 /// </summary> public double Credit { get { return credit; } set { if (credit == value) return; credit = value; OnPropertyChanged("Credit"); } } }
本文寫到這里,希望閱讀后對你有幫助。本人菜鳥一個,望提出寶貴意見。