x:Bind Convert 转换器的简单描述+{x:bind}与binding 的异同

  近期笔者撸的MVVM项目疯狂使用的数据绑定,然后正好遇到了需要修改绑定源数据的问题了,查询了很多dalao们的答案以及官方文档,发现了解决数据绑定时转换数据的好帮手 -- Convert,下面摘记下关于Convert的简单使用:

  首先,我们需要了解到我们何时需要使用Convert ?

  • 简化后台数据处理的部分
  • 简化内存使用

  Convert 官网介绍传送门:Converts Class

  使用Convert的时候我们首先得新建一个对应我们使用场景(比如:我们需要把源数据的日期按我们指定的格式输出。源数据类型:Data,输出数据类型:String)的XXXConvert 类,而这个类需要实现IValueConverter的接口以及它包含的两个抽象方法:Convert与ConvertBack。

  上代码:

namespace App1
{
    class TestConvert:IValueConverter
    {
        // 当源数据传递过来,在这个方法体内进行修改后然后推到目标位置
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            Debug.WriteLine("execute Convert method !");
            int a = int.Parse(value.ToString());
            int b = a * a;
            return b.ToString();
        }
        // 只有当使用双向绑定的时候,需要将自身的变化推回(push)给源才会调用
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            Debug.WriteLine("execute ConvertBack method !");
            return value;
        }
    }
}
<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <!-- 引入自定义转换器 -->
    <Page.Resources>
        <local:TestConvert x:Key="TestConvert"/>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="400"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="test123.Text" Value="1"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="800"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="test123.Text" Value="2"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="1000"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="test123.Text" Value="3"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.RowDefinitions>
            <RowDefinition Height="15*"/>
            <RowDefinition Height="2*"/>
        </Grid.RowDefinitions>
        <Pivot SelectedIndex="0" Grid.Row="0">
            <PivotItem Header="Test Header 1">
                <TextBlock x:Name="test123" Text="Pivot Item 1"/>
            </PivotItem>
            <PivotItem Header="Test Header 2">
                <TextBlock Text="{x:Bind test123.Text,Converter={StaticResource TestConvert},Mode=OneWay}"/>
            </PivotItem>
        </Pivot>
    </Grid>
</Page>

  为了方便理解,先谈下{x:Bind}以及Binding的区别,这里引用一段官方陈述:

  The binding objects created by** {x:Bind}** and {Binding} are largely functionally equivalent. But **{x:Bind}**executes special-purpose code, which it generates at compile-time, and {Binding} uses general-purpose runtime object inspection. Consequently, **{x:Bind} **bindings (often referred-to as compiled bindings) have great performance, provide compile-time validation of your binding expressions, and support debugging by enabling you to set breakpoints in the code files that are generated as the partial class for your page. These files can be found in your obj folder, with names like (for C#) <view name>.g.cs 摘自:{x:bind} markup extension

  OK,简单复述下上面那段话的意思:{x:Bind}绑定数据的时候,会在编译期间生成一段用于检索绑定数据的目标代码,并且执行,而Binding是直接在运行时进行对象检查。

 &nbsp然后就是回到Convert的简述中,简单介绍下两个待实现的抽象方法:Convert和ConvertBack,一般情况下如果我们只需要将源数据进行加工直接推送到目标位置的话,Convert便足够了(一般如果绑定的模式选择的是:OneWay 单向绑定,只会调用Convert方法)。倘若使用场景要求不仅得将处理数据推送到目标位置,还得将修改后数据推送回源数据位置,那么实现上述回调功能的代码就应该放在ConvertBack方法内。

补充:关于{x:Bind}以及Binding容易忽略的默认模式,引用官方陈述?

{x:Bind} has a default mode of OneTime, unlike {Binding}, which has a default mode of OneWay. This was chosen for performance reasons, as using OneWay causes more code to be generated to hookup and handle change detection. You can explicitly specify a mode to use OneWay or TwoWay binding. You can also use x:DefaultBindMode to change the default mode for {x:Bind} for a specific segment of the markup tree. The specified mode applies to any {x:Bind} expressions on that element and its children, that do not explicitly specify a mode as part of the binding

补充:关于{x:Bind}的简单使用示例->

Text="{x:Bind MyModel.Order.CalculateShipping(MyModel.Order.Weight, MyModel.Order.ShipAddr.Zip, 'Contoso'), Mode=OneTime}"

|      Path to function         |    Path argument   |       Path argument       | Const arg |  Bind Props

补充:双向绑定回调:

Two way function bindings In a two-way binding scenario, a second function must be specified for the reverse direction of the binding. This is done using the BindBack binding property, for example Text="{x:Bind a.MyFunc(b), BindBack=a.MyFunc2}". The function should take one argument which is the value that needs to be pushed back to the model.

PS:

  • {x:Bind}不会自动转换绑定数据的类型,也就是传进来的数据必须是控件属性要求的类型
  • Binding 会自动转换类型

OK,就先介绍到这!

转载于:https://my.oschina.net/u/3744313/blog/1790433

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值