.net WPF 中的前移
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5666754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BringToFront in WPF
提问by serhio
I need to bring to front a custom control in WPF.
我需要在 WPF 中引入一个自定义控件。
pseudoCode
伪代码
OnMouseDown()
{
if (this.parent != null)
this.parent.BringToFront(this);
}
I know, I knowthat there are a ZIndex, but still don't understand how to replace the simple WinForm BringToFrontto parent.SetZIndex(this, ?MaxZIndex(parent)? + 1)?
我知道,我知道有一个ZIndex,但仍然不明白如何将简单的 WinForm 替换BringToFront为parent.SetZIndex(this, ?MaxZIndex(parent)? + 1)?
Perhaps there is a better way of doing it in the such a cool thing like WPF?!..
也许在像 WPF 这样很酷的东西中有更好的方法来做到这一点?!..
回答by Erik Rydgren
Here is an extension function that adds the method BringToFront functionality to all FrameworkElements that are contained in a Panel.
这是一个扩展函数,它将方法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);
}
}
回答by CodeNaked
Really the best that you can hope for is to make an element top-most with respect to any sibling elements in the same parent Panel (such as StackPanel, Grid, Canvas, etc). The z-order of the items in the panels is controlled by the Panel.ZIndexattached property.
您真正希望的最好的方法是使元素相对于同一父面板中的任何兄弟元素(例如 StackPanel、Grid、Canvas 等)位于最顶层。面板中项目的 z 顺序由Panel.ZIndex附加属性控制。
For example:
例如:
<Grid>
<Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
<Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
</Grid>
In this example, the blue rectangle would appear on top. This is explained a bit more in this blog post.
在此示例中,蓝色矩形将出现在顶部。这在这篇博文中有更多解释。
There is also an issue with changes to the Panel.ZIndex not being immediately reflected in the UI. There is a private method that allows refreshes the z-index, but since it's private it's not a good idea to use it. To work-around it, you'd have to remove and re-add the children.
还有一个问题是对 Panel.ZIndex 的更改没有立即反映在 UI 中。有一种允许刷新 z-index 的私有方法,但由于它是私有的,因此使用它不是一个好主意。要解决它,您必须删除并重新添加子项。
You cannot however make any given element top-most. For example:
但是,您不能将任何给定元素置于最顶层。例如:
<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>
In this case, the yellow rectangle will be displayed. Because the second inner grid is shown on top of the first inner grid and all it's content. You'd have to alter it like so to bring the blue rectangle to the top:
在这种情况下,将显示黄色矩形。因为第二个内部网格显示在第一个内部网格及其所有内容的顶部。您必须像这样更改它才能将蓝色矩形带到顶部:
<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>
When dealing with an ItemsControl, this questionis relevant. Most other controls have a single child, but you'd still need to bring them forward to make any of it's children top-most.
在处理 ItemsControl 时,这个问题是相关的。大多数其他控件只有一个子项,但您仍然需要将它们提前以使其中的任何一个子项成为最顶层。
Finally, Adornersare a good way to put things on top of everything, but they are not part of the main visual tree. So I'm not sure that would work in your case.
最后,装饰器是将事物置于一切之上的好方法,但它们不是主视觉树的一部分。所以我不确定这是否适用于您的情况。
回答by Sri_kanth0526
I tried canvas.zindex and it didn't work, but the solution that did for me is using Border in a Popup control:
我尝试了 canvas.zindex 但它没有用,但对我有用的解决方案是在 Popup 控件中使用 Border:
<Popup IsOpen="True/False">
<Border Background="White">
<DatePicker/>
</Border>
</Popup>
回答by Sergey
I found better solution. Get it:
我找到了更好的解决方案。得到它:
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;
}
}
It is just example, not universal method. But you can use it in apps with dynamic adding of controls. This code just adds an element which you want to put on a top to the and of the UIElementCollection. It works if all of your elements have the same ZIndex.
这只是示例,而不是通用方法。但是您可以在具有动态添加控件的应用程序中使用它。这段代码只是添加了一个你想放在 UIElementCollection 的和顶部的元素。如果您的所有元素都具有相同的 ZIndex,则它会起作用。
回答by colmde
I've only tested for a Window control but...
我只测试了 Window 控件,但是...
this.Topmost = true;
this.Topmost = false;
The first line brings it to the front, the second line stops it from being permanently on front.
第一行将它带到前面,第二行阻止它永久在前面。

