[源码下载]

背水一战 Windows 10 (21) - 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧

作者:webabcd

介绍
背水一战 Windows 10 之 绑定

  • x:Bind 绑定
  • x:Bind 绑定之 x:Phase
  • 使用绑定过程中的一些技巧

示例
1、演示 x:Bind 绑定的相关知识点
Bind/BindDemo.xaml

<Page
x:Class="Windows10.Bind.BindDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Bind"
xmlns:common="using:Windows10.Common"
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"> <!--
关于 x:Bind 的相关说明:
1、Binding 是在运行时(RunTime)绑定;而 x:Bind 是在编译时(BuildTime)绑定(其会在编译时自动生成一些辅助代码,参见对应的 g.cs 代码),所以 x:Bind 的效率要高
2、x:Bind 是强类型绑定,类型必须比配;Binding 在绑定时如果类型不必配,会做自动转换
3、x:Bind 只具有 Binding 的一部分功能,如下: Path, Mode. FallbackValue, TargetNullValue, Converter, ConverterParameter, ConverterLanguage
4、x:Bind 的 Mode 的默认值是 OneTime;Binding 的 Mode 的默认值是 OneWay
5、x:Bind 的数据上下文是其所属的 Page 或 UserControl, 不能为 x:Bind 指定其他的数据上下文
6、x:Bind 在 DataTemplate 中使用时,必须指定 DataTemplate 的 DataType;而 Binding 则不必
7、x:Bind 只能在 xaml 中使用,无法在 CodeBehind 中使用
8、x:Bind 支持事件绑定到方法
9、仔细看看上面的说明,x:Bind 与 Binding 的大部分不同的本质原因是,他们一个是编译时绑定,一个是运行时绑定
--> <!--绑定到属性-->
<TextBlock Name="textBlock" Text="{x:Bind Path=CurrentEmployee.Name, Mode=OneWay}" Margin="5" /> <!--事件绑定到方法,无参数-->
<Button Content="修改 CurrentEmployee 的 MyName" Click="{x:Bind EventBindNoArgs}" Margin="5" /> <!--事件绑定到方法,参数与对应的事件的参数相同-->
<Button Content="修改 CurrentEmployee 的 MyName" Click="{x:Bind EventBindRegularArgs}" Margin="5" /> <!--事件绑定到方法,参数与对应的事件的参数相同,但是其中的事件参数为 object 类型-->
<Button Content="修改 CurrentEmployee 的 MyName" Click="{x:Bind EventBindBaseArgs}" Margin="5" /> <!--事件绑定到方法,也可以绑定到指定对象中的指定方法-->
<Button Content="修改 CurrentEmployee 的 MyName" Click="{x:Bind CurrentEmployee.ChangeName}" Margin="5" /> <!--在 DataTemplate 中使用 x:Bind 的注意事项:必须要指定 DataTemplate 的 DataType-->
<ListView x:Name="listView" ItemsSource="{x:Bind AllEmployees}" Margin="5">
<ListView.ItemTemplate>
<DataTemplate x:DataType="common:Employee">
<TextBlock Text="{x:Bind Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView> <!--可以与索引器绑定-->
<TextBlock Name="textBlock2" Text="{x:Bind Path=AllEmployees[0].Name, Mode=OneWay}" Margin="5" /> <!--可以与 Element 绑定-->
<TextBlock Name="textBlock3" Text="{x:Bind textBlock2.Text, Mode=OneWay}" Margin="5" /> </StackPanel>
</Grid>
</Page>

Bind/BindDemo.xaml.cs

/*
* 演示 x:Bind 绑定的相关知识点
*/ using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows10.Common; namespace Windows10.Bind
{
// x:Bind 的数据上下文就是它所属的 Page 或 UserControl
public sealed partial class BindDemo : Page
{
public BindDemo()
{
this.InitializeComponent();
} // 事件绑定到方法,无参数
private void EventBindNoArgs()
{
CurrentEmployee.Name = "wanglei" + new Random().Next(, ).ToString();
} // 事件绑定到方法,参数与对应的事件的参数相同
private void EventBindRegularArgs(object sender, RoutedEventArgs e)
{
CurrentEmployee.Name = "wanglei" + new Random().Next(, ).ToString();
} // 事件绑定到方法,参数与对应的事件的参数相同,但是其中的事件参数为 object 类型
private void EventBindBaseArgs(object sender, object e)
{
CurrentEmployee.Name = "wanglei" + new Random().Next(, ).ToString();
} public Employee CurrentEmployee { get; set; } = new Employee() { Name = "wanglei", Age = , IsMale = true }; public ObservableCollection<Employee> AllEmployees { get; set; } = TestData.GetEmployees();
}
}

2、演示 x:Bind 绑定之 x:Phase 的相关知识点
Bind/PhaseDemo.xaml

<Page
x:Class="Windows10.Bind.PhaseDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Bind"
xmlns:common="using:Windows10.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources> <!--
关于 x:Phase 的相关说明:
1、x:Phase 可以实现元素的分阶段显示,用于避免绘制大量数据时的卡顿
2、ListView 和 GridView 均继承自 ListViewBase
3、在 windows 8.1 及以后版本中,ListViewBase 是支持 UI 虚拟化的
4、x:Phase 只适用于 ListViewBase 中的 DataTemplate 里的元素
5、x:Phase 属于 x:Bind 的一项功能,所以其必须在指定了 x:Bind 的元素中使用才有效
6、x:Phase 的作用是解决如下问题:当 ListViewBase 滚动时,如果一屏的 item 多,且每个 item 中的 element 也多,那么绘制时会占用大量的资源以至卡顿
7、在 windows 8.1 及以后版本中,我们可以通过 ContainerContentChanging 事件手动控制列表项的呈现,而 x:Phase 的原理其实就是在编译时自动生成这种手动控制代码(参见对应的 g.cs 代码)
关于如何手动控制列表项的呈现,请参见 /Controls/CollectionControl/ListViewBaseDemo/ListViewBaseDemo4.xaml
--> <DataTemplate x:Key="PhasedFileTemplate" x:DataType="common:Employee">
<StackPanel Width="200" Margin="10" Background="Blue">
<TextBlock Margin="5" Text="{x:Bind Name}" Foreground="Red" x:Phase="9" />
<TextBlock Margin="5" Text="{x:Bind Name}" Foreground="White" />
<TextBlock Margin="5" Text="{x:Bind Name}" Foreground="Green" x:Phase="1" />
<TextBlock Margin="5" Text="{x:Bind Name}" Foreground="Orange" x:Phase="2" />
<TextBlock Margin="5" Text="{x:Bind Name}" Foreground="Orange" x:Phase="2" />
</StackPanel>
</DataTemplate> </Page.Resources> <Grid Background="Transparent"> <!--
ShowsScrollingPlaceholders="false" - 不显示占位符
ContainerContentChanging - 项容器的内容发生变化时触发的事件(在本例中,其用于人为减慢每阶段的显示速度,以便演示) 关于 ShowsScrollingPlaceholders, ContainerContentChanging 的详细说明请参见 ListView, GridView 部分
-->
<GridView Name="gridView" Margin="10 0 10 10" ShowsScrollingPlaceholders="false" ContainerContentChanging="gridView_ContainerContentChanging"
ItemsSource="{x:Bind AllEmployees}" ItemTemplate="{StaticResource PhasedFileTemplate}" /> </Grid>
</Page>

Bind/PhaseDemo.xaml.cs

/*
* 演示 x:Bind 绑定之 x:Phase 的相关知识点
*/ using System.Collections.ObjectModel;
using System.Threading;
using Windows.UI.Xaml.Controls;
using Windows10.Common; namespace Windows10.Bind
{
public sealed partial class PhaseDemo : Page
{
public PhaseDemo()
{
this.InitializeComponent();
} // 用于人为减慢每阶段的显示速度,以便演示
private void gridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
AutoResetEvent h = new AutoResetEvent(false);
h.WaitOne(); uint phase = args.Phase;
if (phase < )
args.RegisterUpdateCallback(gridView_ContainerContentChanging);
} // 数据源
public ObservableCollection<Employee> AllEmployees { get; set; } = TestData.GetEmployees();
}
}

3、演示使用绑定过程中的一些技巧
Bind/Tips.xaml

<Page
x:Class="Windows10.Bind.Tips"
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" xmlns:common="using:Windows10.Common"
Background="Red"> <Page.Resources>
<common:NullableBooleanToBooleanConverter x:Key="NullableBooleanToBooleanConverter" />
</Page.Resources> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions> <!--绑定附加属性,注意要用括号括起来-->
<TextBox Name="textBox1" Margin="5" Text="{Binding Path=(Grid.Row), RelativeSource={RelativeSource Self}}" Grid.Row="0" /> <!--使用绑定时,可以在 Binding 或 x:Bind 后直接加 Path 的值,而不用写“Path=”-->
<TextBox Name="textBox2" Margin="5" Text="{Binding (Grid.Row), RelativeSource={RelativeSource Self}}" Grid.Row="1" /> <!--在 CodeBehind 端绑定附加属性-->
<TextBox Name="textBox3" Margin="5" Grid.Row="2" />
</Grid> <!--绑定自定义附加属性(在 CodeBehind 端绑定自定义附加属性暂时没有成功)-->
<TextBox Name="textBox4" Margin="5" local:MyAttachedProperty.SubTitle="custom attached property" Text="{Binding (local:MyAttachedProperty.SubTitle), RelativeSource={RelativeSource Self}}" /> <!--绑定指定对象的指定属性-->
<TextBox Name="textBox5" Margin="5" Text="{Binding Margin.Top, RelativeSource={RelativeSource Self}}" /> <!--
Background 是 Brush 类型
SolidColorBrush 继承自 Brush
Background.(SolidColorBrush.Color) 的意思就是将 Background 的 Brush 类型转换为 SolidColorBrush 类型并取其 Color 属性
-->
<TextBox Name="textBox6" Margin="5" Text="{x:Bind Background.(SolidColorBrush.Color)}" /> <!--
x:Bind 没有 ElementName,那如何与其他元素绑定呢,像下面这样即可
-->
<TextBox Name="textBox7" Margin="5" Text="{x:Bind textBox6.Text}" /> <!--
x:Bind 如何绑定到其他元素的附加属性呢,像下面这样即可
-->
<TextBox Name="textBox8" Margin="5" Text="{x:Bind textBox2.(Grid.Row)}" /> <!--
x:Bind 如何绑定到其他元素的自定义附加属性呢,像下面这样即可
-->
<TextBox Name="textBox9" Margin="5" Text="{x:Bind textBox4.(local:MyAttachedProperty.SubTitle)}" /> <!--
在本例中 CurrentEmployee 是 object 类型,要将他转换为 Employee 类型,然后再使用其属性,写法如下
-->
<TextBox Name="textBox10" Margin="5" Text="{x:Bind CurrentEmployee.(common:Employee.Name)}" /> <!--
Binding 也可以这么写(x:Bind 不支持这么写)
-->
<TextBox Name="textBox11" Margin="5">
<TextBox.Text>
<Binding Path="Text" ElementName="textBox6" />
</TextBox.Text>
</TextBox> <!--
下面的示例用于演示如何绑定到 DataContext 对象的某个属性
-->
<TextBox Name="textBox12" DataContext="{x:Bind CurrentEmployee}" Text="{Binding Name}" Margin="5" /> <!--
下面的示例用于演示如何直接绑定到 DataContext 对象(而不是绑定 DataContext 对象的某个属性)
-->
<TextBox Name="textBox13" DataContext="{x:Bind MyName}" Text="{Binding}" Margin="5" /> <!--
Binding 绑定时,如果数据类型不一致,会尝试自动转换,比如此例:bool? 会被自动自动转换为 bool
-->
<TextBox Name="textBox14" Text="我是 textBox14" IsReadOnly="{Binding IsChecked, ElementName=chk1}" Margin="5" />
<CheckBox Name="chk1" Content="textBox14 IsReadOnly" IsChecked="True" Margin="5 0 0 0" /> <!--
x:Bind 是编译时的强类型绑定,如果数据类型不一致,不会自动转换,比如此例:要通过 Converter 把 bool? 转换为 bool
-->
<TextBox Name="textBox15" Text="我是 textBox15" IsReadOnly="{x:Bind chk2.IsChecked, Mode=TwoWay, Converter={StaticResource NullableBooleanToBooleanConverter}}" Margin="5" />
<CheckBox Name="chk2" Content="textBox15 IsReadOnly" IsChecked="True" Margin="5 0 0 0" /> <!--
再看看绑定此种路径时的写法,要理解
-->
<Rectangle Name="rectangle1" Height="20" Fill="Orange" Margin="5" />
<TextBox Name="textBox16" Margin="5 0 0 0" Text="{x:Bind rectangle1.(Shape.Fill).(SolidColorBrush.Color)}" /> <!--
再来个更长的看看,要理解
-->
<Rectangle Name="rectangle2" Height="20" Width="100" HorizontalAlignment="Left" Fill="Orange" Margin="5">
<!--
注:这里必须先要声明出 ScaleTransform,这样才能与之绑定(否则运行时会报错)
-->
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<TextBox Name="textBox17" Margin="5 0 0 0" Text="{x:Bind rectangle2.(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX), Mode=TwoWay}" /> </StackPanel>
</Grid>
</Page>

Bind/Tips.xaml.cs

/*
* 用于演示使用绑定过程中的一些技巧
*
* 在这里插一句:
* 在 xaml 使用的 {Binding}, {x:Bind}, {StaticResource} 之类的这种带大括号的语法被称为标记扩展(Markup Extension),在 uwp 中无法开发自定义标记扩展(但是在 wpf 中是可以的)
*/ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows10.Common; namespace Windows10.Bind
{
public sealed partial class Tips : Page
{
public Tips()
{
this.InitializeComponent(); this.Loaded += Tips_Loaded;
} private void Tips_Loaded(object sender, RoutedEventArgs e)
{
BindingAttachedProperty();
} // 在 CodeBehind 端绑定附加属性
private void BindingAttachedProperty()
{
Binding binding = new Binding()
{
Path = new PropertyPath("(Grid.Row)"), // 注意要有括号,另外在 CodeBehind 端绑定自定义附加属性暂时没有成功
Source = textBox3
};
BindingOperations.SetBinding(textBox3, TextBox.TextProperty, binding);
} // 通过 x:Bind 绑定时,要做转换
public object CurrentEmployee { get; set; } = new Employee() { Name = "wanglei", Age = , IsMale = true }; public string MyName { get; set; } = "webabcd";
} /// <summary>
/// 用于附加属性的演示
/// </summary>
public class MyAttachedProperty
{
// 获取附加属性
public static string GetSubTitle(DependencyObject obj)
{
return (string)obj.GetValue(SubTitleProperty);
} // 设置附加属性
public static void SetSubTitle(DependencyObject obj, string value)
{
obj.SetValue(SubTitleProperty, value);
} // 注册一个附加属性
public static readonly DependencyProperty SubTitleProperty =
DependencyProperty.RegisterAttached(
"SubTitle", // 附加属性的名称
typeof(string), // 附加属性的数据类型
typeof(MyAttachedProperty), // 附加属性所属的类
new PropertyMetadata("", PropertyMetadataCallback)); // 指定附加属性的默认值,以及值发生改变时所调用的方法 private static void PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
object newValue = args.NewValue; // 发生改变之后的值
object oldValue = args.OldValue; // 发生改变之前的值
}
}
}

OK
[源码下载]

背水一战 Windows 10 (21) - 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧的更多相关文章

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

    [源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd ...

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

    [源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd ...

  3. 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合

    [源码下载] 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合 作 ...

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

    [源码下载] 背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换 作者:webabcd 介 ...

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

    [源码下载] 背水一战 Windows 10 (19) - 绑定: TemplateBinding 绑定, 与 RelativeSource 绑定, 与 StaticResource 绑定 作者:we ...

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

    [源码下载] 背水一战 Windows 10 (18) - 绑定: 与 Element 绑定, 与 Indexer 绑定, TargetNullValue, FallbackValue 作者:weba ...

  7. 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command)

    [源码下载] 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command) 作者:webabcd 介绍背水一战 Windows 10 之 MVV ...

  8. 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox

    [源码下载] 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox 作者:webabcd 介绍背水一战 Windows 10 之 控件(选择类) Sel ...

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

    [源码下载] 背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null 作者:webabcd 介绍背水一战 Windows 10 之 XAML ...

随机推荐

  1. 如何让用户只能访问特定的数据库(MSSQL)

    背景 客户的SQL Server实例上有多个厂商的数据库,每个数据库由各自的进行厂进行商维护, 为了限定不同厂商的维护人员只能访问自己的数据库,现需要给各个厂商限定权限,让他们登录SQL Server ...

  2. SQL Server对比两字段的相似度(函数算法)

    相似度函数 概述    比较两个字段的相似度    最近有人问到关于两个字段求相似度的函数,所以就写了一篇关于相似度的函数,分别是“简单的模糊匹配”,“顺序匹配”,“一对一位置匹配”.在平时的这种函数 ...

  3. js动态生成选项之考试系统(一)

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...

  4. 有一个团队协同工具,叫Worktile

    项目管理,本是一个老生常谈的话题,曾几何时大碗云集在这个市场,其中不乏出现像微软.SAP.IBM.用友这样的名字.复杂而又冗繁的流程控制,让人们划分成两类人,一类是会使用这些工具和系统的人,另一类是不 ...

  5. Oracle没有WM_CONCAT函数的解决办法

    WM_CONCAT是oracle的非公开函数,并不鼓励使用,新版本oracle并没有带此函数,需要手工加上. 1.下载三个文件:owmctab.plb  . owmaggrs.plb . owmagg ...

  6. HTML5 音频播放器-Javascript代码(短小精悍)

    直接上干货咯! //HTML5 音频播放器 lzpong 2015/01/19 var wavPlayer = function () { if(window.parent.wavPlayer) re ...

  7. ES6新特性之 promise

    新的ES6中引入了promise的概念,目的是让回调更为优雅.层层嵌套的回调会让javascript失去美感和可读性,同时javascript也推荐采用链式的方式去书写函数调用.于是Promise就应 ...

  8. C#设计模式系列:开闭原则(Open Close Principle)

    1.开闭原则简介 开闭原则对扩展开放,对修改关闭,开闭原则是面向对象设计中可复用设计的基石. 2.开闭原则的实现 实现开闭原则的关键就在于抽象,把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规 ...

  9. 简单生成svg文件

    this.fileSaveSync = function (file, data) { var fs = require('fs-extra'); fs.writeFileSync(file, dat ...

  10. Android之TabActivity的使用

    TabActivity实现多页显示效果 由于手机屏幕有限,所以我们要尽量充分利用屏幕资源.在我们的应用程序中通常有多个Activity,而且会经常切换显示,这样我们就可以用TabActivity来显示 ...