#c# #wpf #xaml
#c# #wpf #xaml
Вопрос:
У меня есть сетка с двумя перекрывающимися пользовательскими элементами управления:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ControlA Grid.Row="0" Grid.Column="1"
Grid.RowSpan="2"
Canvas.ZIndex="1"
Background="Transparent"/>
<ControlB Grid.Row="1" Grid.Column="0"
Grid.ColumnSpan="2"/>
</Grid>
Оба имеют поведение щелчка и прокрутки и прослушивают события MouseDown / MouseWheel, ControlB также имеет собственное VisualTree с дочерними элементами управления, которые должны получать эти туннелирующие и пузырьковые события (ControlA довольно проста, но все еще нуждается в этих событиях).
Нажатие на неперекрывающуюся часть работает нормально и предназначено, но когда я нажимаю на перекрывающуюся часть, я могу получить только одно из этих событий, а не оба, как я хочу.
Я пытался перехватить события предварительного просмотра и делегировать их дочерним элементам управления, но до сих пор я не нашел способа, который вообще не приводил бы ни к какому поведению, ни к StackOverflow.
//Does not work
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
ControlA.RaiseEvent( new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left){RoutedEvent = MouseDownEvent} );
ControlB.RaiseEvent( new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left){RoutedEvent = MouseDownEvent} );
}
Должен ли я вручную реализовать VisualTreeHelper.HitTest()
и просмотреть визуальное дерево? Должен ли я сделать фоновое значение controlla нулевым и принудительно запускать события для него (поскольку в нем отсутствует VisualTree дочерних элементов), в то время как ControlB может использовать обычное туннелирование и пузырькование?
Как я могу отправлять события естественным образом (чтобы никакие принудительные команды полностью не заменяли систему событий) обоим элементам управления?
Комментарии:
1. Почему бы просто не использовать
ControlA.RaiseEvent(e);
?2. Приводит к рекурсивному StackOverflow, поскольку это увеличило бы сетку. По какой-то причине снова происходит событие предварительного просмотра. Создание новых аргументов предотвратило это. 🤷
3. Если
ControlB
это не логический потомокControlA
, вы не можете туннелировать или переносить события из одного элемента управления в другой. Вам нужно вызвать эти события вручную.4. Логически они являются братьями и сестрами, и было бы мало смысла иметь их родительскими / дочерними (в любой конфигурации). Итак, я должен вызывать события, как? Мой опубликованный способ работает не так, как предполагалось. Может быть, я просто использую неправильный синтаксис или метод?