zoukankan      html  css  js  c++  java
  • UWP开发入门(三)——{x:Bind}扩展标记

      上周打炉石打得太晚……忘记更新了,本周补上。本篇我们讲一下{x:Bind}扩展标记。{x:Bind}扩展标记也是Windows 10 Uinversal 新增的内容,按官方的说法 {Binding} 的备用选项。虽然 {x:Bind} 缺少 {Binding} 中的一些功能,但它运行时所花费的时间和使用的内存量均比 {Binding} 要少,且支持更好的调试。

    首先我们来看一下{x:Bind}的基本用法:

    <Page
        x:Class="XBindTest.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XBindTest"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <TextBlock Text="{x:Bind HelloWorld}"></TextBlock>
        </Grid>
    </Page>
        public sealed partial class MainPage : Page
        {
            public string HelloWorld { get; set; }
    
            public MainPage()
            {
                this.InitializeComponent();
                this.HelloWorld = "Hello World";
            }
        }

      和原先使用的Binding最大的不同,就是不需要设置DataContext,而是从Page(或者UserControl)来寻找属性进行绑定。值得注意的是,可能是为了强调性能,{x:Bind}的默认绑定ModeOneTime,而不是OneWay。之前Binding写得太多的各位可能会思维定势而忘记修改Mode

      有的同学可能会说,既然以Page作为绑定的默认源,是不是意味着就木有ViewModel啥事了,以后代码就一股脑都写在Page.cs里了?当然不是啦,因为每个Page里写个ViewModel是很常见的事情啊,再通过ViewModel来进一层绑定属性就可以了。

        public sealed partial class HostView : Page
        {
         public HostViewModel ViewModel { get; set; }
    public HostView() { this.InitializeComponent(); this.ViewModel = new HostViewModel(); } }
    <Page x:Class="QuizGame.View.HostView" ... >
        <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
    </Page>

      {x:Bind}还有一个非常神奇的地方,就是Xaml里写了就可以直接在Design视图显示出来。而Binding则是没有办法做到的,这是因为{x:Bind} 编译时就已经生成了一些奇怪的代码(位于对应的Page.g.cs文件,该文件可以在obj文件夹中找到){Binding} 则是在运行时才获取对象进行绑定所以{x:Bind}才能具有更好的性能。

      在g.cs文件中我们可以找到这样的代码:

    private void Update_HelloWorld(global::System.String obj, int phase)
                {
                    if((phase & ((1 << 0) | NOT_PHASED )) != 0)
                    {
                        XamlBindingSetters.Set_Windows_UI_Xaml_Controls_TextBlock_Text(this.obj2, obj, null);
                    }
                }
    public static void Set_Windows_UI_Xaml_Controls_TextBlock_Text(global::Windows.UI.Xaml.Controls.TextBlock obj, global::System.String value, string targetNullValue)
                {
                    if (value == null && targetNullValue != null)
                    {
                        value = targetNullValue;
                    }
                    obj.Text = value ?? global::System.String.Empty;
                }

      在需要的时候,就可以打个断点进行调试了,虽然我觉得然并卵……

      接下来说的非常重要,就是在DataTemplate中如何使用{x:Bind},稍稍有别于在PageXaml里,在DataTemplate中使用{x:Bind}必须要表明绑定的数据类型:

            <ListView ItemsSource="{x:Bind PersonList}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="local:Person">
                        <TextBlock Text="{x:Bind Name}"></TextBlock>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

      还是那句话,{x:Bind}是在编译时处理绑定的,必须明确知道数据类型才能在g.cs里生成一些奇怪的辅助信息。

      看看下面这张截图,因为类型都在g.cs里都生成好了,所以Design视图里才能根据Xaml生成对应的展示数据,这是Binding所做不到的。

      

      上面说了这么多{x:Bind}的优点,你是不是有些心动了呢?但是!终于到了说但是的时间了,{x:Bind}还是存在一些比不过Binding的地方:

    • {x:Bind}不支持Source的用法,比如下面这个常用的功能就实现不了,乖乖滚回Binding的怀抱。Visibility="{Binding Settings.Accessibility,Source={StaticResource Locator}
    • 另外呢,UpdateSourceTrigger也是不支持的。Text="{Binding Email,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
    • 还有呢,如果你想把{x:Bind}写到ResouceDirectory里,更是一件麻烦的事情,你需要给ResouceDirectory创建一个class,然后人肉添加类似InitializeComponent的方法……想想都觉得还是算了,哎呀我不想写了……
    • 如果你之前经常写C# code来创建Binding,那么{x:Bind}又会让你失望了,完全不支持……

      除了以上这些,{x:Bind}还会诱使一种叫做代码洁癖的疾病发生。你想啊,都把DataType写到Xaml里了,这特么眼里还有没有MVVM和王法了,类型都暴露了一点隐私都没有了。底下写Service的同事(请不要误会底下的意思,这不是体位描写)说:哎哟不好意思,我重构代码把类型改了。你一看要改NXaml文件,抄起一把椅子就砸过去了,然后就被派出所带走了……

      所以这里还是需要通过接口来减少依赖,举个例子在MainPage里通过IViewModel,而不是具体的MainViewModel来绑定,在DataTemplate里通过IPerson,而不是Person类型。这部分是面向对象的知识了,就不展开讨论了。

      本篇到此打住,再去开一盘炉石,我就不信萨满打不上传说……

  • 相关阅读:
    mysql 历史版本下载
    mysql 5.7 版本 You must reset your password using ALTER USER statement before executing this statement报错处理
    5.7 zip 版本的安装 以及遇到的坑
    mysql 5.6zip版本的卸载与5.7 zip 版本的安装
    mysql数据库的备份与还原
    本地Navicat连接docker里的mysql
    docker修改数据库密码
    docker 在push镜像到本地registry出现的500 Internal Server Error
    linux 没有界面内容显示不全解决办法
    json与map互相转换
  • 原文地址:https://www.cnblogs.com/manupstairs/p/5024487.html
Copyright © 2011-2022 走看看