我正在尝试将一个集合绑定到ItemsControl,将Canvas作为items面板,并将每个项目的Canvas.Left和Top绑定到项目对象上的属性。基本上我正在尝试重新创建我在this post on my blog中描述的二维数据绑定,但这次是在WinRT而不是WPF中。
由于ItemsControl将您的ItemTemplate内容包装在另一个UI元素(在WinRT的情况下为ContentPresenter)中,并且那些直接放置在items面板内的包装器/容器元素,因此必须在那些上设置Left和Top容器;你不能只在DataTemplate中设置它们。在WPF中,使用ItemContainerStyle中的绑定很容易做到这一点,例如:
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=X}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
但是当我在WinRT / XAML项目中尝试同样的事情时,我什么都没得到。 甚至没有绑定错误。如果我对一个值进行硬编码,它就会起作用;但是如果我使用绑定,则该属性将保持其默认值(零),并且“输出”窗口中不会显示绑定错误。
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<!-- This works, so ItemContainerStyle does work in WinRT: -->
<Setter Property="Canvas.Left" Value="200"/>
<!-- But this silently fails, leaves Top as 0, and does not show
any binding errors in the debugger's Output window: -->
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
我已经验证了ContentPresenters确实有正确的DataContext(即集合项,而不是集合本身或其他时髦的东西),所以你认为这些绑定可以正常工作。但他们似乎甚至没有得到评估。如果我在其他任何地方放置了一个坏的绑定,并运行调试版本,我会在调试器的Output窗口中看到绑定错误;但如果我在ItemContainerStyle中引用了一个无意义的属性,则不会显示绑定错误。
这是一个更完整的例子,(据我所知)应该可以在WPF中正常工作,但是它会在WinRT中保留原点:
<ItemsControl ItemsSource="{Binding Tiles}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding DataContext.Left}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="80" Height="80" Fill="Gray"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我在Binding
上尝试了一些更具异国情调的选项 - 特别是RelativeSource
。当我使用RelativeSource TemplatedParent
时,无操作行为没有改变。但是,当我使用RelativeSource Self
时,我确实收到了绑定错误,说该属性在Setter
类型上不存在!那里的Self
字面意义太强了。
我也和TemplateBinding
一起玩过,但我从来没有真正理解过应该使用的东西,我得到的只是一些难以理解的COM错误(欢迎使用WinRT,这是一个巨大的技术倒退)。 p>
我怎样才能(a)使绑定正常工作(Binding
上还有其他选项可以用来强制它正常工作吗?),或者(b)否则允许我ItemsContainer
中的项目1}}基于对集合项的属性的数据绑定在Canvas
上任意定位?
答案 0 :(得分:15)
Setters不支持绑定。我认为Silverlight只会在版本5中获得它们。对于变通方法,您可以查看我的旧文章here。基本上,您定义了一个为您设置绑定的附加依赖项属性。
答案 1 :(得分:8)
在silverlight和winrt / metro / 8.1中应用RenderTransform似乎很适合我:
<ItemsControl ItemsSource="{Binding TreeMapItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Brush}" ToolTipService.ToolTip="{Binding Label}">
<Rectangle.RenderTransform>
<TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
答案 2 :(得分:0)
替代方案:以下是在创建&#34;项目&#34;期间通过代码附加绑定的其他机会。在介绍之前。
ItemsControl.PrepareContainerForItemOverride http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.itemscontrol.preparecontainerforitemoverride.aspx
ListViewBase.ContainerContentChanging http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.listviewbase.containercontentchanging.aspx