繁体   English   中英

更改itemscontrol windows phone中元素的zindex

[英]changing zindex of elements in itemscontrol windows phone

这是一个有许多不同答案的问题,但还没有找到适用于Windows Phone的问题。
所以这里:

我有一个显示UserControls的Items Control。
我将ObservableCollection绑定到此ItemsControl,如下所示:

<Canvas Name="CanvasGrid" Grid.Column="1" Background="Transparent" Canvas.ZIndex="5">
    <ItemsControl ItemsSource="{Binding InGame}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas>
                    <View:SInGame/>
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Canvas>

当在Itemscontrol中添加一个元素时,该元素被赋予一个独立于我给予该元素的zindex,以及显示的usercontrol。 我想要做的是有按钮,我可以在z方向上下移动选定的元素。

查看SInGame

要从以下视图中正确绑定位置,需要使用itemscontrol中的Canvas:

<UserControl x:Class="MVVMTestApp.View.SInGame"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
xmlns:View="clr-namespace:MVVMTestApp.View"
mc:Ignorable="d"
Canvas.Left="{Binding pos.x}" Canvas.Top="{Binding pos.y}">

<Path >
    <.....
    ....../>
</Path>
</UserControl>

然后可以认为视图应该由具有绑定位置的Canvas组成。 但这仍然会留下zindex的问题。

正如评论中所述。 ItemsControl无法看到外部画布,因此无法使用zindex来实现。 那么如何设置zindex呢? 或者使用ItemsControl元素是不可能的?

ItemsControl获取每个项目,将其包装在容器(ContentPresenter)中,并将其添加到项目面板(默认情况下为StackPanel)。 因此,示意性地,您将最终获得此树:

<!-- the items panel (StackPanel by default) -->
<StackPanel>
    <!-- the first item wrapper -->
    <ContentPresenter>
        <!-- your item template -->
        <Canvas>
            <View:SInGame/>
        </Canvas>
    </ContentPresenter>

    <!-- more items ... -->
</StackPanel>

你会想要做两件事:

  • 设置ItemsControl.ItemsPanel为项目提供共享的Canvas容器。
  • 确保您想要的ZIndex应用于ContentPresenter包装器。

这两点将为您提供这样的架构,这应该允许您从前到后定位项目:

<!-- the items panel (change to a Canvas) -->
<Canvas>
    <!-- the first item wrapper (need to set Canvas.ZIndex to position) -->
    <ContentPresenter Canvas.ZIndex="1">
        <!-- your item template -->
        <Canvas>
            <View:SInGame/>
        </Canvas>
    </ContentPresenter>

    <!-- more items ... -->
</Canvas>

为了达到第二点,我相信你需要子类ItemsControl ,并重写PrepareContainerForItemOverride 例如,以下内容修改每个项容器,将其ZIndex属性绑定到项本身的ZIndex:

public class CanvasItemsControl : ItemsControl
{
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        var contentPresenter = (ContentPresenter)element;
        var binding = new Binding("ZIndex") { Source = contentPresenter.Content };
        contentPresenter.SetBinding(Canvas.ZIndexProperty, binding);
    }
}

现在,你可以绑定Canvas.ZIndexView:SInGame项目底层模型属性(“pos.x”?)。

把它们放在一起:

<local:CanvasItemsControl ItemsSource="{Binding InGame}">
    <local:CanvasItemsControl.ItemTemplate>
        <DataTemplate>
            <Canvas Canvas.ZIndex="{Binding pos.x}" >
                <View:SInGame />
            </Canvas>
        </DataTemplate>
    </local:CanvasItemsControl.ItemTemplate>
    <local:CanvasItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    <local:CanvasItemsControl.ItemsPanel>
</local:CanvasItemsControl>

这样,每个SInGame实例都获得一个Z-index,每个实例都应该相对于其他实例定位。 您可以通过修改“InGame”中每个视图模型项的“MyZIndex”属性来前后重新定位项目。


编辑

上面有一个更简单的替代方案,可能对你有用。 这种方法会给你一个扁平的树,如下所示:

<!-- the items panel (change to a Canvas) -->
<Canvas>
    <!-- the items -->
    <View:SInGame/>
    <View:SInGame/>
</Canvas>

为此,重写GetContainerForItemOverride()以返回SInGame对象:

public class CanvasItemsControl : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new SInGame();
    }

    // Any setup of the `SInGame` items should be done here
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        var container = (SInGame)element;
    }
}

这允许您在没有任何ItemTemplate的情况下定义ItemsControl:

<local:CanvasItemsControl ItemsSource="{Binding InGame}">
    <local:CanvasItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    <local:CanvasItemsControl.ItemsPanel>
</local:CanvasItemsControl>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM