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类型。这部分是面向对象的知识了,就不展开讨论了。

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

  • 相关阅读:
    jquery怎么实现跨域的访问呢?与别人提供的接口连接
    服务器返回数组,data[0]得到的总是不对?如何处理?
    ajax 如何实现页面跳转
    问答精华-IntelliJ IDEA快捷键大全
    setinterval在jQuery里面是怎么使用的。
    background 、backgroundcolor、background-color 我怎么有点分不清了??
    视频最后用使用了function(i,ot)一笔带过,但我看不懂i和ot这2个参数的具体值是怎么获取得到的,能不能说一下参数传递过程?
    3张大图片自动播放
    图片自动加载
    用jQuery之后,之前javascript的一些方法就不能用了吗
  • 原文地址:https://www.cnblogs.com/manupstairs/p/5024487.html
Copyright © 2011-2022 走看看