Binding vs. x:Bind,默认使用 StaticResource 以及它们在 DataContext 中的区别 [英] Binding vs. x:Bind, using StaticResource as a default and their differences in DataContext

查看:22
本文介绍了Binding vs. x:Bind,默认使用 StaticResource 以及它们在 DataContext 中的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了半天的时间尝试使用 UserControl 使 ListViewItemTemplate 可通过DependencyProperty 表示 UserControl.关于 Windows 10 UAP 平台上可用的两种不同的 Binding 方法(Bindingx:Bind),我遇到了一些奇怪的不一致.

I've spent the better of half a day trying to make the ItemTemplate of a ListView with a UserControl configurable through means of a DependencyProperty on said UserControl. I've come across some weird inconsistencies regarding the two different Binding methods available on Windows 10 UAP platform ( Binding and x:Bind).

UserControl 看起来像这样,是自定义日历组件的一部分.

The UserControl looks like this and is part of a custom calendar component.

<UserControl
   x:Class="FlowDesigner.UserControls.CalendarDayView"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="using:FlowDesigner.UserControls"
   xmlns:vw="using:FlowDesigner.ViewModels"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:uc="using:FlowDesigner.UserControls"
   mc:Ignorable="d"
   d:DesignHeight="300"
   d:DesignWidth="400"
   x:Name="DateControl">
   <UserControl.Resources>
      <DataTemplate x:Key="DefaultDataTemplate" x:DataType="vw:Event" >
          <uc:EventListTemplate IsToday="{Binding Date, Converter={StaticResource IsTodayConverter}}" 
                              Date="{Binding Date, Mode=OneWay}"
                              Summary="{Binding Path=Summary, Mode=OneWay}" />
      </DataTemplate>
   </UserControl.Resources>
   <RelativePanel Background="White" BorderBrush="Black" BorderThickness="1" DataContext="{Binding ElementName=DateControl}">
       <TextBlock x:Name="DayText" TextAlignment="Center" VerticalAlignment="Center" />
       <TextBlock x:Name="MonthText" TextAlignment="Center" VerticalAlignment="Center" RelativePanel.RightOf="DayText" />
       <ListView x:Name="EventList" ItemsSource="{x:Bind Events, Mode=OneWay}" 
              ItemTemplate="{Binding Path=EventItemTemplate, Mode=OneWay, FallbackValue={StaticResource DefaultDataTemplate}, TargetNullValue={StaticResource DefaultDataTemplate}}" 
              RelativePanel.Below="DayText" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">

        </ListView>
    </RelativePanel>
</UserControl>

EventItemTemplateUserControlDependencyProperty.

public DataTemplate EventItemTemplate
{
    get { return (DataTemplate)GetValue(EventItemTemplateProperty); }
    set { SetValue(EventItemTemplateProperty, value); }
}

public static readonly DependencyProperty EventItemTemplateProperty =
        DependencyProperty.Register("EventItemTemplate", typeof(DataTemplate), typeof(CalendarDayView), new PropertyMetadata(null));

在其中一个根页面上更改以一种或另一种方式设置 ListView 的样式,就像这样.

Which is altered on one of the root pages to style the ListView in one way or the other, like so.

<Style TargetType="uc:CalendarDayView">
    <Setter Property="EventItemTemplate">
        <Setter.Value>
            <DataTemplate x:DataType="vw:Event" >
                <TextBlock Text="{Binding Summary, Mode=OneWay}" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

这实际上是一个工作版本,但我不得不对其进行大量修改.我第一次尝试使用 x:BindBinding 并且没有 RelativePanel 上的 DataContext 作为UserControl 现在是.x:Bind 在根页面中将值设置为 EventItemTemplate 时会起作用,但无法使用指定的默认 DataTemplate当根页面未指定任何内容时,由 StaticResource 执行.另一方面,Binding 将始终使用默认的 DataTemplate,即使在根页面设置了其他值到 EventItemTemplate 时也是如此.

This is actually a working version, but I had to tinker around with it quite a bit. The first attempts were made by me with both x:Bind and Binding and without the DataContext on the RelativePanel as the UserControl is now. x:Bind would be functional when setting a value to EventItemTemplate in the root page, but it would not be able to use the default DataTemplate specified by the StaticResource when the root page did not specify anything. Binding on the other hand would use the default DataTemplate at all times, even when the the root page had a set an other value to EventItemTemplate.

通过将 RelativePanel 上的 DataContext 设置为 UserControl Binding 开始像想要的那样工作.x:Bind 仍然显示相同的行为.

By setting the DataContext on the RelativePanel to the UserControl Binding started worked like wanted it too. x:Bind still shows the same behavior.

现在我了解到 Binding 默认情况下不会绑定到 UserControlDataContext,但我仍然不完全确定为什么x:Bind 不起作用.这是预期的行为还是我的整个计划有问题,我想出的只是一个幸运的技巧?

Now I understand that Binding does not by default bind to the UserControl's DataContext, but I'm still not entirely sure why x:Bind doesn't work. Is this intended behavior or is there something wrong with my entire scheme here and is what I came up with just a lucky hack?

推荐答案

来自 {x:Bind} 标记扩展:

{x:Bind} 标记扩展(Windows 10 的新功能)是 {Binding} 的替代品.{x:Bind} 缺少 {Binding} 的一些功能,但它比 {Binding} 运行时间和内存更少,并且支持更好的调试.

The {x:Bind} markup extension—new for Windows 10—is an alternative to {Binding}. {x:Bind} lacks some of the features of {Binding}, but it runs in less time and less memory than {Binding} and supports better debugging.

在 XAML 加载时,{x:Bind} 被转换为您可以认为的绑定对象,并且此对象从数据源的属性中获取值.可以选择将绑定对象配置为观察数据源属性值的变化并根据这些变化刷新自身.它还可以选择配置为将其自身值的更改推送回源属性.{x:Bind} 和 {Binding} 创建的绑定对象在功能上基本相同.但是 {x:Bind} 执行特殊用途的代码,它在编译时生成,而 {Binding} 使用通用的运行时对象检查.因此,{x:Bind} 绑定(通常称为已编译绑定)具有出色的性能,提供绑定表达式的编译时验证,并通过使您能够在作为部分生成的代码文件中设置断点来支持调试您的页面的类.这些文件可以在您的 obj 文件夹中找到,其名称类似于 (for C#) .g.cs.

At XAML load time, {x:Bind} is converted into what you can think of as a binding object, and this object gets a value from a property on a data source. The binding object can optionally be configured to observe changes in the value of the data source property and refresh itself based on those changes. It can also optionally be configured to push changes in its own value back to the source property. 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#) .g.cs.

这篇关于Binding vs. x:Bind,默认使用 StaticResource 以及它们在 DataContext 中的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆