本页包含并说明使用 LINQ to XML 的 WPF 数据绑定示例的 XAML 源文件。
整体 UI 结构
与 WPF 项目一样,此文件包含一个父元素,即与 Window 命名空间中派生类 L2XDBFrom
关联的 LinqToXmlDataBinding
XML 元素。
客户端区域包含在具有浅蓝色背景的 StackPanel 中。 此面板包含四个 DockPanel UI 区域,由 Separator 条分隔。 此处介绍了这些区域的用途。
每个部分都包含一个标识标签。 在前两个区域中,此标签通过使用 LayoutTransform 旋转 90 度。 该部分的其余部分包含适合该部分用途的 UI 元素,例如文本块、文本框和按钮。 有时使用子 StackPanel 来对齐这些子控件。
窗口资源区域
第 9 行的 <Window.Resources>
开始标记表示窗口资源部分的开头。 它以第 35 行的结束标记结束。
<ObjectDataProvider>
标记跨越第 11 至第 25 行,声明一个名为 ObjectDataProvider 的 LoadedBooks
,它使用 XElement 作为源。 此 XElement 是通过分析嵌入的 XML 文档(一个 CDATA
元素)来初始化的。 请注意,在声明嵌入的 XML 文档以及分析该文档时将保留空格。 保留空格,因为用于显示原始 XML 的 TextBlock 控件没有特殊的 XML 格式设置功能。
最后,第 28 行至第 34 行定义一个名为 DataTemplate 的 BookTemplate
。 此模板用于显示 书籍列表 UI 部分中的条目。 它使用数据绑定和 LINQ to XML 动态属性通过下面的赋值来检索书籍 ID 和书名:
Text="{Binding Path=Attribute[id].Value}"Text="{Binding Path=Value}"
数据绑定代码
除了 DataTemplate 元素,数据绑定还用于此文件中许多其他位置。
在第 38 行的 <StackPanel>
开始标记中,此面板的 DataContext 属性设置为 LoadedBooks
数据提供程序。
DataContext="{Binding Source={StaticResource LoadedBooks}}
设置数据上下文使名为 TextBlock 的 tbRawXml
(第 46 行)能够通过绑定到此数据提供程序的 Xml
属性来显示原始 XML:
Text="{Binding Path=Xml}"
从第 58 行至第 62 行,“Book List”(书籍列表)UI 区域中的 ListBox 将其显示项的模板设置为在窗口资源区域中定义的 BookTemplate
:
ItemTemplate ="{StaticResource BookTemplate}"
然后,第 59 行至第 62 行将书籍的实际值绑定到此列表框:
<ListBox.ItemsSource>
<Binding Path="Elements[{http://www.mybooks.com}book]"/>
</ListBox.ItemsSource>
在第三个 UI 区域“Edit Selected Book”(编辑所选书籍)中,首先将父 的 DataContext 绑定到“Book List”(书籍列表)UI 区域中的当前所选项(第 82 行)StackPanel:
DataContext="{Binding ElementName=lbBooks, Path=SelectedItem}"
然后,它使用双向数据绑定,以便在此面板中的两个文本框中显示和更新书本元素的当前值。 数据绑定到动态属性类似于在 BookTemplate
数据模板中使用数据绑定:
Text="{Binding Path=Attribute[id].Value}"...Text="{Binding Path=Value}"
最后一个 UI 区域“Add New Book”(新增书籍)不在其 XAML 代码中使用数据绑定。 相反,数据绑定在文件 L2DBForm.xaml.cs的事件处理代码中进行。
示例:
DESCRIPTION
注释
建议将下面的代码复制到代码编辑器中,例如 Visual Studio 中的 C# 源代码编辑器,以便行号更易于跟踪。
代码
<Window x:Class="LinqToXmlDataBinding.L2XDBForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:xlinq="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq"
xmlns:local="clr-namespace:LinqToXmlDataBinding"
Title="WPF Data Binding using LINQ-to-XML" Height="665" Width="500" ResizeMode="NoResize">
<Window.Resources>
<!-- Books provider and inline data -->
<ObjectDataProvider x:Key="LoadedBooks" ObjectType="{x:Type xlinq:XElement}" MethodName="Parse">
<ObjectDataProvider.MethodParameters>
<system:String xml:space="preserve">
<![CDATA[
<books xmlns="http://www.mybooks.com">
<book id="0">book zero</book>
<book id="1">book one</book>
<book id="2">book two</book>
<book id="3">book three</book>
</books>
]]>
</system:String>
<xlinq:LoadOptions>PreserveWhitespace</xlinq:LoadOptions>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<!-- Template for use in Books List listbox. -->
<DataTemplate x:Key="BookTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="3" Text="{Binding Path=Attribute[id].Value}"/>
<TextBlock Margin="3" Text="-"/>
<TextBlock Margin="3" Text="{Binding Path=Value}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<!-- Main visual content container -->
<StackPanel Background="lightblue" DataContext="{Binding Source={StaticResource LoadedBooks}}">
<!-- Raw XML display section -->
<DockPanel Margin="5">
<Label Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">XML
<Label.LayoutTransform>
<RotateTransform Angle="90"/>
</Label.LayoutTransform>
</Label>
<TextBlock Name="tbRawXml" Height="200" Background="LightGray" Text="{Binding Path=Xml}" TextTrimming="CharacterEllipsis" />
</DockPanel>
<Separator Height="4" Margin="5" />
<!-- List box to display all books section -->
<DockPanel Margin="5">
<Label Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">Book List
<Label.LayoutTransform>
<RotateTransform Angle="90"/>
</Label.LayoutTransform>
</Label>
<ListBox Name="lbBooks" Height="200" Width="415" ItemTemplate ="{StaticResource BookTemplate}">
<ListBox.ItemsSource>
<Binding Path="Elements[{http://www.mybooks.com}book]"/>
</ListBox.ItemsSource>
</ListBox>
<Button Margin="5" DockPanel.Dock="Right" Height="30" Width ="130" Content="Remove Selected Book" Click="OnRemoveBook">
<Button.LayoutTransform>
<RotateTransform Angle="90"/>
</Button.LayoutTransform>
</Button>
</DockPanel>
<Separator Height="4" Margin="5" />
<!-- Edit current selection section -->
<DockPanel Margin="5">
<TextBlock Margin="5" Height="30" Width="65" DockPanel.Dock="Right" Background="LightGray" TextWrapping="Wrap" TextAlignment="Center">
Changes are live!
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
<StackPanel>
<Label Width="450" Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" FontWeight="Bold">Edit Selected Book</Label>
<StackPanel Margin="1" DataContext="{Binding ElementName=lbBooks, Path=SelectedItem}">
<StackPanel Orientation="Horizontal">
<Label Width="40">ID:</Label>
<TextBox Name="editAttributeTextBox" Width="410" Text="{Binding Path=Attribute[id].Value}">
<TextBox.ToolTip>
<TextBlock FontWeight="Bold" TextAlignment="Center">
<Label>Edit the selected book ID and see it changed.</Label>
</TextBlock>
</TextBox.ToolTip>
</TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Width="40">Value:</Label>
<TextBox Name="editValueTextBox" Width="410" Text="{Binding Path=Value}" Height="25">
<TextBox.ToolTip>
<TextBlock FontWeight="Bold" TextAlignment="Center">
<Label>Edit the selected book Value and see it changed.</Label>
</TextBlock>
</TextBox.ToolTip>
</TextBox>
</StackPanel>
</StackPanel>
</StackPanel>
</DockPanel>
<Separator Height="4" Margin="5" />
<!-- Add new book section -->
<DockPanel Margin="5">
<Button Margin="5" Height="30" DockPanel.Dock="Right" Click ="OnAddBook">Add Book
<Button.LayoutTransform>
<RotateTransform Angle="90"/>
</Button.LayoutTransform>
</Button>
<StackPanel>
<Label Width="450" Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" FontWeight="Bold">Add New Book</Label>
<StackPanel Margin="1">
<StackPanel Orientation="Horizontal">
<Label Width="40">ID:</Label>
<TextBox Name="tbAddID" Width="410">
<TextBox.ToolTip>
<TextBlock FontWeight="Bold" TextAlignment="Center">
<Label>Enter a book ID and Value pair, then click Add Book.</Label>
</TextBlock>
</TextBox.ToolTip>
</TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Width="40">Value:</Label>
<TextBox Name="tbAddValue" Width="410" Height="25">
<TextBox.ToolTip>
<TextBlock FontWeight="UltraBold" TextAlignment="Center">
<Label>Enter a book ID and Value pair, then click Add Book.</Label>
</TextBlock>
</TextBox.ToolTip>
</TextBox>
</StackPanel>
</StackPanel>
</StackPanel>
</DockPanel>
</StackPanel>
</Window>
注释
有关与 WPF UI 元素关联的事件处理程序的 C# 源代码,请参阅 L2DBForm.xaml.cs 源代码。