What is the best way to simulate a Click with MouseUp & MouseDown events or otherwise?

前端 未结 5 730
天涯浪人
天涯浪人 2020-11-30 02:17

In WPF most controls have MouseUp and MouseDown events (and the mouse-button-specific variations) but not a simple Click event that ca

5条回答
  •  没有蜡笔的小新
    2020-11-30 02:26

    Here is a behavior you can add to any element so that it will raise the ButtonBase.Click event using the normal button logic:

    public class ClickBehavior : Behavior
    {
        protected override void OnAttached()
        {
            AssociatedObject.MouseLeftButtonDown += (s, e) =>
            {
                e.Handled = true;
                AssociatedObject.CaptureMouse();
            };
            AssociatedObject.MouseLeftButtonUp += (s, e) =>
            {
                if (!AssociatedObject.IsMouseCaptured) return;
                e.Handled = true;
                AssociatedObject.ReleaseMouseCapture();
                if (AssociatedObject.InputHitTest(e.GetPosition(AssociatedObject)) != null)
                    AssociatedObject.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
            };
        }
    }
    

    Notice the use of mouse capture/release and the input hit test check. With this behavior in place, we can write click handlers like this:

    
        
            
                
            
        
    
    

    and the code behind:

        private void Rectangle_Click(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("Code-behind: Click");
        }
    

    It's easy enough to convert this to all code-behind; the important part is the capture and click logic.

    If you are not familiar with behaviors, install the Expression Blend 4 SDK and add this namespace:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    

    and add System.Windows.Interactivity to your project.

    Edit:

    Here's how to attach the click behavior to an element in code-behind and add a handler for the click event:

    void AttachClickBehaviors()
    {
        AttachClickBehavior(rectangle1, new RoutedEventHandler(OnAttachedClick));
    }
    
    void OnAttachedClick(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("Attached: Click");
    }
    
    // Reusable: doesn't need to be in the code-behind.
    static void AttachClickBehavior(FrameworkElement element, RoutedEventHandler clickHandler)
    {
        Interaction.GetBehaviors(element).Add(new ClickBehavior());
        element.AddHandler(ButtonBase.ClickEvent, clickHandler);
    }
    

提交回复
热议问题