Нет событий, переданных в слой рекламодателя 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