四、 XML數據綁定
這次我們來學習新的綁定知識,XML數據綁定。XmlDataProvider 用來綁定 XML 數據,該XML數據可以是嵌入.Xmal文件的 XmlDataProvider 標記中,也可以是外部位置引用的文件中。
當然嵌入式 XML 內容必須置于 XmlDataProvider 內部的 <x:XData> 標記中,而且不容易修改,所以建議使用XML數據文件形式。對于 XmlDataProvider 必須命名一個 x:Key 值,以便數據綁定目標可對其進行引用。
XmlDataProvider 也可以指向 XML 內容的外部源。例如,項目中一個 colors.xml 文件,文件的內容就是一個顏色列表。需要在 <StackPanel.Resources>
中添加一個 XmlDataProvider 資源,并將其的Source設置為 XML 文件名即可。 代碼與XML文件如下。
<StackPanel> <StackPanel.Resources> <XmlDataProvider x:Key="MyColors" Source="Colors.xml" XPath="colors"> </XmlDataProvider> </StackPanel.Resources>
XML文件:
<?xml version="1.0" encoding="utf-8" ?> <colors > <color name="Pink"/> <color name="Red"/> <color name="Purple"/> <color name="Cyan"/> <color name="Gray"/> <color name="Turquoise"/> </colors>
資源綁定語法與控件綁定語法略有不同。綁定到控件時,可以設置綁定的 ElementName 和 Path 屬性。但是綁定到資源時,需要設置 Source 屬性,由于我們是綁定到 XmlDataProvider,所以還要設置綁定的 XPath 屬性。例如,下列代碼可將 ListBox 的項綁定 MyColors資源。將 Source 屬性設置為資源,并將其指定為名為 MyColors 的 StaticResource。XPath 屬性指示項會綁定到 XML 數據源中 <color> 元素的name屬性:
<TextBlock Width="248" Height="24" Text="XML數據綁定:" TextWrapping="Wrap"/> <ListBox x:Name="listXmlColor" Width="248" Height="56" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource MyColors},XPath=color/@name}"> </ListBox> <TextBlock Width="248" Height="24" Text="選中的顏色:" /> <TextBlock Width="248" Height="24" Text="{Binding ElementName=listXmlColor, Path=SelectedValue, Mode=OneWay}" > </TextBlock>
結果如下圖:
五、對象綁定和數據模板
雖然 XmlDataProvider 對 XML 非常有用,但是當您想綁定到對象或對象列表時,可以創建 ObjectDataProvider 作為資源。ObjectDataProvider 的 ObjectType 指定將提供數據綁定源的對象,而 MethodName 則指示為獲得數據而需調用的方法。例如,假設我有一個名為 StudentService 的類,該類使用一種名為 GetStudentList的方法來返回列表 <Student>。那么 ObjectDataProvider 應該如下所示:
<StackPanel.Resources> <ObjectDataProvider x:Key="students" ObjectType="{x:Type local:StudentService}" MethodName="GetStudentList"> </ObjectDataProvider> </StackPanel.Resources>
ObjectDataProvider 還可以使用許多其他屬性。ConstructionParameters 屬性允許您將參數傳遞給要調用的類的構造函數。此外,可以使用 MethodParameters 屬性來指定參數,同時還可以使用 ObjectInstance 屬性來指定現有的對象實例作為源。
如果希望異步檢索數據,可以將 ObjectDataProvider 的 IsAsynchronous 屬性設為 true。這樣,用戶將可以在等待數據填充綁定到 ObjectDataProvider 的源的目標控件時與屏幕進行交互。
在添加 ObjectDataProvider 時,必須限定數據源類的命名空間。在本例中,我必須將 xmlns 屬性添加到 <Window> 標記中,以便 local 快捷方式符合要求,并指示正確的命名空間:
xmlns:local="clr-namespace:WpfApp1.Services"
既然數據源已通過 ObjectDataProvider 定義,接下來就是如何將數據顯示在 ListBox 控件。我要把姓名、年齡、出生日期、國籍在每個 ListBoxItem 中一行顯示。姓名用粗體,年齡、出生日期、國籍使用默認字體顯示。這在 XAML 中,通過使用數據模板(DataTemplate)很容易實現的,DataTemplate 允許您定義自己的顯示樣式。
如下代碼,在XAML代碼中我將 DataTemplate 定義成如何顯示Student信息的布局樣式。我通過設置 DataTemplate 的 DataType 屬性為students,告訴 DataTemplate 將要引用 Student類型。
我將對象數據students綁定到 ListBox 的 ItemsSource 屬性,這樣就把將數據綁定到 ListBox了,但是我沒有指定如何顯示綁定的數據,顯示樣式是通過將 ItemTemplate 屬性設置為 studentLayout資源(即 DataTemplate 的鍵名),就可以根據我之前在模板中設計的顯示樣式顯示數據了。最終結果如下圖 所示。
XMAL代碼:
<StackPanel Grid.Row="3"> <StackPanel.Resources> <ObjectDataProvider x:Key="students" ObjectType="{x:Type local:StudentService}" MethodName="GetStudentList"> </ObjectDataProvider> <DataTemplate x:Key="studentLayout" DataType="students"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Foreground="Blue"/> <TextBlock Text=", "></TextBlock> <TextBlock Text="{Binding Path=Age}"></TextBlock> <TextBlock Text=", "></TextBlock> <TextBlock Text="{Binding Path=Birthday}"></TextBlock> <TextBlock Text=", "></TextBlock> <TextBlock Text="{Binding Path=Country}"></TextBlock> </StackPanel> </DataTemplate> </StackPanel.Resources> <TextBlock Width="248" Height="24" Text="對象數據綁定:" TextWrapping="Wrap"/> <ListBox x:Name="listObjectBind" Width="450" Height="100" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource students}}" ItemTemplate="{DynamicResource studentLayout}"> </ListBox> </StackPanel>
c#代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WpfApp1.Models; namespace WpfApp1.Services { public class StudentService { public List<Student> GetStudentList() { Student liang = new Student(); liang.Age = "18"; liang.Name = "梁丘"; liang.Birthday = "1990-02-03"; liang.Country = "中國"; Student zuo = new Student(); zuo.Age = "22"; zuo.Name = "左丘"; zuo.Birthday = "1992-02-03"; zuo.Country = "中國"; Student diwu = new Student(); diwu.Age = "32"; diwu.Name = "第五言"; diwu.Birthday = "1982-11-03"; diwu.Country = "中國"; Student yang = new Student(); yang.Age = "12"; yang.Name = "羊舌微"; yang.Birthday = "2002-11-13"; yang.Country = "中國"; List<Student> personList = new List<Student>(); personList.Add(liang); personList.Add(zuo); personList.Add(diwu); personList.Add(yang); return personList; } } }
文章列表
留言列表