作者:webabcd
介紹
背水一戰(zhàn) Windows 10 之 綁定
示例
1、演示 DataContextChanged 的用法
Bind/DataContextChanged.xaml
<Page x:Class="Windows10.Bind.DataContextChanged" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Bind" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button x:Name="btnChange" Content="改變 listBox 的數(shù)據(jù)上下文" Click="btnChange_Click" Margin="5" /> <ListBox x:Name="listBox" ItemsSource="{Binding}" DataContextChanged="listBox_DataContextChanged" Background="Orange" Margin="5" /> </StackPanel> </Grid></Page>
Bind/DataContextChanged.xaml.cs
/* * DataContextChanged - FrameworkElement 的 DataContext 發(fā)生變化時(shí)觸發(fā)的事件 */using System;using System.Collections.Generic;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;namespace Windows10.Bind{ public sealed partial class DataContextChanged : Page { public DataContextChanged() { this.InitializeComponent(); this.Loaded += DataContextChanged_Loaded; } private void DataContextChanged_Loaded(object sender, RoutedEventArgs e) { // 指定數(shù)據(jù)上下文 listBox.DataContext = new List<string> { "a", "b", "c" }; } private void btnChange_Click(object sender, RoutedEventArgs e) { // 修改數(shù)據(jù)上下文 listBox.DataContext = new List<string> { "a", "b", new Random().Next(0, 1000).ToString().PadLeft(3, '0') }; } private void listBox_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) { /* * FrameworkElement.DataContextChanged - 數(shù)據(jù)上下文發(fā)生改變后觸發(fā)的事件 */ // 數(shù)據(jù)上下文發(fā)生改變后 lblMsg.Text = "數(shù)據(jù)上下文發(fā)生改變:" + DateTime.Now.ToString("hh:mm:ss"); } }}
2、演示 UpdateSourceTrigger 的用法
Bind/UpdateSourceTrigger.xaml
<Page x:Class="Windows10.Bind.UpdateSourceTrigger" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Bind" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Foreground="Orange" Margin="5" /> <!-- UpdateSourceTrigger - 數(shù)據(jù)更新的觸發(fā)方式 Default - 失去焦點(diǎn)后觸發(fā) PropertyChanged - 屬性值發(fā)生改變后觸發(fā) Explicit - 需要通過 BindingExpression.UpdateSource() 顯示觸發(fā) --> <TextBox Text="{Binding Text, Mode=TwoWay, ElementName=lblMsg, UpdateSourceTrigger=Default}" Margin="5" /> <TextBox Text="{Binding Text, Mode=TwoWay, ElementName=lblMsg, UpdateSourceTrigger=PropertyChanged}" Margin="5" /> <TextBox Name="txtExplicit" Text="{Binding Text, Mode=TwoWay, ElementName=lblMsg, UpdateSourceTrigger=Explicit}" Margin="5" /> <Button Name="btnBinding" Content="顯示觸發(fā)更新" Click="btnBinding_Click" Margin="5" /> </StackPanel> </Grid></Page>
Bind/UpdateSourceTrigger.xaml.cs
/* * UpdateSourceTrigger - 數(shù)據(jù)更新的觸發(fā)方式 * Default - 失去焦點(diǎn)后觸發(fā) * PropertyChanged - 屬性值發(fā)生改變后觸發(fā) * Explicit - 需要通過 BindingExpression.UpdateSource() 顯示觸發(fā) * * * BindingExpression - 綁定信息,可以通過 FrameworkElement 的 GetBindingExpression() 方法獲取指定屬性的綁定信息 * DataItem - 獲取綁定的源對(duì)象 * ParentBinding - 獲取綁定的 Binding 對(duì)象(Binding 對(duì)象里包括 ElementName, Path, Mode 等綁定信息) * UpdateSource() - 將當(dāng)前值發(fā)送到 TwoWay 綁定的源對(duì)象的綁定的屬性中 */using System;using Windows.UI.Popups;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Data;namespace Windows10.Bind{ public sealed partial class UpdateSourceTrigger : Page { public UpdateSourceTrigger() { this.InitializeComponent(); } private async void btnBinding_Click(object sender, RoutedEventArgs e) { // 顯示觸發(fā) txtExplicit 的數(shù)據(jù)更新 BindingExpression be = txtExplicit.GetBindingExpression(TextBox.TextProperty); be.UpdateSource(); // 獲取綁定的相關(guān)信息 Binding binding = be.ParentBinding; TextBlock textBlock = be.DataItem as TextBlock; MessageDialog messageDialog = new MessageDialog($"BindingExpression.DataItem:{textBlock.Name}, Binding.Mode:{binding.Mode}"); await messageDialog.ShowAsync(); } }}
3、演示如何對(duì)綁定的數(shù)據(jù)做自定義轉(zhuǎn)換
Bind/BindingConverter.xaml
<Page x:Class="Windows10.Bind.BindingConverter" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Bind" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <!-- 配置 IValueConverter 資源 --> <StackPanel.Resources> <local:IntegerLetterConverter x:Key="IntegerLetterConverter"/> <local:FormatConverter x:Key="FormatConverter"/> <x:String x:Key="FormatString">格式化字符串 {0}</x:String> </StackPanel.Resources> <Slider Name="slider1" Minimum="97" Maximum="122" Value="1" Width="300" Background="White" HorizontalAlignment="Left" Margin="5" /> <!-- 演示如何使用 Binding 的 Converter, ConverterParameter, ConverterLanguage 注:ConverterParameter 和 ConverterLanguage 不支持綁定,只能配置為一個(gè)靜態(tài)的值(但是在 C# 端可以實(shí)現(xiàn)一些在 xaml 中無法實(shí)現(xiàn)的特性,詳見后面的例子) --> <TextBox Name="textBox1" Width="300" HorizontalAlignment="Left" Margin="5" Text="{Binding ElementName=slider1, Path=Value, Mode=TwoWay, Converter={StaticResource IntegerLetterConverter}, ConverterParameter=param, ConverterLanguage=zh}" /> <Slider Name="slider2" Minimum="97" Maximum="122" Value="1" Width="300" Background="White" HorizontalAlignment="Left" Margin="5" /> <!-- 在 C# 端使用 Binding 的 Converter, ConverterParameter, ConverterLanguage --> <TextBox Name="textBox2" Width="300" HorizontalAlignment="Left" Margin="5" /> <TextBlock Name="lblMsg" Margin="5" TextWrapping="Wrap" /> <!-- 演示如何在 ConverterParameter 中通過 {0} 格式化字符串 --> <TextBlock Name="textBlock1" Text="我是“textBlock1”" Margin="5" /> <TextBlock Name="textBlock2" Margin="5" Text="{Binding ElementName=textBlock1, Path=Text, Converter={StaticResource FormatConverter}, ConverterParameter={StaticResource FormatString}}" /> </StackPanel> </Grid></Page>
Bind/BindingConverter.xaml.cs
/* * 演示如何對(duì)綁定的數(shù)據(jù)做自定義轉(zhuǎn)換 */using System;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Data;namespace Windows10.Bind{ public sealed partial class BindingConverter : Page { public BindingConverter() { this.InitializeComponent(); this.Loaded += BindingConverter_Loaded; } private void BindingConverter_Loaded(object sender, RoutedEventArgs e) { // 實(shí)例化 Binding 對(duì)象 Binding binding = new Binding() { ElementName = nameof(slider2), Path = new PropertyPath(nameof(Slider.Value)), Mode = BindingMode.TwoWay, // 默認(rèn)是 OneWay 的 Converter = new IntegerLetterConverter(), ConverterParameter = lblMsg, // 將 ConverterParameter 設(shè)置為一個(gè)指定的控件,這個(gè)在 xaml 中實(shí)現(xiàn)不了,但是可以在 C# 端實(shí)現(xiàn) ConverterLanguage = "zh" }; // 將目標(biāo)對(duì)象的目標(biāo)屬性與指定的 Binding 對(duì)象關(guān)聯(lián) BindingOperations.SetBinding(textBox2, TextBox.TextProperty, binding); } } // 自定義一個(gè)實(shí)現(xiàn)了 IValueConverter 接口的類,用于對(duì)綁定的數(shù)據(jù)做自定義轉(zhuǎn)換 public sealed class IntegerLetterConverter : IValueConverter { /// <summary> /// 正向轉(zhuǎn)換器。將值從數(shù)據(jù)源傳給綁定目標(biāo)時(shí),數(shù)據(jù)綁定引擎會(huì)調(diào)用此方法 /// </summary> /// <param name="value">轉(zhuǎn)換之前的值</param> /// <param name="targetType">轉(zhuǎn)換之后的數(shù)據(jù)類型</param> /// <param name="parameter">轉(zhuǎn)換器所使用的參數(shù)(它是通過 Binding 的 ConverterParameter 傳遞過來的)</param> /// <param name="language">轉(zhuǎn)換器所使用的區(qū)域信息(它是通過 Binding 的 ConverterLanguage 傳遞過來的)</param> /// <returns>轉(zhuǎn)換后的值</returns> public object Convert(object value, Type targetType, object parameter, string language) { if (parameter != null && parameter.GetType() == typeof(TextBlock)) { ((TextBlock)parameter).Text = $"value: {value}, targetType: {targetType}, parameter: {parameter}, language: {language}"; } int v = (int)(double)value; return (char)v; } /// <summary> /// 反向轉(zhuǎn)換器。將值從綁定目標(biāo)傳給數(shù)據(jù)源時(shí),數(shù)據(jù)綁定引擎會(huì)調(diào)用此方法 /// </summary> /// <param name="value">轉(zhuǎn)換之前的值</param> /// <param name="targetType">轉(zhuǎn)換之后的數(shù)據(jù)類型</param> /// <param name="parameter">轉(zhuǎn)換器所使用的參數(shù)(它是通過 Binding 的 ConverterParameter 傳遞過來的)</param> /// <param name="language">轉(zhuǎn)換器所使用的區(qū)域信息(它是通過 Binding 的 ConverterLanguage 傳遞過來的)</param> /// <returns>轉(zhuǎn)換后的值</returns> public object ConvertBack(object value, Type targetType, object parameter, string language) { if (parameter != null && parameter.GetType() == typeof(TextBlock)) { ((TextBlock)parameter).Text = $"value: {value}, targetType: {targetType}, parameter: {parameter}, language: {language}"; } int v = ((string)value).ToCharArray()[0]; return v; } } // 自定義一個(gè)實(shí)現(xiàn)了 IValueConverter 接口的類,用于格式化字符串 public sealed class FormatConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { string format = (string)parameter; return string.Format(format, value); } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }}
聯(lián)系客服