Проблема с VisualTreeHelper.HitTest в WPF - PullRequest
4 голосов
/ 05 августа 2010

Я пытаюсь протестировать группу пользовательских элементов управления на холсте. Я не хочу, чтобы HitTest () прошел весь путь по визуальному дереву, поэтому я использую FilterCallback, чтобы удостовериться, что я только проверяю пользовательский контроль.

Моя проблема в том, что UserControl никогда не срабатывает, он должен, но это не так. Если я использую FilterCallback, я возвращаюсь, что он ничего не ударил. Если я позволю HitTest проходить через визуальное дерево, он пропускает UserControl.

Вот код:

<Canvas x:Name="Container">
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
</Canvas>

...
VisualTreeHelper.HitTest(Container, OnFilter, OnResult, myPoint);
...

private void OnResult(DependencyObject o)
{
   //I'll get the Rectangle here, but never the userControl  
}

private void OnFilter(DependencyObject o)
{
   //I will get the UserControl here, but even when I do nothing more than continue, it will not trigger a visualHit.  But the child rectangle will.
}

Ответы [ 2 ]

11 голосов
/ 23 августа 2011

Я знаю, что чертовски поздно отвечать на этот вопрос, но здесь идет речь: другой подход - переопределить HitTestCore в UserControl и предоставить ему поведение по умолчанию, которое можно ожидать от него:

protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters)
{
    return new PointHitTestResult(this, hitTestParameters.HitPoint);
}

(Конечно, вы могли бы усложнять вещи и проверять нажатия на реальных дочерних элементах или комбинации их ограничивающих рамок, но для меня ограничивающая рамка пользовательского элемента управления была достаточно хорошей, а также, если вы хотите выполнить проверку на соответствие геометрии, вам нужно переопределитьэта вторая перегрузка также.)

Это заставляет его работать как положено, отфильтровывая дочерние элементы при использовании HitTestFilterBehavior.ContinueSkipChildren в фильтре.

2 голосов
/ 05 августа 2010

У меня была такая же проблема, когда HitTest не нашел пользовательский элемент управления.Очевидно, это сделано специально (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/005dad03-c8eb-405f-9567-50653a0e612c).

). Я работал над этим, обрабатывая попадание какого-либо элемента внутри пользовательского элемента управления, а затем находя родительский элемент управления с помощью метода VisualTreeHelper.GetParent. Я не оченьеще не знаком с WPF, поэтому я не уверен, что было бы лучше использовать свойство FrameworkElement.Parent.

Однако, вот мой метод для нахождения пользовательского элемента управления (или любого визуального родителя некоторого необходимого типа)после первого поиска некоторых из его элементов содержимого с помощью теста нажатия:

public static T GetVisualParent<T>(this DependencyObject element) where T : DependencyObject
{
    while (element != null && !(element is T))
        element = VisualTreeHelper.GetParent(element);

    return (T)element;
}
...