我有一个ItemsControl,它使用Canvas和ItemsPanel。 itemsTemplate托管自定义控件。当点击控件时我希望它“向前移动”。我知道我可以在控件中使用ZIndex这样做:
private void MyControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if(((FrameworkElement)sender).TemplatedParent==null) return;
ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;
int currentValue = Panel.GetZIndex(presenter);
Console.WriteLine(currentValue);
Panel.SetZIndex(presenter, 99);
}
这可以正常工作并设置ZIndex。但是当我点击ItemsControl中的不同控件时,它将获得完全相同的ZIndex,因此它不会“移动到另一个控件的前面”。
基本上我只想要与windows展示相同的行为。
我已经尝试在PreviewMouseUp事件中将ZIndex设置为0,这确保了单击的控件始终位于顶部,但由于所有其他控件具有相同的ZIndex为0,因此将采用基于的默认顺序在列表中有位置。
一个例子:
假设我有3个控件,ZIndex都是0.(所以他们使用默认的列表位置。)
如果我点击控制3,那么2然后1.我希望它在ZOrder的顶部有3,然后是2然后1.但是因为我在MouseUp上将ZIndex设置为零它会有默认顺序为1,2,3。
是否有一种简单的方法来处理这个问题,或者我是否需要跟踪顺序并递增递减任意值,例如99我自己?
答案 0 :(得分:5)
我会沿着这些方向做点什么:
在鼠标按下时,将所选控件上的Z-index设置为非常高的数字。 将一个静态int Zindex初始化为0。 鼠标向上设置Z-index等于Zindex ++
private static int Zindex = 0;
private void MyControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if(((FrameworkElement)sender).TemplatedParent==null) return;
ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;
int currentValue = Panel.GetZIndex(presenter);
Console.WriteLine(currentValue);
Panel.SetZIndex(presenter, Int32.MaxValue);
}
private void MyControl_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if(((FrameworkElement)sender).TemplatedParent==null) return;
ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;
int currentValue = Panel.GetZIndex(presenter);
Console.WriteLine(currentValue);
Panel.SetZIndex(presenter, Zindex++);
}
如果您的程序应该运行很长时间,您可能会对Zorder有一些上限,所以如果达到,您可以找到正在使用的最小z-index并从所有控件和Zindex计数器上的z-index中减去它
答案 1 :(得分:0)
在我的情况下,我在选定的控件上设置Zindex然后枚举所有其他控件并在需要时增加它们的ZIndex,因为在某些时候你可以遇到选定的控件而所有其他控件都不需要更改。
丑陋,但到目前为止我没有更好的解决方案
答案 2 :(得分:0)
最简单的方法是只枚举一次所有项目,只有在我们通过一个项目才能将z-index减少时才会减少z-index。这样可以确保最底部项目的z-index始终具有0的z-index,最后一项z-index为(count-1),每个项目的差值均为1的整数。
如果你每次增加(或减少)每一个,将一个设置为最高的前置,z-index可能永远不会从0开始,最终结果可能太符合你的喜好。
因此,无论何时将项目放在前面,您都可以枚举这样的项目:
//If you don't already have the z-index of the item to bring to front (or target item)...
var i = YourItem.Z;
foreach (var j in YourListOfItems)
{
//Current item occurs after target item in sequence
if (j.Z > i)
{
j.Z--;
}
else if (j.Z < i)
{
//Curent item occurs before target item in sequence; no need to change the z-index
}
else j.Z = YourListOfItems.Count - 1;
}
这假设您将对象列表绑定到ItemsControl
,并且对象具有Z
属性,该属性绑定到Panel.ZIndex
中的ItemContainerStyle
属性。