Я столкнулся с подобной проблемой прошлой ночью.Цель для меня состояла в том, чтобы определить, будет ли один элемент управления отображен перед другим.Я искал около 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;
}