WP8.1学习系列(第二十三章)——到控件的数据绑定
本主题介绍了如何在使用 C++、C# 或 Visual Basic 的 Windows 应用商店应用中将控件绑定到单个项或将列表控件绑定到项目集合。此外,本主题向你介绍了如何自定义控件项目的显示、如何基于所选内容实现详细信息视图,以及如何转换数据以进行显示。有关更多详细信息,请参阅使用 XAML 进行数据绑定。
路线图: 本主题与其他主题有何关联?请参阅:
先决条件
本主题假定你可以使用 Microsoft Visual Basic、Microsoft Visual C# 或 Microsoft Visual C++ 创建基本 Windows 运行时应用。有关创建你的第一个 Windows 运行时应用的说明,请参阅使用 C# 或 Visual Basic 创建你的第一个 Windows 应用商店应用。
将控件绑定到单个项目
数据绑定包括一个目标和一个源。目标通常是控件的属性,源通常是数据对象的属性。有关目标和源要求的信息,请参阅使用 XAML 进行数据绑定。
下面是将控件绑定到单个项目的一个示例。目标是文本框控件的 Text 属性。源是一个简单的音乐 Recording
类。
- <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
- <TextBox x:Name="textBox1" Text="{Binding}" FontSize="30"
- Height="120" Width="440" IsReadOnly="True"
- TextWrapping="Wrap" AcceptsReturn="True" />
- </Grid>
- // Constructor
- public MainPage()
- {
- InitializeComponent();
- // Set the data context to a new Recording.
- textBox1.DataContext = new Recording("Chris Sells", "Chris Sells Live",
- new DateTime(2008, 2, 5));
- }
- // A simple business object
- public class Recording
- {
- public Recording() { }
- public Recording(string artistName, string cdName, DateTime release)
- {
- Artist = artistName;
- Name = cdName;
- ReleaseDate = release;
- }
- public string Artist { get; set; }
- public string Name { get; set; }
- public DateTime ReleaseDate { get; set; }
- // Override the ToString method.
- public override string ToString()
- {
- return Name + " by " + Artist + ", Released: " + ReleaseDate.ToString("d");
- }
- }
上述代码会产生类似下图的输出。
若要在文本框中显示音乐录音,请通过使用标记扩展将控件的 Text 属性设置为 Binding。在此示例中,默认情况下 Mode 是 OneWay,这意味着数据是从源检索的,但不会将更改传播回到源。
Recording
类有三个公共属性和一个 ToString 方法重写。这三个属性是 Artist
、Name
和ReleaseDate
。ToString 方法很重要,因为如果未指定任何格式,会出于显示目的在绑定对象上调用 ToString方法。该绑定的 Binding.Source 属性不是直接设置的,而是将 TextBox 控件的 DataContext 属性设置为一个新的 Recording
对象。
将控件绑定到对象的集合
上一个示例展示了用于将数据绑定到控件的语法,但这不是很实际。一个更常见的情形是绑定到业务对象的集合。在 C# 和 Visual Basic 中,通用 ObservableCollection<T> 类是数据绑定的一个很好的集合选择,因为它实现INotifyPropertyChanged 和 INotifyCollectionChanged 接口。当列表中的项目改变时,或列表本身的属性改变时,这些接口向绑定控件提供更改通知。如果你希望你的绑定控件使用集合中的对象属性更改进行更新,则业务对象也应该实现 INotifyPropertyChanged。 有关在 C++ 中进行绑定的信息,请参阅使用 XAML 进行数据绑定。
以下示例将音乐 Recording
对象集合绑定到 ComboBox。若要尝试此示例,请单击组合框中的向下箭头,以查看绑定录音列表。
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
- Foreground="Black" FontSize="30" Height="50" Width="780"/>
- </Grid>
- public ObservableCollection<Recording> MyMusic = new ObservableCollection<Recording>();
- public Page()
- {
- InitializeComponent();
- // Add items to the collection.
- MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live",
- new DateTime(2008, 2, 5)));
- MyMusic.Add(new Recording("Luka Abrus",
- "The Road to Redmond", new DateTime(2007, 4, 3)));
- MyMusic.Add(new Recording("Jim Hance",
- "The Best of Jim Hance", new DateTime(2007, 2, 6)));
- // Set the data context for the combo box.
- ComboBox1.DataContext = MyMusic;
- }
上述代码会产生类似下图的输出。
若要显示 ComboBox 中的音乐录音,则将该控件的 ItemsSource 属性设置为 Binding,并将 ComboBox 控件的 DataContext 属性设置为 Recording
对象的集合,该集合为绑定提供源。针对集合中的每个项都创建了一个 ComboBoxItem。针对每个 Recording
对象将自动调用 ToString,以在组合框项中显示该对象。
通过使用数据模板显示控件中的项目
你可以通过使用项目的 ToString 方法显示列表中的项目。但是,一种更常见的情形是通过使用 DataTemplate来提供数据绑定项目的自定义显示。使用 DataTemplate,可以自定义在控件中显示列表项的方式。通常,通过使用内容控件的 ContentTemplate 属性或项控件的 ItemTemplate 属性来设置数据模板。
以下示例显示了通过使用数据模板绑定到某个组合框的相同录音列表。组合框是 ItemsControl,这意味着通过将每个项目的 ItemTemplate 属性设置为一个数据模板来为每个项目建立数据模板。若要尝试此示例,请单击向下箭头,以查看录音列表。请注意这些录音与上一示例有何不同。在自定义格式中会显示艺术家和 CD 名称。
- <ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
- Foreground="Black" FontSize="30" Height="50" Width="450">
- <ComboBox.ItemTemplate>
- <DataTemplate>
- <StackPanel Orientation="Horizontal" Margin="2">
- <TextBlock Text="Artist:" Margin="2" />
- <TextBlock Text="{Binding Artist}" Margin="2" />
- <TextBlock Text="CD:" Margin="10,2,0,2" />
- <TextBlock Text="{Binding Name}" Margin="2" />
- </StackPanel>
- </DataTemplate>
- </ComboBox.ItemTemplate>
- </ComboBox>
上述代码会产生类似下图的输出。
在 XAML 中,你可以看到数据模板定义。数据模板包含一个带有四个 TextBlock 控件的 StackPanel。堆叠面板具有一个水平方向,这样四个文本块控件会并排显示。其中两个 TextBlock 控件绑定到 Recording
对象的 Artist 和 Name 属性。另外两个 TextBlock 控件显示静态文本。对于每个绑定项,该绑定提供到 Recording
对象上的属性的路径。如上一示例中所示,该绑定依赖于要设置为录音列表的数据上下文。
此 XAML 使用属性元素语法。有关 XAML 语法的详细信息,请参阅快速入门:使用 XAML 创建用户界面。有关控件布局的详细信息,请参阅快速入门:定义布局。
添加详细信息视图
从集合中选择项目时,要显示项目的详细信息,你必须创建相应的 UI 并将该 UI 绑定到你希望其显示的数据。此外,必须将 CollectionViewSource 用作数据上下文以使详细信息视图能够绑定到当前项。
以下示例显示了相同的录音列表,但这次该列表是某个 CollectionViewSource 实例的数据源。会将整个页面或用户控件的数据上下文设置为集合视图源,且组合框和详细信息视图会继承数据上下文。这使得组合框绑定到集合并且能够显示相同的项列表,同时详细信息视图会自动绑定到当前项。详细信息视图不需要明确绑定到当前项,因为集合视图源自动提供数据的相应级别。
若要尝试此示例,请单击向下箭头,并选择不同的录音。请注意,艺术家、CD 名称和发布日期会显示在详细信息视图中的相应组合框下方。
- <!--The UI for the details view-->
- <StackPanel x:Name="RecordingDetails">
- <TextBlock Text="{Binding Artist}" FontWeight="Bold" FontSize="30" />
- <TextBlock Text="{Binding Name}" FontStyle="Italic" FontSize="30" />
- <TextBlock Text="{Binding ReleaseDate}" FontSize="30" />
- </StackPanel>
- // Set the DataContext on the parent object instead of the ComboBox
- // so that both the ComboBox and details view can inherit it.
- // ComboBox1.DataContext = MyMusic;
- this.DataContext = new CollectionViewSource { Source = MyMusic };
上述代码会产生类似下图的输出。
在此示例中,将向包含现有组合框的用户控件中添加一个 StackPanel。接下来是包含用于显示录音详细信息的三个文本块的一个堆叠面板。每个文本块的 Text 属性将绑定到 Recording
对象上的某个属性。
转换数据以在控件中显示
如果需要在控件中设置某个非字符串类型(如 TextBox)的格式并显示该类型,则可以使用转换器。例如,你可以显示一个标签和一个已设置格式的日期,而不是仅显示该日期。
以下示例将展示在录音列表中发布日期的某个转换器实现。若要尝试此示例,请单击向下箭头,并选择不同的录音。请注意,下拉列表和详细信息视图中的发布日期会以自定义格式显示。
- <UserControl x:Class="TestDataBindingQS.Page2"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="using:TestDataBindingQS"
- mc:Ignorable="d"
- d:DesignHeight="768" d:DesignWidth="1366">
- <UserControl.Resources>
- <local:StringFormatter x:Key="StringConverter"/>
- </UserControl.Resources>
- <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
- <StackPanel Width="750" Height="200"
- VerticalAlignment="Center" HorizontalAlignment="Center">
- <ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
- Foreground="Black" FontSize="30" Height="50" Width="750">
- <ComboBox.ItemTemplate>
- <DataTemplate>
- <StackPanel Orientation="Horizontal" Margin="2">
- <TextBlock Text="Artist:" Margin="2" />
- <TextBlock Text="{Binding Artist}" Margin="2" />
- <TextBlock Text="CD:" Margin="10,2,0,2" />
- <TextBlock Text="{Binding Name}" Margin="2" />
- </StackPanel>
- </DataTemplate>
- </ComboBox.ItemTemplate>
- </ComboBox>
- <!--The UI for the details view-->
- <StackPanel x:Name="RecordingDetails">
- <TextBlock Text="{Binding Artist}" FontSize="30" FontWeight="Bold" />
- <TextBlock Text="{Binding Name}" FontSize="30" FontStyle="Italic" />
- <TextBlock Text="{Binding ReleaseDate,
- Converter={StaticResource StringConverter},
- ConverterParameter=Released: \{0:d\}}" FontSize="30" />
- </StackPanel>
- </StackPanel>
- </Grid>
- </UserControl>
- public class StringFormatter : IValueConverter
- {
- // This converts the value object to the string to display.
- // This will work with most simple types.
- public object Convert(object value, Type targetType,
- object parameter, System.Globalization.CultureInfo culture)
- {
- // Retrieve the format string and use it to format the value.
- string formatString = parameter as string;
- if (!string.IsNullOrEmpty(formatString))
- {
- return string.Format(culture, formatString, value);
- }
- // If the format string is null or empty, simply
- // call ToString() on the value.
- return value.ToString();
- }
- // No need to implement converting back on a one-way binding
- public object ConvertBack(object value, Type targetType,
- object parameter, System.Globalization.CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
上述代码会产生类似下图的输出。
转换器是从 IValueConverter 接口派生出的一个类。IValueConverter 有两种方法:Convert 和ConvertBack。对于从数据源到绑定目标的单向绑定,仅仅需要实现 Convert 方法。此示例中的转换器是相当通用的。可以将所需的字符串格式作为参数传递,且转换器会使用 String.Format 方法执行转换。如果未传递任何格式字符串,则转换器会返回在对象上调用 ToString 的结果。
在你实现转换器之后,你要立即创建转换器类的一个实例,并通知绑定使用此实例。在此示例中,这是在 XAML 中执行的。转换器的实例是作为静态资源创建的,并会向其分配一个键。在绑定上设置转换器属性时,会使用该键。
有关如何转换数据以便在控件中显示的详细信息,请参阅IValueConverter。
WP8.1学习系列(第二十三章)——到控件的数据绑定的更多相关文章
- 【WPF学习】第二十三章 列表控件
WPF提供了许多封装项的集合的控件,本章介绍简单的ListBox和ComboBox控件,后续哈会介绍更特殊的控件,如ListView.TreeView和ToolBar控件.所有这些控件都继承自Item ...
- WP8.1学习系列(第五章)——中心控件Hub或透视控件Pivot交互UX
具有主页菜单(中心或透视控件)的中心应用中心 你可能要设计包含许多功能的应用.当你看着这些功能时,可能会决定将它们整理到独立的区域中.这些区域最终会成为用户要访问的应用的独立部分.你需要设计一个简便的 ...
- WP8.1学习系列(第十一章)——中心控件Hub开发指南
在本文中 先决条件 什么是中心控件? 添加中心控件 将分区添加到中心 添加交互式分区头用于导航 将展示磁贴添加到中心 使用窄应用中的垂直中心 借助中心使用语义式缩放视图 摘要和后续步骤 重要的 API ...
- WP8.1学习系列(第六章)——中心控件Hub面板部分交互UX
本主题中呈现的模型类似于适用于 Windows Phone 的具有主页菜单(中心或透视控件)的中心应用中描述的模型.正如之前的案例所示,你要向用户呈现不同的功能区域.此处的区别在于你可以在顶层呈现所有 ...
- WP8.1学习系列(第二十七章)——ListView和GridView入门
快速入门:添加 ListView 和 GridView 控件 (XAML) 在本文中 先决条件 选择 ListView 或 GridView 将项添加到项集合 设置项目源 指定项目的外观 指定视图 ...
- WP8.1学习系列(第二十一章)——本地应用数据
了解如何存储和检索本地应用数据存储中的设置和文件. 路线图: 本主题与其他主题有何关联?请参阅: 使用 C# 或 Visual Basic 的 Windows 运行时应用的路线图 使用 C++ 的 W ...
- Ext入门学习系列(五)表格控件(1)
上节学习了Ext面板控件,为后面的各个控件学习奠定基础,在此基础上本章将学习网络开发最期待的功能——表格控件. 我们都知道网络编程语言中,除了.net其他的基本没有提供网格控件,而最近的asp.net ...
- WP8.1学习系列(第二十五章)——控件样式
XAML 框架提供许多自定义应用外观的方法.通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 路线图: 本主题与其他主题有何关联?请参阅: 使用 C# 或 Visua ...
- WP8.1学习系列(第二十章)——添加控件和处理事件
先决条件 添加控件 设置控件的名称 设置控件属性 创建事件处理程序 新控件 总结 相关主题 通过使用如按钮.文本框和组合框等控件,你可以创建应用的 UI. 下面将显示如何将控件添加到应用.处理控件时, ...
随机推荐
- JUnit4参数化测试实例
在JUnit中,可以同时使用@RunWith 和 @parameter 注解来为单元测试传递参数. 注意: 在Eclipse中因为版本问题,可能无法使用@parameters(name = " ...
- Yii2 session的使用方法(1)
yii2打开session use yii\web\Session; $session = Yii::$app->session; // check if a session is alread ...
- 机器学习——利用SVD简化数据
奇异值分解(Singular Value Decompositon,SVD),可以实现用小得多的数据集来表示原始数据集. 优点:简化数据,取出噪声,提高算法的结果 缺点:数据的转换可能难以理解 适用数 ...
- 大数据学习笔记01-HDFS-集群安装
安装 下载 Hadoop,以2.7.5版本为例 在虚拟机上创建目录bigdata,即执行mkdir bigdata 上传到master机器节点的目录~/bigdata下(可以用FileZilla等ft ...
- zip压缩工具 tar打包 打包并压缩
6.5 zip压缩工具 6.6 tar打包 6.7 打包并压缩 zip压缩工具 xz,bzip2,gzip都不支持压缩目录 zip可以压缩目录 压缩文件 zip 2.txt.zip 2.txt [ ...
- css box-shadow添加阴影
基础说明: 外阴影:box-shadow: X轴 Y轴 Rpx color; 属性说明(顺序依次对应): 阴影的X轴(可以使用负值) 阴影的Y轴(可以使用负值) 阴影 ...
- UNIX环境编程学习笔记(20)——进程管理之exec 函数族
lienhua342014-10-07 在文档“进程控制三部曲”中,我们提到 fork 函数创建子进程之后,通常都会调用 exec 函数来执行一个新程序.调用 exec 函数之后,该进程就将执行的程序 ...
- useradd groupadd passwd usermod userdel chfn id
chfn 修改用户信息 id 显示当前用户和用户组的id
- java中字符串太长,怎么自动换到下一行
直接在中间代码出按回车
- Smallest Difference(暴力全排列)
Smallest Difference Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10387 Accepted: 2 ...