В слой рекламодателя WPF не было передано ни одного события - PullRequest
5 голосов
/ 31 мая 2010

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

Для отладки моей проблемы я создал очень простой пример, в котором у меня есть пользовательский элемент управления, в котором есть только кнопка. Этот пользовательский элемент управления отображается в слое 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 ]

11 голосов
/ 29 декабря 2010

Не знаю, пробовали ли вы это уже: Если вы хотите, чтобы добавленный элемент реагировал на события, я думаю, что этот элемент должен быть привязан к визуальному дереву рекламодателя. Способ сделать это - использовать 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];
    }

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

1 голос
/ 06 апреля 2011

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

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

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

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

...