从 WPF 中重叠的 UserControl 获取 MouseEvent

Get MouseEvent from overlapped UserControl in WPF

我在 WPF/C# 中的 MouseEvents 有问题。
我得到了一些简单的 WPF 结构:

<Grid Name="ID1" Grid.Column="1" Grid.Row="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <customUserControl:CustomUserControl:Name="MainDisplay" UseDefaultContextMenu="False" Grid.Row="0">
        <customUserControl:CustomUserControl.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Thing1" Click="Click1"/>
                <MenuItem Header="Thing2" Click="Click2"/>
                <MenuItem Header="Thing3" Click="Click3"/>
                <MenuItem Header="Thing4" Click="Click4"/>
            </ContextMenu>
        </customUserControl:CustomUserControl.ContextMenu>
    </customUserControl:CustomUserControl>
    <Overlay1:OverlayS Name="Overlay_One" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Transparent"/>
</Grid>

如您所见,我得到了带有两个重叠用户控件的标准网格。 当右击 CustomUserControl 时,我可以访问 ContextMenu。
Overlay1 确实显示了具有透明背景的叠加层。仍然显示时,我无法再访问 customUserControl 的 MouseEvents。但这是必需的。

我现在的想法是简单地实现一个切换按钮来在 CustomUserControl 或 Overlay1 上的 MouseEvents 之间切换,并且两者仍然同时显示。

您可以将 OverlayS 捕获的所有事件绕过到您需要的控件,例如:

  private void OverlayS_Click(object sender, RoutedEventArgs e)
        {                 
                if (!e.Handled)
                {
                   // e.Handled = true; //Set to true only when the mouse event must end here
                    var eventArg = new RoutedEventArgs(e.RoutedEvent);                    
                    eventArg.Source = sender;
                    var otherUIControl = CustomUserControl as UIElement;
                    otherUIControl.RaiseEvent(eventArg);
                }  
        }

   

对于其他鼠标事件(previewMouseDown、MouseWheel 等),您必须创建适当的 EventArgs。例如:

       private void OverlayS_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!e.Handled)
            {
                // e.Handled = true;//Set to true only when the mouse event must end here
                 var eventArg = new MouseButtonEventArgs(e.MouseDevice,e.Timestamp, e.ChangedButton);
                eventArg.RoutedEvent = e.RoutedEvent; 
                eventArg.Source = sender;               
                var otherUIControl = CustomUserControl as UIElement;
                otherUIControl.RaiseEvent(eventArg);
            }
        }

您可能不必复制 EventArgs,只需将它们传递给其他 UiControl。

  private void OverlayS_Click(object sender, RoutedEventArgs e)
        {                 
                if (!e.Handled)
                {                    
                    var otherUIControl = CustomUserControl as UIElement;
                    otherUIControl.RaiseEvent(e);
                }  
        }

但要小心,因为某些鼠标事件可能会到达许多控件并且它们会干扰 e.Handled。