背水一戰 Windows 10 之 綁定: 通過 Binding 綁定對象, 通過 x:Bind 綁定對象, 通過 Binding 綁定集合, 通過 x:Bind 綁定集合 ...
背水一戰 Windows 10 (22) - 綁定: 通過 Binding 綁定對象, 通過 x:Bind 綁定對象, 通過 Binding 綁定集合, 通過 x:Bind 綁定集合
作者:webabcd
介紹
背水一戰 Windows 10 之 綁定
- 通過 Binding 綁定對象
- 通過 x:Bind 綁定對象
- 通過 Binding 綁定集合
- 通過 x:Bind 綁定集合
示例
1、演示如何通過 Binding 綁定對象
Bind/BindingModel.xaml
<Page x:Class="Windows10.Bind.BindingModel" 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 Name="root" Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <TextBox Text="{Binding Name, Mode=TwoWay}" Margin="5" /> <TextBox Text="{Binding Age, Mode=TwoWay}" Margin="5" /> <ToggleSwitch IsOn="{Binding IsMale, Mode=TwoWay}" OffContent="女" OnContent="男" Header="性別" Margin="5" /> </StackPanel> </Grid> </Page>
Bind/BindingModel.xaml.cs
/* * 演示如何通過 Binding 綁定對象 */ using System; using System.ComponentModel; using Windows.System.Threading; using Windows.UI.Core; using Windows.UI.Xaml.Controls; using Windows10.Common; namespace Windows10.Bind { public sealed partial class BindingModel : Page { private Employee _employee; public BindingModel() { this.InitializeComponent(); this.Loaded += BindingModel_Loaded; } void BindingModel_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { // 創建一個需要綁定的實體對象(註:Employee 實現了 INotifyPropertyChanged 介面) _employee = new Employee(); _employee.Name = "webabcd"; _employee.Age = 33; _employee.IsMale = true; // Employee 對象的屬性的值發生變化時觸發的事件(源自 INotifyPropertyChanged 介面) _employee.PropertyChanged += _employee_PropertyChanged; // 指定數據上下文(綁定的數據源) root.DataContext = _employee; // 每 5 秒更新一次數據 ThreadPoolTimer.CreatePeriodicTimer ( (timer) => { var ignored = Dispatcher.RunAsync ( CoreDispatcherPriority.Normal, () => { Random random = new Random(); _employee.Age = random.Next(10, 100); _employee.IsMale = random.Next() % 2 == 0 ? true : false; } ); }, TimeSpan.FromMilliseconds(5000) ); } // 每次屬性的值發生變化時,顯示變化後的結果 void _employee_PropertyChanged(object sender, PropertyChangedEventArgs e) { lblMsg.Text = "屬性:“" + e.PropertyName + "”的值發生了變化"; lblMsg.Text += Environment.NewLine; lblMsg.Text += string.Format("當前的值為:Name-{0}, Age-{1}, IsMale-{2}", _employee.Name, _employee.Age, _employee.IsMale); } } }
2、演示如何通過 x:Bind 綁定對象
Bind/BindModel.xaml
<Page x:Class="Windows10.Bind.BindModel" 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" /> <TextBox Text="{x:Bind CurrentEmployee.Name, Mode=TwoWay}" Margin="5" /> <TextBox Text="{x:Bind CurrentEmployee.Age, Mode=TwoWay}" Margin="5" /> <ToggleSwitch IsOn="{x:Bind CurrentEmployee.IsMale, Mode=TwoWay}" OffContent="女" OnContent="男" Header="性別" Margin="5" /> </StackPanel> </Grid> </Page>
Bind/BindModel.xaml.cs
/* * 演示如何通過 x:Bind 綁定對象 */ using System; using System.ComponentModel; using Windows.System.Threading; using Windows.UI.Core; using Windows.UI.Xaml.Controls; using Windows10.Common; namespace Windows10.Bind { public sealed partial class BindModel : Page { // Employee 實現了 INotifyPropertyChanged 介面 public Employee CurrentEmployee { get; set; } = new Employee() { Name = "wanglei", Age = 36, IsMale = true }; public BindModel() { this.InitializeComponent(); this.Loaded += BindingModel_Loaded; } void BindingModel_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { // 每 5 秒更新一次數據 ThreadPoolTimer.CreatePeriodicTimer ( (timer) => { var ignored = Dispatcher.RunAsync ( CoreDispatcherPriority.High, () => { Random random = new Random(); CurrentEmployee.Age = random.Next(10, 100); CurrentEmployee.IsMale = random.Next() % 2 == 0 ? true : false; } ); }, TimeSpan.FromMilliseconds(5000) ); // Employee 對象的屬性的值發生變化時觸發的事件(源自 INotifyPropertyChanged 介面) CurrentEmployee.PropertyChanged += CurrentEmployee_PropertyChanged; } private void CurrentEmployee_PropertyChanged(object sender, PropertyChangedEventArgs e) { lblMsg.Text = "屬性:“" + e.PropertyName + "”的值發生了變化"; lblMsg.Text += Environment.NewLine; lblMsg.Text += string.Format("當前的值為:Name-{0}, Age-{1}, IsMale-{2}", CurrentEmployee.Name, CurrentEmployee.Age, CurrentEmployee.IsMale); } } }
3、示如何通過 Binding 綁定集合
Bind/BindingCollection.xaml
<Page x:Class="Windows10.Bind.BindingCollection" 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 Orientation="Vertical" VerticalAlignment="Top" Margin="10 0 10 10"> <Button Name="btnDelete" Content="刪除第 1 條數據" Click="btnDelete_Click" Margin="5" /> <Button Name="btnUpdate" Content="更新前 2 條數據" Click="btnUpdate_Click" Margin="5" /> <ListView x:Name="listView" Margin="5"> <ListView.ItemTemplate> <DataTemplate> <Border Background="Blue" Width="200" CornerRadius="3" HorizontalAlignment="Left"> <TextBlock Text="{Binding Name}" /> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackPanel> </Grid> </Page>
Bind/BindingCollection.xaml.cs
/* * 演示如何通過 Binding 綁定集合 */ using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows10.Common; namespace Windows10.Bind { public sealed partial class BindingCollection : Page { // ObservableCollection<T> 實現了 INotifyCollectionChanged 介面 // ObservableCollection<T> 雖然也實現了 INotifyPropertyChanged 介面,但是其對應的 event 是 protected 的,所以不可用(需要的話就自己再封一層) private ObservableCollection<Employee> _employees; public BindingCollection() { this.InitializeComponent(); this.Loaded += BindingCollection_Loaded; } void BindingCollection_Loaded(object sender, RoutedEventArgs e) { _employees = new ObservableCollection<Employee>(TestData.GetEmployees()); _employees.CollectionChanged += _employees_CollectionChanged; // 指定 ListView 的數據源 listView.ItemsSource = _employees; } void _employees_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { /* * e.Action - 引發此事件的操作類型(NotifyCollectionChangedAction 枚舉) * Add, Remove, Replace, Move, Reset * e.OldItems - Remove, Replace, Move 操作時影響的數據列表 * e.OldStartingIndex - Remove, Replace, Move 操作發生處的索引 * e.NewItems - 更改中所涉及的新的數據列表 * e.NewStartingIndex - 更改中所涉及的新的數據列表的發生處的索引 */ } private void btnDelete_Click(object sender, RoutedEventArgs e) { // 此處的通知來自 INotifyCollectionChanged 介面 _employees.RemoveAt(0); } private void btnUpdate_Click(object sender, RoutedEventArgs e) { Random random = new Random(); // 此處的通知來自實現了 INotifyPropertyChanged 介面的 Employee _employees.First().Name = random.Next(1000, 10000).ToString(); // 此處的通知來自 INotifyCollectionChanged 介面 _employees[1] = new Employee() { Name = random.Next(1000, 10000).ToString() }; } } }
4、演示如何通過 x:Bind 綁定集合
Bind/BindCollection.xaml
<Page x:Class="Windows10.Bind.BindCollection" 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" xmlns:common="using:Windows10.Common" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="10 0 10 10"> <Button Name="btnDelete" Content="刪除第 1 條數據" Click="btnDelete_Click" Margin="5" /> <Button Name="btnUpdate" Content="更新前 2 條數據" Click="btnUpdate_Click" Margin="5" /> <ListView x:Name="listView" ItemsSource="{x:Bind Employees}" Margin="5"> <ListView.ItemTemplate> <DataTemplate x:DataType="common:Employee"> <Border Background="Blue" Width="200" CornerRadius="3" HorizontalAlignment="Left"> <TextBlock Text="{x:Bind Name, Mode=OneWay}" /> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackPanel> </Grid> </Page>
Bind/BindCollection.xaml.cs
/* * 演示如何通過 x:Bind 綁定集合 */ using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows10.Common; namespace Windows10.Bind { public sealed partial class BindCollection : Page { // 數據源 // ObservableCollection<T> 實現了 INotifyCollectionChanged 介面 // ObservableCollection<T> 雖然也實現了 INotifyPropertyChanged 介面,但是其對應的 event 是 protected 的,所以不可用(需要的話就自己再封一層) public ObservableCollection<Employee> Employees { get; set; } = new ObservableCollection<Employee>(TestData.GetEmployees()); public BindCollection() { this.InitializeComponent(); this.Loaded += BindCollection_Loaded; } void BindCollection_Loaded(object sender, RoutedEventArgs e) { Employees.CollectionChanged += _employees_CollectionChanged; } void _employees_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { /* * e.Action - 引發此事件的操作類型(NotifyCollectionChangedAction 枚舉) * Add, Remove, Replace, Move, Reset * e.OldItems - Remove, Replace, Move 操作時影響的數據列表 * e.OldStartingIndex - Remove, Replace, Move 操作發生處的索引 * e.NewItems - 更改中所涉及的新的數據列表 * e.NewStartingIndex - 更改中所涉及的新的數據列表的發生處的索引 */ } private void btnDelete_Click(object sender, RoutedEventArgs e) { // 此處的通知來自 INotifyCollectionChanged 介面 Employees.RemoveAt(0); } private void btnUpdate_Click(object sender, RoutedEventArgs e) { Random random = new Random(); // 此處的通知來自實現了 INotifyPropertyChanged 介面的 Employee Employees.First().Name = random.Next(1000, 10000).ToString(); // 此處的通知來自 INotifyCollectionChanged 介面 Employees[1] = new Employee() { Name = random.Next(1000, 10000).ToString() }; } } }
OK
[源碼下載]