Предотвратить двойной щелчок от двойного запуска команды - PullRequest
12 голосов
/ 08 мая 2009

Учитывая, что у вас есть элемент управления, который запускает команду:

<Button Command="New"/>

Есть ли способ предотвратить двойной запуск команды, если пользователь дважды щелкнет по команде?

РЕДАКТИРОВАТЬ: В данном случае важно то, что я использую модель Commanding в WPF.

Похоже, что при каждом нажатии кнопки команда выполняется. Я не вижу способа предотвратить это, кроме отключения или скрытия кнопки.

Ответы [ 14 ]

0 голосов
/ 30 октября 2018

Я использую Xamarin и MVVMCross, хотя это не WPF. Я думаю, что применимо следующее решение, я создал решение, специфичное для viewmodel (не связанное с пользовательским интерфейсом для конкретной платформы), которое я считаю очень удобным, используя помощника. или базовый класс для модели представления создает список, который отслеживает команды, что-то вроде этого:

private readonly List<string> Commands = new List<string>();

        public bool IsCommandRunning(string command)
        {
            return Commands.Any(c => c == command);
        }

        public void StartCommand(string command)
        {
            if (!Commands.Any(c => c == command)) Commands.Add(command);
        }

        public void FinishCommand(string command)
        {
            if (Commands.Any(c => c == command))  Commands.Remove(command);
        }

        public void RemoveAllCommands()
        {
            Commands.Clear();
        }

Добавьте команду в действие следующим образом:

public IMvxCommand MyCommand
        {
            get
            {
                return new MvxCommand(async() =>
                {
                    var command = nameof(MyCommand);
                    if (IsCommandRunning(command)) return;

                    try
                    {
                        StartCommand(command);

                        await Task.Delay(3000);
                       //click the button several times while delay
                    }
                    finally
                    {
                        FinishCommand(command);
                    }
                });
            }
        }

Команда try / finally просто гарантирует, что команда всегда завершается.

Протестировал это, установив асинхронное действие и сделав задержку, первое нажатие срабатывает, второе возвращается в состояние.

0 голосов
/ 20 апреля 2017

Была такая же проблема, решена с помощью прикрепленного поведения.

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;
        }

    }
}

, а затем просто установите для свойства значение TRUE либо непосредственно в XAML, объявив стиль, чтобы он мог влиять на все ваши кнопки одновременно. (не забудьте объявление пространства имен XAML)

<Style x:Key="styleBoutonPuff" TargetType="{x:Type Button}">
    <Setter Property="VLEvaControls:ButtonBehavior.IgnoreDoubleClick" Value="True" />
    <Setter Property="Cursor" Value="Hand" />
</Style>
0 голосов
/ 16 декабря 2009

Это проверяет, прошла ли проверка, а если нет, то отключает кнопку.

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 голосов
/ 08 мая 2009

Если ваш элемент управления происходит от System.Windows.Forms.Control, вы можете использовать событие двойного щелчка .

Если он не является производным от System.Windows.Forms.Control, вместо этого подключает mousedown и подтверждает количество кликов == 2:

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.ClickCount == 2)
    {
       //Do stuff
    }
 }
...