[英]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.