gpt4 book ai didi

c# - 如何比较属于同一逻辑/可视树的两个 WPF 控件的相对 Z 顺序?

转载 作者:行者123 更新时间:2023-11-30 22:33:41 28 4
gpt4 key购买 nike

是否可以比较两个 WPF 控件的相对 Z 顺序(哪个将绘制在顶部),而不管它们在逻辑/可视树结构中的关系以及使用什么布局容器?

我需要它来确定可能与其他控件重叠的控件的可见区域。我的计划是从控件几何形状开始,然后使用将 GeometryCombineMode 属性设置为“Exclude”的 CombinedGeometry 与将在顶部绘制的所有控件的几何形状相交。

更新:如果每个人都有兴趣,我已经使用 gdi32 API 来计算可见区域。



 [DllImport("gdi32.dll")]
static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

[DllImport("gdi32.dll")]
static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2, int fnCombineMode);

[DllImport("gdi32.dll")]
static extern int GetRegionData(IntPtr hRgn, uint dwCount, IntPtr lpRgnData);

[DllImport("gdi32.dll")]
static extern bool SetRectRgn(IntPtr hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

[DllImport("gdi32.dll")]
static 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com