繁体   English   中英

在WPF中使用BringToFront

[英]BringToFront in WPF

我需要在WPF中引入自定义控件。

伪代码

OnMouseDown()
{
    if (this.parent != null)
        this.parent.BringToFront(this);
}

我知道,我知道有一个ZIndex ,但仍然不明白如何将简单的WinForm BringToFront替换为parent.SetZIndex(this, ?MaxZIndex(parent)? + 1)

也许有更好的方法在像WPF这样的酷事中做到这一点?!..

这是一个扩展函数,它将方法BringToFront功能添加到Panel中包含的所有FrameworkElements。

  public static class FrameworkElementExt
  {
    public static void BringToFront(this FrameworkElement element)
    {
      if (element == null) return;

      Panel parent = element.Parent as Panel;
      if (parent == null) return;

      var maxZ = parent.Children.OfType<UIElement>()
        .Where(x => x != element)
        .Select(x => Panel.GetZIndex(x))
        .Max();
      Panel.SetZIndex(element, maxZ + 1);
    }
  }

你真正希望的最好的方法是使一个元素相对于同一父面板中的任何兄弟元素(例如StackPanel,Grid,Canvas等)最顶层。 面板中项目的z顺序由Panel.ZIndex附加属性控制。

例如:

<Grid>
    <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
    <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
</Grid>

在此示例中,蓝色矩形将显示在顶部。 这个博客文章对此进行了解释。

Panel.ZIndex的更改也没有立即反映在UI中。 有一个私有方法允许刷新z-index,但由于它是私有的,因此使用它不是一个好主意。 要解决它,您必须删除并重新添加子项。

但是,您不能将任何给定元素置于最顶层。 例如:

<Grid>
    <Grid>
        <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
        <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
    <Grid>
        <Rectangle Fill="Green" Width="50" Height="50" Panel.ZIndex="0" />
        <Rectangle Fill="Yellow" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
</Grid>

在这种情况下,将显示黄色矩形。 因为第二个内部网格显示在第一个内部网格的顶部以及它的所有内容。 您必须像这样改变它以将蓝色矩形置于顶部:

<Grid>
    <Grid Panel.ZIndex="1">
        <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
        <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
    <Grid Panel.ZIndex="0">
        <Rectangle Fill="Green" Width="50" Height="50" Panel.ZIndex="0" />
        <Rectangle Fill="Yellow" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
</Grid>

在处理ItemsControl时, 这个问题是相关的。 大多数其他控件只有一个孩子,但你仍然需要将它们带到前面,以使其中任何一个孩子最顶级。

最后, Adorners是将事物置于一切之上的好方法,但它们不是主要视觉树的一部分。 所以我不确定这会对你的情况有效。

我只测试了一个Window控件,但......

this.Topmost = true;
this.Topmost = false;

第一条线将它带到前面,第二条线阻止它永久地在前面。

我尝试了canvas.zindex并且它没有用,但是为我做的解决方案是在Popup控件中使用Border:

<Popup IsOpen="True/False">
    <Border Background="White">
        <DatePicker/>
    </Border>
</Popup>

我发现更好的解决方案 得到它:

foreach (var item in Grid1.Children)
{
    if ((item as UIElement).Uid == "StackPan1")
    {
        UIElement tmp = item as UIElement;
        Grid1.Children.Remove(item as UIElement);
        Grid1.Children.Add(tmp);
        break;
    }
}

这只是一个例子,不是普遍的方法。 但您可以在动态添加控件的应用程序中使用它。 此代码只是添加了一个元素,您希望将其置于UIElementCollection的顶部。 如果所有元素都具有相同的ZIndex,则它可以正常工作。

暂无
暂无

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

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