背水一战 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
[源码下载]

时间: 2025-01-14 08:50:56

背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合的相关文章

背水一战 Windows 10 (19) - 绑定: TemplateBinding 绑定, 与 RelativeSource 绑定, 与 StaticResource 绑定

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 绑定 TemplateBinding 绑定 与 RelativeSource 绑定 与 StaticResource 绑定 示例1.演示 TemplateBinding 的用法Bind/TemplateBindingDemo.xaml <Page x:Class="Windows10.Bind.TemplateBindingDemo" xmlns="http://schemas.microsof

背水一战 Windows 10 (18) - 绑定: 与 Element 绑定, 与 Indexer 绑定, TargetNullValue, FallbackValue

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 绑定 与 Element 绑定 与 Indexer 绑定 TargetNullValue - 当绑定数据为 null 时显示的值 FallbackValue - 当绑定失败时显示的值 示例1.演示如何与 Element 绑定Bind/BindingElement.xaml <Page x:Class="Windows10.Bind.BindingElement" xmlns="http://sc

背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 绑定 DataContextChanged - FrameworkElement 的 DataContext 发生变化时触发的事件 UpdateSourceTrigger - 数据更新的触发方式 对绑定的数据做自定义转换 示例1.演示 DataContextChanged 的用法Bind/DataContextChanged.xaml <Page x:Class="Windows10.Bind.DataContex

背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

原文:背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 [源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 MVVM(Model-View-ViewModel) 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 示例1.ModelMVVM/Model/Product.cs /* * Model 层的实

背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 MVVM(Model-View-ViewModel) 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 示例1.ModelMVVM/Model/Product.cs /* * Model 层的实体类,如果需要通知则需要实现 INotifyPropertyChanged 接口 */ using System.ComponentModel; namespace Wind

背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null

原文:背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null [源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 XAML x:DeferLoadStrategy="Lazy" - 用于指定一个 UIElement 为一个延迟加载元素 x:Null - null 示例1.x:DeferLoadStrategy 通过 FindName 加载Xaml/DeferLoadStrategy/Demo1.xaml

背水一战 Windows 10 (58) - 控件(集合类): ListViewBase - ListView, GridView

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类 - ListViewBase) ListView GridView 示例1.ListView 的示例Controls/CollectionControl/ListViewBaseDemo/ListViewDemo.xaml <Page x:Class="Windows10.Controls.CollectionControl.ListViewDemo" xmlns="http://

背水一战 Windows 10 (55) - 控件(集合类): ItemsControl - SemanticZoom, ISemanticZoomInformation

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类 - ItemsControl) SemanticZoom ISemanticZoomInformation 示例1.SemanticZoom 的示例Controls/CollectionControl/SemanticZoomDemo/SemanticZoomDemo.xaml <Page x:Class="Windows10.Controls.CollectionControl.SemanticZo

背水一战 Windows 10 (8) - 控件 UI: StateTrigger

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件 UI VisualState 之 StateTrigger 示例1.自定义 StateTriggerControls/UI/VisualState/MyDeviceFamilyStateTrigger.cs /* * 用于演示自定义 StateTrigger * * * StateTriggerBase - 自定义 StateTrigger 需要继承此基类 * SetActive(Boolean IsActive)