MouseDown / Up事件在WPF中无法正常工作

时间:2015-11-13 13:20:13

标签: c# wpf checkbox togglebutton

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

button.AddHandler(Ellipse.MouseDownEvent, new MouseButtonEventHandler(Toggle));

这是我的事件处理程序:

void Toggle(object sender, EventArgs e)
    {
        DependencyObject active = GetTemplateChild("Active");
        DependencyObject button = GetTemplateChild("ToggleButton");
        Storyboard sb = new Storyboard();

        ThicknessAnimation ta = new ThicknessAnimation();
        Storyboard.SetTargetProperty(ta, new PropertyPath("Margin"));
        Storyboard.SetTarget(ta, button);
        ta.Duration = TimeSpan.FromSeconds(0.2);


        DoubleAnimation 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.....)也无效。

如果您想在没有太多编辑的情况下重现问题,请使用代码here。 然后在WPF应用程序中使用它,你就会看到。

任何帮助都非常感激。

编辑:另一个发现:它适用于右键单击和中键单击,但不适用于左键单击。想知道为什么...?? 我的鼠标工作正常。

编辑#2: Converters

2 个答案:

答案 0 :(得分:3)

实现了一些自定义控件后,我发现了一些特别处理鼠标事件的有趣行为。基本上,您可能遇到另一个控件,甚至可能在您的ControlTemplate中窃取鼠标焦点并在获取之前使用鼠标事件。

该问题有两种解决方案:

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

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

答案 1 :(得分:2)

用户控件触发MouseDown和MouseUp事件。
您应该使用事件:PreviewMouseDown和PreviewMouseUp。

此外,您可以使用MouseEnter和MouseLeave事件,以便在鼠标位于对象上时解决视觉反馈。