WPF UIElement.IsHitTestVisible = false;все еще возвращаются хиты? - PullRequest
10 голосов
/ 27 января 2011

Я извлекаю элемент управления из FrameworkElement для использования в качестве контейнера для VisualCollection, поскольку я выполняю много пользовательских операций рендеринга с использованием DrawingVisuals (создание игровой карты).

У меня есть несколько разных экземпляров моего контейнера, наложенных друг на друга, и я хочу, чтобы только тестирование попаданий влияло на видимый в данный момент слой, поэтому я попытался сделать очевидное и установить .IsHitTestVisible = false, что в соответствии с в MSDN не должны возвращать дочерние элементы в качестве результатов попаданий.

Тем не менее, я все еще получаю хиты, возвращенные для контейнеров, которые установлены .IsHitTestVisible = false. Я пробовал все остальное, о чем могу подумать: «Свернуто», «Скрыто», «Отключено», 0 «Непрозрачность».

1 Ответ

13 голосов
/ 27 января 2011

Я думаю, что это ошибка. Я использовал Reflector, чтобы понять, почему метод HitTest возвращает невидимые элементы, и обнаружил, что нет проверки на видимость.

Мое решение - использовать перегрузку HitTest с фильтром:

public static HitTestFilterBehavior HitTestFilterInvisible(DependencyObject potentialHitTestTarget)
{
    bool isVisible = false;
    bool isHitTestVisible = false;

    var uiElement = potentialHitTestTarget as UIElement;
    if (uiElement != null)
    {
        isVisible = uiElement.IsVisible;
        if (isVisible)
        {
            isHitTestVisible = uiElement.IsHitTestVisible;
        }
    }
    else
    {
        UIElement3D uiElement3D = potentialHitTestTarget as UIElement3D;
        if (uiElement3D != null)
        {
            isVisible = uiElement3D.IsVisible;
            if (isVisible)
            {
                isHitTestVisible = uiElement3D.IsHitTestVisible;
            }
        }
    }

    if (isVisible)
    {
        return isHitTestVisible ? HitTestFilterBehavior.Continue : HitTestFilterBehavior.ContinueSkipSelf;
    }

    return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
}
...
// usage:

    VisualTreeHelper.HitTest(
        myHitTestReference,
        HitTestFilterInvisible,
        hitTestResult =>
        {
            // code to handle element which is visible to the user and enabled for hit testing.
        },
        new PointHitTestParameters(myHitTestPoint));

Я надеюсь, что это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...