Binding 如何在WinRT中使用ItemContainerStyle进行绑定?

Binding 如何在WinRT中使用ItemContainerStyle进行绑定?,binding,windows-runtime,itemscontrol,winrt-xaml,itemcontainerstyle,Binding,Windows Runtime,Itemscontrol,Winrt Xaml,Itemcontainerstyle,我正在尝试将集合绑定到ItemsControl,将画布作为items面板,并将每个项的Canvas.Left和Top绑定到item对象的属性。基本上,我正在尝试重新创建我在中描述的二维数据绑定,但这次是在WinRT而不是WPF中 由于ItemsControl将ItemTemplate内容包装在另一个UI元素(WinRT中的ContentPresenter)中,并且正是那些包装器/容器元素直接放置在items面板中,因此必须在这些容器上设置左侧和顶部;不能只在DataTemplate中设置它们。在

我正在尝试将集合绑定到ItemsControl,将画布作为items面板,并将每个项的Canvas.Left和Top绑定到item对象的属性。基本上,我正在尝试重新创建我在中描述的二维数据绑定,但这次是在WinRT而不是WPF中

由于ItemsControl将ItemTemplate内容包装在另一个UI元素(WinRT中的ContentPresenter)中,并且正是那些包装器/容器元素直接放置在items面板中,因此必须在这些容器上设置左侧和顶部;不能只在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>

我已经验证了ContentPresenter确实具有正确的DataContext(即集合项,而不是集合本身或其他时髦的东西),因此您认为这些绑定可以正常工作。但他们甚至没有得到评估。如果我将坏绑定放在其他任何地方,并运行调试生成,我会在调试器的输出窗口中看到绑定错误;但如果我在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>

我在
绑定
上尝试了一些更奇特的选项,特别是
相对资源
。当我使用
RelativeSourceTemplatedParent
时,什么也不做的行为没有改变。但是,当我使用
relativesourceself
时,我确实得到了一个绑定错误,表示type
Setter
上不存在该属性!这是把
Self
看得太字面了一点

我还玩过
模板绑定
,但我从来没有真正弄清楚它应该用于什么,我得到的只是一些无法理解的COM错误(欢迎使用WinRT,这是一个巨大的技术倒退)


我如何(a)使绑定正常工作(在
绑定
上是否有其他选项可用于强制它正常工作?)或(b)否则,基于集合项目属性的数据绑定,允许my
ItemsContainer
中的项目在
画布上任意定位?

setter不支持绑定。我认为Silverlight只有在版本5中才有它们。对于解决方法,您可以查看我的旧文章。基本上,您可以定义一个附加的依赖属性来为您设置绑定。

在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>

备选方案:在演示之前创建“项”的过程中,还可以通过代码附加绑定

ItemsControl.PrepareContainerForItemOverride

ListViewBase.ContainerContentChangeing

这是一个相当聪明的黑客,它确实在WinRT中工作——尽管语法不同;您必须执行
newbinding{Path=newpropertypath(newValue)}
而不是
newbinding(newValue)
。我还想将附加属性重命名为
Path
BindingPath
结尾,这样XAML就更容易理解了。但总而言之,这是一个好的、可行的解决方案。谢谢在安装了最新版本win8.9200(8月15日之后)之后,它似乎也不起作用!我想我会放弃图形应用程序中的绑定:(因为在我看来这是一大步。)back@Filip斯卡昆:+1代表画布(左)为什么会这样?我想这是因为它是一个附加属性?虽然这是一篇非常古老的文章,但你的方法似乎对我有部分作用,唯一的问题是Windows Phone 8.1中的按钮已经从画布上消失了。你知道怎么了吗?