Binding的使用梳理
1.Binding的基礎概念
將Source的數據傳遞給Target,或者Target的數據傳遞給Source
2.Binding最簡單的綁定
創建一個普通的Student類,包含一個Name屬性,當作Source
讓這個類繼承INotifyPropertyChanged接口,實現該接口,即聲明
一個PropertyChangedEventHandler事件
也可以在XAML中做綁定,XAML語言是不能直接訪問對象的,只能通過ElementName=sourceName,即通過設置ElementName,對象名字來訪問對象
<TextBox x:Name="text1" Margin="5" Text="{Binding Path=Value,ElementName=slider1}"/> <Slider x:Name="slider1" Margin="5" Maximum="100" Minimum="0" />XAML中進行綁定最好是簡單的綁定,只有Source Path 這種是比較合適的,當涉及到數據校驗或者數據轉換的時候,需要在C#的代碼中實現較為合適。
可以看出的是XAML中進行Binding的方式是對某一屬性使用擴展方法進行賦值,賦值的內容為"{Binding Path= , ElementName =,…}"
3.沒有Path的綁定
Source本身就是一個值的時候,即Source為Path的時候可以省略掉Path
對應的C#綁定代碼為
string mystring = “菩提本無樹,明鏡亦非臺。本來無一物,何處惹塵埃。”;
this.textBlock1.SetBinding(TextBlock.TextProperty, new Binding(".") { Source = mystring });
4.作為Source的情況,當Source指定好之后,Path就可以比較簡單的確認了,無論是Source本身還是其中的某一屬性。
(1)普通的類(注意要實現INotifyPropertyChanged接口來通知binding數據更新),或者普通的控件都可以作為Source
(2)DataContext:所有的控件都有這個屬性,當沒有給這個屬性賦值的時候,會根據UI樹向上尋找有賦該值的控件,然后借用其值(依賴屬性的定義)
先聲明一個學生類
注意不要聲明字段,在XAML中為DatatContext中設置的時候讀取不到字段。
XAML中設置TextBox與Student中類的屬性進行綁定
這時候是沒有指明Source的,聲明綁定過后,會在UI樹上尋找有該屬性的控件然后綁定該屬性的值。
例如:第一個TextBox 綁定的 Path是Name,這時候就會在UI樹上找那個控件有對應的值,這時候發現 StackPanel中的DataContext有該值,則進行綁定。
另外比較特殊的是,如果Source即是Path則 可以直接寫作Text="{Binding}" 這種既無Source也無Path的形式。
(3)關于鏈表式控件的綁定
鏈表式控件,可以像普通的綁定那樣進行一對一的綁定。
并且鏈表式控件都有ItemsSource,該屬性接收一個IEnumerable接口派送類的對象。并且鏈表式控件具有條目容器。當使用 ItemsSource接收數據時,就會為每個數據都準備條目容器,當作數據外衣使用。
做一個簡單的例子:
XAML中聲明一個鏈表式控件:
在C#中聲明一個List,并且與listStudent進行綁定
List<Student> students = new List<Student>{new Student(){ Id=0,Age=29,Name="tim"},new Student(){ Id=1,Age=26,Name="tom"},new Student(){ Id=2,Age=25,Name="lucy"},new Student(){ Id=3,Age=24,Name="jerry"},new Student(){ Id=4,Age=23,Name="nancy"},new Student(){ Id=5,Age=22,Name="mike"},};this.listStudent.ItemsSource = students;this.listStudent.DisplayMemberPath = "Name";唯一的缺陷是這個條目容器是默認值的,只能顯示一個值,當要同時顯示Id,Age,Name的時候就需要自己設計條目容器ItemTemplate,DataTemplate
<ListBox x:Name="listStudent" Height="300" Width="500"><ListBox.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Path=Id}" Width="30"/><TextBlock Text="{Binding Path=Name}" Width="60"/><TextBlock Text="{Binding Path=Age}" Width="30"/></StackPanel></DataTemplate></ListBox.ItemTemplate></ListBox>說完鏈表式控件作為Target使用的過程,可以作為鏈表式控件的Source的是IEnumrable的派送類??梢钥吹奖容^常用的場景有:
①ADO.NET讀取的數據庫的數據
ADO.NET類,常用來與數據庫做交互使用。常見的工作是從數據庫中讀取數據到DataTable中,在把DataTable中的數據顯示在UI上。
比較特殊的是DataTable不能直接綁定在鏈表式控件的ItemsSource上。一般是
DataTable dt=this.Load();
this.listName.DisplayMemberPath=“Name”;
this.listName.ItemsSource=dt.DefaultView;
DataTable的DefaultView中的值是DataView類型的對象實現了IEnumerable接口
為了更好的展示就使用ListView控件來展示,手動的設置條目容器的樣式。XAML代碼如下:
條目容器的設置是設置相關的View屬性。View屬性的值是GridView。GridView的屬性值是Column。綁定的Target.Property也變成了DisplayMemberBinding。
綁定的Source還是ItemsSource。
已知的是DataTable是不能直接賦給ItemsSource的,但是可以賦給控件的DataContext,然后直接進行沒有Source的綁定。
②XML數據
主要是XML數據讀取轉換成IEnumerable派送類這塊,后續綁定和前面說的鏈表式控件的綁定過程一樣。
使用的是XmlDataProvider類。
設置條目容器的樣式的時候的展示內容,在Xaml中需要注意的是,如果是Xml的Attribute要加@,不加的是子級元素
<GridViewColumn Header="TileName" Width="60" DisplayMemberBinding="{Binding XPath=@AttributepathName}"/> <GridViewColumn Header="TileName" Width="60" DisplayMemberBinding="{Binding XPath=pathName}"/>XML語言是很方便展示樹形結構的數據。
③前面兩種都可以通過 Linq語言直接處理之后變為IEnumerable類型的數據,直接賦給ItemsSource屬性。
this,listViewName.ItemsSource= from list1 in listName Where … select stu;
關于數據庫文件與Xml文件通過Linq處理的,單獨列章分析。
5.有時候要綁定的Source是別人類庫的東西,或者是通過別人封裝好的方法的返回值,這時候就可以通過ObjectDataProvider來包裝作為Binding源的數據對象。
ObjectDataProvider包裝過程 ObjectDataProvider odp = new ObjectDataProvider(); odp.ObjectInstance = new ClassName(); odp.MethodName = "MethodName"; odp.MethodParameters.Add("Arg[0]"); odp.MethodParameters.Add("Arg[1]");Demo:
設置一個Calculator類做加法運算
使用ObjectDataProvider進行封裝
ObjectDataProvider odp = new ObjectDataProvider(); odp.ObjectInstance = new Calculator(); odp.MethodName = "Add"; odp.MethodParameters.Add("0"); odp.MethodParameters.Add("0");設置Binding:
<StackPanel Background="LightBlue"><TextBox x:Name="textArg1" Margin="5"/><TextBox x:Name="textArg2" Margin="5"/><TextBox x:Name="textArgResult" Margin="5"/></StackPanel>C#中運行就調用的方法:
private void SetBinding() {ObjectDataProvider odp = new ObjectDataProvider();odp.ObjectInstance = new Calculator();odp.MethodName = "Add";odp.MethodParameters.Add("0");odp.MethodParameters.Add("0");Binding bindingToArg1 = new Binding("MethodParameters[0]") {Source = odp,BindsDirectlyToSource=true,UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged};Binding bindingToArg2 = new Binding("MethodParameters[1]"){Source = odp,BindsDirectlyToSource = true,UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged};Binding bindingToResult = new Binding(".") { Source = odp };this.textArg1.SetBinding(TextBox.TextProperty,bindingToArg1);this.textArg2.SetBinding(TextBox.TextProperty, bindingToArg2);this.textArgResult.SetBinding(TextBox.TextProperty, bindingToResult);}6.Source為RelativeSource
先初始化該類
初始化的Mode,為枚舉類型,分別為PreviousData,TemplatedParent,Self和FindAncestor,前三個是創建RelativeSource實例,把實例的Mode是指為相應的值,然后返回這個實例。
Demo:
如果是其他三個則可以直接使用:
RelativeSource rs = new RelativeSource(RelativeSourceMode.Self); this.t1.SetBinding(TextBox.TextProperty, new Binding("Name") { RelativeSource=rs});7.Binding過程的數據校驗
Binding數據校驗主要是使用Binding.Validation.Add(ValidationRule)
參數為實現了ValidationRule的派生類。
Demo:
如果要在UI樹上通知校驗后的信息,只需要把
Binding.ValidationOnNotifyDataErrors=true;然后在需要顯示的UI控件上做路由偵聽。(路由事件的時候具體寫)
8.Binding數據的轉換
數據的傳輸很多時候要面對的問題是數據類型。
當Source Path與Target的類型不一樣的時候,如slider的Value是Double,而Text是String。
一些簡單的數據轉換Binding會自動實現,像是Double->String。
遇到復雜的情況需要自己實現 Data Converter
即創建一個類實現IValueConverter接口的類
從Source->Target時調用Convert
從Target->Source時調用ConvertBack
使用的時候直接設置:
9.MutilBinding
MutilBinding mb=new MutilBinding(); mb.MutilBindings.Add(new Binding());另外這種多個Source綁定一個Target的數據類型轉換器Data Converter要實現的是IMutilValueConverter接口,實現的方法同IValueConverter差不多,不過傳遞的第一個參數為object[] values。
MutilBindings.Add添加的時候是順序敏感的。
整理《深入淺出WPF》
總結
以上是生活随笔為你收集整理的Binding的使用梳理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 频率混叠
- 下一篇: 安装VMware出现无效驱动器