是否可以比较两个 WPF 控件的相对 Z 顺序(哪一个将绘制在顶部),无论它们在逻辑/可视树结构中的关系以及使用什么布局容器?
我需要它能够确定可能与其他控件重叠的控件的可见区域。我的计划是从控件几何图形开始,并与将使用将 GeometryCombineMode 属性设置为“排除”的 CombinedGeometry 在顶部绘制的所有控件的几何图形相交。
更新:
如果大家感兴趣的话,我使用 gdi32 API 来计算可见区域。
<前> [DllImport("gdi32.dll")]
静态 extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport(“gdi32.dll”)]
静态外部int合并Rgn(IntPtr hrgnDest,IntPtr hrgnSrc1,IntPtr hrgnSrc2,int fnCombineMode);
[DllImport(“gdi32.dll”)]
静态 extern int GetRegionData(IntPtr hRgn, uint dwCount, IntPtr lpRgnData);
[DllImport(“gdi32.dll”)]
静态 extern bool SetRectRgn(IntPtr hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport(“gdi32.dll”)]
静态 extern bool DeleteObject(IntPtr hObject);
最佳答案
昨晚我也遇到了类似的问题。我的目标是确定一个控件是否会绘制在另一个控件的前面。我搜索了大约 45 分钟,没有找到 API 提供的解决方案,所以我不得不遍历可视化树来找出哪一个应该绘制在上面。所以,根据我的研究,我想我的答案是否定的,如果不亲自查看视觉树,您就无法比较相对 z 顺序。
如果您仍然需要,这里是我用来查找控件的相对 z 顺序的代码(InFrontOf 方法),其中还考虑了手动设置控件的 .ZOrder 属性(适用于我的代码,但未经过彻底测试) ,如果控件的 ZOrder 属性设置为负值则不起作用)。
private bool InFrontOf(FrameworkElement c1, FrameworkElement c2){
Panel root = FindWindowRoot(c1); // Find the root of the document, assumes that c1 and c2 are part of the same document
Trace.Assert(root != null, "root of ui element is not a window or a panel that contains children");
int z1 = Math.Max(Panel.GetZIndex(c1), GetDrawOrder(root, c1));
int z2 = Math.Max(Panel.GetZIndex(c2), GetDrawOrder(root, c2));
return z1 > z2;
}
private Panel FindWindowRoot(FrameworkElement child)
{
FrameworkElement current = child;
while(current as Window == null)
{
current = (FrameworkElement)VisualTreeHelper.GetParent(current);
}
return ((Window)current).Content as Panel;
}
private int GetDrawOrder(Panel root, FrameworkElement needle)
{
int result = 0;
FrameworkElement current = root;
Queue<FrameworkElement> toSearch = new Queue<FrameworkElement>();
toSearch.Enqueue(current);
while(needle != current)
{
if(current is Panel)
{
Panel p = (Panel) current;
foreach (FrameworkElement frameworkElement in p.Children)
{
toSearch.Enqueue(frameworkElement);
}
}
if (current is ContentControl)
{
ContentControl cc = (ContentControl)current;
if(cc.Content as FrameworkElement != null)
toSearch.Enqueue(cc.Content as FrameworkElement);
}
current = toSearch.Dequeue();
result++;
}
return result;
}
关于c# - 如何比较属于同一逻辑/可视树的两个 WPF 控件的相对 Z 顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8186844/