问题描述
我花了半天的时间尝试使用 UserControl
使 ListView
的 ItemTemplate
可通过DependencyProperty
表示 UserControl
.关于 Windows 10 UAP 平台上可用的两种不同的 Binding
方法(Binding
和 x: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>
EventItemTemplate
是 UserControl
的 DependencyProperty
.
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:Bind
和 Binding
并且没有 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
默认情况下不会绑定到 UserControl
的 DataContext
,但我仍然不完全确定为什么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 中的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!