Нет событий, переданных в слой рекламодателя WPF

Я пытаюсь создать красивую "зону перетаскивания" в WPF, которая отображается в слое adorner, когда что-то перетаскивается в основное приложение. Проблема в том, что я не получаю никаких событий от своего рекламодателя, хотя он согласно документации должен получать все входные события, поскольку он находится в более высоком z-порядке.

Чтобы отладить мою проблему, я создал очень простой пример, где у меня есть пользовательский элемент управления только с кнопкой. Этот пользовательский элемент управления отображается в слое adorner, но я не могу нажать кнопку. Зачем? Что я сделал не так?

Мой класс adorner построен так:

    public ShellOverlayAdorner(UIElement element, AdornerLayer adornerLayer)
        :base(element)
    {
        _adornerLayer = adornerLayer;

        _overlayView = new AdornedElement();
        _overlayView.AllowDrop = true;
        _adornerLayer.Add(this);
     }

и создается в главном окне

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        adornerLayer = AdornerLayer.GetAdornerLayer(MyTopGridWithButtonInIt);
        ShellOverlayAdorner shell = new ShellOverlayAdorner(MyTopGridWithButtonInIt, adornerLayer);

    }

Я не получаю никаких событий от моего контроля, то есть никаких щелчков мышью, мыши, нажатий кнопок. Я даже не могу нажать на кнопку в слое Adorner. Что я сделал не так?

2 ответа

Я не знаю, пытались ли вы это сделать: если вы хотите, чтобы добавленный элемент реагировал на события, я думаю, что этот элемент должен быть привязан к визуальному дереву рекламодателя. Способ сделать это - использовать коллекцию VisualCollection, инициализированную для самого рекламодателя, или, по крайней мере, так, как это работает:

    VisualCollection visualChildren;
    FrameworkElement @object;

    public CustomAdorner(UIElement adornedElement) :
        base(adornedElement)
    {
        visualChildren = new VisualCollection(this);
        @object = new Button {Content = "prova"};
        visualChildren.Add(@object);
    }
    protected override Visual GetVisualChild(int index)
    {
        return visualChildren[index];
    }

Таким образом, события правильно маршрутизируются.

У меня просто была такая же проблема. Следуя совету MSDN, я разобрался с ним:

Adorners получают входные события, как и любой другой FrameworkElement. Поскольку у украшателя всегда более высокий z-порядок, чем у элемента, который он украшает, он получает входные события (такие как Drop или MouseMove), которые могут быть предназначены для базового украшенного элемента. Автор может прослушивать определенные входные события и передавать их нижележащему украшенному элементу, повторно вызывая событие.

Чтобы включить сквозное тестирование на попадание элементов в рекламном устройстве, установите для свойства "IsHitTestVisible" для теста на попадание значение "ложный" для рекламодателя.

т.е. в самом рекламодателе убедитесь, что IsHitTestVisible = false

Другие вопросы по тегам