c# - 使用 StaticResource 作为默认绑定(bind)与 x :Bind, 的绑定(bind)及其在 DataContext 中的差异

标签 c# xaml binding windows-10

我花了大半天的时间尝试使 ListViewItemTemplate 具有 UserControl 可配置,方法是DependencyProperty 在所述 UserControl 上。关于 Windows 10 UAP 平台上可用的两种不同的 Binding 方法(Bindingx:Bind),我遇到了一些奇怪的不一致。

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

<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 的样式,就像这样。

<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

通过将 RelativePanel 上的 DataContext 设置为 UserControl Binding 也开始正常工作。 x:Bind 仍然显示相同的行为。

现在我明白 Binding 默认情况下不会绑定(bind)到 UserControlDataContext,但我仍然不完全确定为什么x:Bind 不起作用。这是有意为之的行为,还是我的整个方案有问题,我想出的只是一个幸运的 hack?

最佳答案

来自 {x:Bind} markup extension :

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.

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.

关于c# - 使用 StaticResource 作为默认绑定(bind)与 x :Bind, 的绑定(bind)及其在 DataContext 中的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32582303/

相关文章:

c# - DDD 和 IOC 容器

c# - 使用右键单击 Windows 窗体按钮

c# - LINQ 作为方法参数

c# - 条件文本绑定(bind) XAML

wpf - DataTemplate 中的样式仅应用于 ItemsControl 中的最后一项?

c# - bool 到 System.Windows.Visibility(动态创建 DataGridColumnHeaders 时的绑定(bind)问题)

c# - 为什么要在 UpdateAsync 上设置 CreationTime 和 CreatorUserId?

.net - TabControl 填充不适用于经典主题

javascript - 为什么按钮中的 event.target 返回空值?

c# - 死掉的简单 MVVM 应用程序的列表框保持为空 - 我错过了什么?