更改项目中元素的锌指数控制windows手机
本文关键字:指数 控制 windows 手机 项目 元素 | 更新日期: 2023-09-27 17:58:56
这是一个有很多不同答案的问题,但尚未找到适用于Windows Phone的答案
因此:
我有一个显示UserControls的Items控件
我将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
项目控件内的画布是从以下视图正确绑定位置所必需的:
<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组成。但这仍然会留下锌指数的问题。
如评论中所述。ItemsControl
看不到外面的画布,因此无法使用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);
}
}
现在,您只需将View:SInGame
项上的Canvas.ZIndex
绑定到底层模型属性("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索引,并且每个实例都应该相对于其他实例进行定位。您可以通过修改"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>