x:Bind Convert 轉換器的簡單描述+{x:bind}與binding 的異同

  近期筆者擼的MVVM項目瘋狂使用的數據綁定,而後正好遇到了須要修改綁定源數據的問題了,查詢了不少dalao們的答案以及官方文檔,發現瞭解決數據綁定時轉換數據的好幫手 -- Convert,下面摘記下關於Convert的簡單使用:express

  首先,咱們須要瞭解到咱們什麼時候須要使用Convert ?windows

  • 簡化後臺數據處理的部分
  • 簡化內存使用

  Convert 官網介紹傳送門:Converts Classapp

  使用Convert的時候咱們首先得新建一個對應咱們使用場景(好比:咱們須要把源數據的日期按咱們指定的格式輸出。源數據類型:Data,輸出數據類型:String)的XXXConvert 類,而這個類須要實現IValueConverter的接口以及它包含的兩個抽象方法:Convert與ConvertBack。ide

  上代碼:ui

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的區別,這裏引用一段官方陳述:spa

  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 extensiondebug

  OK,簡單複述下上面那段話的意思:{x:Bind}綁定數據的時候,會在編譯期間生成一段用於檢索綁定數據的目標代碼,而且執行,而Binding是直接在運行時進行對象檢查。雙向綁定

 &nbsp而後就是回到Convert的簡述中,簡單介紹下兩個待實現的抽象方法:Convert和ConvertBack,通常狀況下若是咱們只須要將源數據進行加工直接推送到目標位置的話,Convert便足夠了(通常若是綁定的模式選擇的是:OneWay 單向綁定,只會調用Convert方法)。假若使用場景要求不只得將處理數據推送到目標位置,還得將修改後數據推送回源數據位置,那麼實現上述回調功能的代碼就應該放在ConvertBack方法內。code

補充:關於{x:Bind}以及Binding容易忽略的默認模式,引用官方陳述👇orm

{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,就先介紹到這!

相關文章
相關標籤/搜索