Prevent double-click from double firing a command

前端 未结 14 1689
情书的邮戳
情书的邮戳 2020-12-15 08:34

Given that you have a control that fires a command:

Is there a way to prevent the command from being fired

相关标签:
14条回答
  • 2020-12-15 09:19

    Simple & Effective for blocking double, triple, and quadruple clicks

    <Button PreviewMouseDown="Button_PreviewMouseDown"/>
    
    private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ClickCount >= 2)
        {
            e.Handled = true;
        }
    }
    
    0 讨论(0)
  • 2020-12-15 09:20

    You can use the EventToCommand class in the MVVMLightToolkit to prevent this.

    Handle the Click event and send it through EventToCommand from your view to your viewmodel (you can use EventTrigger to do this).
    Set MustToggleIsEnabled="True" in your view and implement a CanExecute() method in your viewmodel.
    Set CanExecute() to return false when the command starts to execute and back to true when the command is done.

    This will disable the button for the duration of processing the command.

    0 讨论(0)
  • 2020-12-15 09:21

    Had the same problem, solved it by using attached behavior.

    namespace VLEva.Core.Controls
    {
        /// <summary></summary>
        public static class ButtonBehavior
        {
            /// <summary></summary>
            public static readonly DependencyProperty IgnoreDoubleClickProperty = DependencyProperty.RegisterAttached("IgnoreDoubleClick",
                                                                                                                      typeof(bool),
                                                                                                                      typeof(ButtonBehavior),
                                                                                                                      new UIPropertyMetadata(false, OnIgnoreDoubleClickChanged));
    
            /// <summary></summary>
            public static bool GetIgnoreDoubleClick(Button p_btnButton)
            {
                return (bool)p_btnButton.GetValue(IgnoreDoubleClickProperty);
            }
    
            /// <summary></summary>
            public static void SetIgnoreDoubleClick(Button p_btnButton, bool value)
            {
                p_btnButton.SetValue(IgnoreDoubleClickProperty, value);
            }
    
            static void OnIgnoreDoubleClickChanged(DependencyObject p_doDependencyObject, DependencyPropertyChangedEventArgs e)
            {
                Button btnButton = p_doDependencyObject as Button;
                if (btnButton == null)
                    return;
    
                if (e.NewValue is bool == false)
                    return;
    
                if ((bool)e.NewValue)
                    btnButton.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(btnButton_PreviewMouseLeftButtonDown);
                else
                    btnButton.PreviewMouseLeftButtonDown -= btnButton_PreviewMouseLeftButtonDown;
            }
    
            static void btnButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (e.ClickCount >= 2)
                    e.Handled = true;
            }
    
        }
    }
    

    and then just set the property to TRUE either directly in XAML by declaring a style so it can affects all your buttons at once. (don't forget the XAML namespace declaration)

    <Style x:Key="styleBoutonPuff" TargetType="{x:Type Button}">
        <Setter Property="VLEvaControls:ButtonBehavior.IgnoreDoubleClick" Value="True" />
        <Setter Property="Cursor" Value="Hand" />
    </Style>
    
    0 讨论(0)
  • 2020-12-15 09:22

    This checks if validation has passed and if it does then disables the button.

    private void checkButtonDoubleClick(Button button)
        {
            System.Text.StringBuilder sbValid = new System.Text.StringBuilder();
            sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ");
            sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ");
            sbValid.Append("this.value = 'Please wait...';");
            sbValid.Append("this.disabled = true;");
            sbValid.Append(this.Page.ClientScript.GetPostBackEventReference(button, ""));
            sbValid.Append(";");
            button.Attributes.Add("onclick", sbValid.ToString());
        }
    
    0 讨论(0)
  • 2020-12-15 09:24

    We solved it like this... with async we couldn't find any other way to effectively block extra clicks on the button which invokes this Click:

    private SemaphoreSlim _lockMoveButton = new SemaphoreSlim(1);
    private async void btnMove_Click(object sender, RoutedEventArgs e)
    {
        var button = sender as Button;
        if (_lockMoveButton.Wait(0) && button != null)
        {
            try
            {                    
                button.IsEnabled = false;
            }
            finally
            {
                _lockMoveButton.Release();
                button.IsEnabled = true;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-15 09:26

    A simple and elegant solution is to create a Behavior disabling reaction on second click in double-click scenario. That's pretty easy to use:

      <Button Command="New">
              <i:Interaction.Behaviors>
                <behaviors:DisableDoubleClickBehavior />
              </i:Interaction.Behaviors>
      </Button>
    

    Behavior (more about behaviors - https://www.jayway.com/2013/03/20/behaviors-in-wpf-introduction/)

    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Interactivity;
    
    public class DisableDoubleClickBehavior : Behavior<Button>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.PreviewMouseDoubleClick += AssociatedObjectOnPreviewMouseDoubleClick;
        }
    
        private void AssociatedObjectOnPreviewMouseDoubleClick(object sender, MouseButtonEventArgs mouseButtonEventArgs)
        {
            mouseButtonEventArgs.Handled = true;
        }
    
        protected override void OnDetaching()
        {
            AssociatedObject.PreviewMouseDoubleClick -= AssociatedObjectOnPreviewMouseDoubleClick;
            base.OnDetaching();
        }
    }
    
    0 讨论(0)
提交回复
热议问题