鼠标下降/上升事件在WPF中无法正常工作

本文关键字:常工作 工作 WPF 事件 鼠标 | 更新日期: 2023-09-27 18:21:52

我有一个基于ToggleButton的自定义控件。在它的构造函数中,我创建了一些FrameworkElementFactory类型的元素,并为其中一个元素分配了一个EventHandler,如下所示:

button.AddHandler(Ellipse.MouseDownEvent,新的MouseButtonEventHandler(切换));

这是我的事件处理程序:

private void Toggle(object sender, EventArgs e)
{
    var active = GetTemplateChild("Active");
    var button = GetTemplateChild("ToggleButton");
    Storyboard sb = new Storyboard();
    var ta = new ThicknessAnimation();
    Storyboard.SetTargetProperty(ta, new PropertyPath("Margin"));
    Storyboard.SetTarget(ta, button);
    ta.Duration = TimeSpan.FromSeconds(0.2);

    var da = new DoubleAnimation();
    Storyboard.SetTargetProperty(da, new PropertyPath("Width"));
    Storyboard.SetTarget(da, active);
    da.Duration = TimeSpan.FromSeconds(0.2);
    if ((bool)IsChecked)
    {
        ta.To = new Thickness(0);
        da.To = (double)button.GetValue(Ellipse.WidthProperty);
        IsChecked = !IsChecked;
    }
    else
    {
        ta.To = new Thickness(this.Width - (double)button.GetValue(Ellipse.WidthProperty), 0, 0, 0);
        da.To = this.Width;
        IsChecked = !IsChecked;
    }
    sb.Children.Add(ta);
    sb.Children.Add(da);
    sb.Begin();
}

但它不起作用。不起作用,因为它只起一次作用。我的意思是,它应该根据IsChecked属性设置滑块的宽度。最初,它被设置为false。当我单击它时,它会按预期向右展开。但当我再次单击时,它并没有像预期的那样向左移动。

更令人惊讶的是,它与MouseEnter事件完美配合。像MouseDown/Up/LeftMouseButtonUp/PreviewMouseDown.....这样的所有其他事件也不起作用。

如果您想在不进行太多编辑的情况下重现问题,请使用此处的代码。然后只需在WPF应用程序中使用它,您就会看到。

非常感谢您的帮助。

编辑:另一个发现:它适用于右键单击和中键单击,但不适用于左键单击。不知道为什么我的鼠标很好用

编辑#2:转换器

鼠标下降/上升事件在WPF中无法正常工作

MouseDownMouseUp事件由UserControl触发。您应该使用事件:PreviewMouseDownPreviewMouseUp

此外,当鼠标位于对象上方时,可以使用MouseEnterMouseLeave事件来处理视觉反馈。

在实现了几个自定义控件后,我发现了一些有趣的行为,尤其是处理鼠标事件。基本上,你可能会遇到另一个控件,甚至可能是在你的ControlTemplate中,在你得到鼠标焦点并消耗鼠标事件之前的情况

这个问题有两种解决方案:

  • 使用MousePreviewEvents,注意不要标记已消费的事件
  • 绑定到您希望看到更改的实际属性

在这种特殊的情况下,我会有一个InternalIsCheckedProperty,您可以将其绑定到ToggleButton.IsCheckedProperty以调用您的故事板。