代码之家  ›  专栏  ›  技术社区  ›  Kelly

WPF到前面

  •  3
  • Kelly  · 技术社区  · 16 年前

    我有一个itemscontrol,它使用画布作为itemspanel。itemstmlate承载一个自定义控件。单击控件时,我希望它“移到前面”。我知道我可以用我控制的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。我希望它的顶部有3个,然后是2,然后是1。但是因为我在mouseup上将zindex设置为零,所以它的默认顺序是1,2,3。

    是否有一个简单的方法来处理这个问题,或者我需要跟踪顺序和增量递减,比如我自己的99个任意值?

    3 回复  |  直到 9 年前
        1
  •  5
  •   Falle1234    16 年前

    我会沿着这条线做一些事情:

    鼠标按下时,将所选控件上的Z索引设置为非常高的数字。 将静态int zindex初始化为0。 鼠标启动后,将Z索引设置为z index++

    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-索引,并从所有控件的z-索引和z index计数器中减去它。

        2
  •  0
  •   TTRider    16 年前

    在我的例子中,我将zindex设置为选中的控件,然后枚举所有其他控件,并在需要时增加它们的zindex,因为在某个时刻,您可能会遇到选中的控件,而不需要更改所有其他控件。

    丑陋,但到目前为止我没有更好的解决办法

        3
  •  0
  •   James M    9 年前

    最简单的方法是只枚举一次所有项,如果我们将Z索引传递到前面,则只减少Z索引。这样可以确保最下面的项的z-索引始终具有0的z-索引,最后一项的z-索引为(count-1),每一项都有1的整数。

    如果你每次增加(或减少)一个,设置一个带到前面最高,Z指数可能永远不会开始于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 .