0

我花了很多时间来解决这个问题。我在 wpf 中有自定义用户控件,它是带有 10 个按钮的工具栏。此工具栏添加在 Panel(winform panel) panel.Controls.Add(usercontrol) 中。我想要的是,从面板响应 MouseLeave 事件。我试过 panel.MouseLeave += MouseLeaveEvent,但没有引发事件。没有一个事件没有引发(MouseMove 等)。是否有任何解决方案,如何实现,将引发 MouseLeave 事件?非常感谢。

编辑

这是代码。

CustomToolbar = new AxisMediaControlToolbarViewModel(this);
                    var toolbarView = new AxisMediaControlToolbarView { ViewModel = CustomToolbar };
                    var elementHost = new ElementHost { Dock = DockStyle.Fill, Child = toolbarView };
                    toolbarPanel.Controls.Add(elementHost);
4

2 回答 2

0

原因之一可能是您的面板的背景未设置。

如果你不设置背景,那么控件虽然是“它的区域不被照顾”并且实际上它是透明的,因为它没有被绘制。然而,它有更多的后果:它的区域不仅没有被绘制,而且它也没有被跟踪,即鼠标事件。

对于初学者,请尝试设置 Background="Transparent"。这可能没什么意义,因为它已经是透明的,但这样面板控件将背景,如果没有其他问题,它可能会立即开始看到鼠标事件。

编辑:快速示例:

用户控件.xaml

<UserControl x:Class="UserControlMouse.MyButtonPanel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Background="LightBlue"
             Tag="You will never see this message">

    <StackPanel Margin="20" Background="LightGray"
                MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
                Tag="StackPanel">
        <StackPanel.Resources>
            <Style TargetType="Border">
                <Setter Property="Margin" Value="2" />
                <Setter Property="Padding" Value="5" />
                <Setter Property="Background" Value="Gray" />
            </Style>
            <Style TargetType="TextBlock">
                <Setter Property="TextAlignment" Value="Center" />
                <Setter Property="Background" Value="WhiteSmoke" />
            </Style>
        </StackPanel.Resources>

        <Button Content="#1" MaxWidth="80" Tag="Button#1" />
        <Button Content="#2" MaxWidth="80" Tag="Button#2"
                MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
                />
        <Button Content="#3" MaxWidth="80" Tag="Button#3" />
        <Button Content="#4" MaxWidth="80" Tag="Button#4" />
        <Button Content="#5" MaxWidth="80" Tag="Button#5"
                MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
                />
        <Button Content="#6" MaxWidth="80" Tag="Button#6" />
        <Button Content="#7" MaxWidth="80" Tag="Button#7" />
        <Button Content="#8" MaxWidth="80" Tag="Button#8" />

        <TextBlock Margin="0,20,0,0" Tag="Comment TextBlock #1">
            <Run Text="Sender was: " />
            <Run Text="{Binding ReportingControl}" />
        </TextBlock>
        <TextBlock Tag="Comment TextBlock #2">
            <Run Text="Source was: " />
            <Run Text="{Binding ContainerControl}" />
        </TextBlock>
        <TextBlock Tag="Comment TextBlock #3">
            <Run Text="Now you are in: " />
            <Run Text="{Binding ControlUnderMouse}" />
        </TextBlock>

        <UniformGrid Columns="3" Tag="indicator UniformGrid">
            <Border Visibility="{Binding Visib_OnEnter}" Tag="indicator border #1">
                <TextBlock Text="Enter" />
            </Border>
            <Border Visibility="{Binding Visib_OnMove}" Tag="indicator border #2"
                    MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave">
                <TextBlock Text="Move" />
            </Border>
            <Border Visibility="{Binding Visib_OnLeave}" Tag="indicator border #3">
                <TextBlock Text="Leave" />
            </Border>
        </UniformGrid>
    </StackPanel>

</UserControl>

用户控件.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace UserControlMouse
{
    public partial class MyButtonPanel : UserControl
    {
        private SimpleDataObject theData = new SimpleDataObject();

        public MyButtonPanel()
        {
            InitializeComponent();
            this.DataContext = theData;
        }

        private const int COUNTER_LAG = 20;

        private int counter_enter = 0;
        private void handler_MouseEnter(object sender, MouseEventArgs e)
        {
            counter_enter = counter_mouse;

            theData.Visib_OnEnter = System.Windows.Visibility.Visible;
            theData.Visib_OnMove = System.Windows.Visibility.Hidden;
            theData.Visib_OnLeave = System.Windows.Visibility.Hidden;

            theData.ReportingControl = makeDescriptionOfControl(sender);
            theData.ContainerControl = makeDescriptionOfControl(e.Source);
            theData.ControlUnderMouse = makeDescriptionOfControl(null);
        }

        private int counter_mouse = 0;
        private void handler_MouseMove(object sender, MouseEventArgs e)
        {
            ++counter_mouse;

            if (counter_mouse > counter_enter + COUNTER_LAG) theData.Visib_OnEnter = System.Windows.Visibility.Hidden;
            theData.Visib_OnMove = System.Windows.Visibility.Visible;
            if (counter_mouse > counter_leave + COUNTER_LAG) theData.Visib_OnLeave = System.Windows.Visibility.Hidden;

            theData.ReportingControl = makeDescriptionOfControl(sender);
            theData.ContainerControl = makeDescriptionOfControl(e.Source);
            theData.ControlUnderMouse = makeDescriptionOfControl(null);
        }

        private int counter_leave = 0;
        private void handler_MouseLeave(object sender, MouseEventArgs e)
        {
            counter_leave = counter_mouse;

            theData.Visib_OnEnter = System.Windows.Visibility.Hidden;
            theData.Visib_OnMove = System.Windows.Visibility.Hidden;
            theData.Visib_OnLeave = System.Windows.Visibility.Visible;

            theData.ReportingControl = makeDescriptionOfControl(sender);
            theData.ContainerControl = makeDescriptionOfControl(e.Source);
            theData.ControlUnderMouse = makeDescriptionOfControl(null);
        }

        private string makeDescriptionOfControl(object uiobj)
        {
            if (uiobj == null)
                return "???";

            string text = uiobj.GetType().Name;

            var fe = uiobj as FrameworkElement;
            if (fe != null && fe.Tag != null)
                text += " (" + (string)((FrameworkElement)uiobj).Tag + ")";

            return text;
        }
    }

    public class SimpleDataObject : DependencyObject
    {
        public string ControlUnderMouse { get { return (string)GetValue(ControlUnderMouseProperty); } set { SetValue(ControlUnderMouseProperty, value); } }
        public static readonly DependencyProperty ControlUnderMouseProperty = DependencyProperty.Register("ControlUnderMouse", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));

        public string ReportingControl { get { return (string)GetValue(ReportingControlProperty); } set { SetValue(ReportingControlProperty, value); } }
        public static readonly DependencyProperty ReportingControlProperty = DependencyProperty.Register("ReportingControl", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));

        public string ContainerControl { get { return (string)GetValue(ContainerControlProperty); } set { SetValue(ContainerControlProperty, value); } }
        public static readonly DependencyProperty ContainerControlProperty = DependencyProperty.Register("ContainerControl", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));

        public Visibility Visib_OnEnter { get { return (Visibility)GetValue(Visib_OnEnterProperty); } set { SetValue(Visib_OnEnterProperty, value); } }
        public static readonly DependencyProperty Visib_OnEnterProperty = DependencyProperty.Register("Visib_OnEnter", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));

        public Visibility Visib_OnMove { get { return (Visibility)GetValue(Visib_OnMoveProperty); } set { SetValue(Visib_OnMoveProperty, value); } }
        public static readonly DependencyProperty Visib_OnMoveProperty = DependencyProperty.Register("Visib_OnMove", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));

        public Visibility Visib_OnLeave { get { return (Visibility)GetValue(Visib_OnLeaveProperty); } set { SetValue(Visib_OnLeaveProperty, value); } }
        public static readonly DependencyProperty Visib_OnLeaveProperty = DependencyProperty.Register("Visib_OnLeave", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));
    }
}

样本窗口

<Window x:Class="UserControlMouse.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:UserControlMouse"
        Title="MainWindow" Height="350" Width="525">
    <Grid Background="Red">
        <my:MyButtonPanel Margin="10" />
    </Grid>
</Window>

请运行它并使用它。

  • 观察事件是如何触发的以及哪些控件可以看到它们。注意 SENDER 和 SOURCE 是如何变化的
  • 请注意,SENDER 始终是相同的,即鼠标捕获的根。改变的是源头
  • 请注意,只有按钮 #2 和按钮 #5 报告进入/离开(他们有直接的处理程序,其他人没有!)
  • 请注意,即使其他控件没有鼠标处理程序,也可以通过鼠标移动“检测到”其他控件-您可以使用没有任何鼠标捕获集的 Source 获取事件
  • 检查 OriginalSource(最后一个文本行) - 这是鼠标正下方的控件 - 通常它不是您想要注意的控件,因为它是某些模板或样式中的一些“叶子控件”。
于 2012-08-22T09:15:14.593 回答
0

这个线程中提到了很多原因:

  • 设置用户控件的背景
  • 使画布可聚焦
  • 注意 RenderTransforms

编辑

我做了一个测试,只要 WPF 元素没有覆盖面板,它就可以正常工作。鼠标必须直接在面板上才能生成事件。DockStyle.Fill 可能是您的问题的原因。

于 2012-08-22T10:10:21.837 回答