如何防止在Xamarin表单中快速单击按钮时多次触发事件

如何防止在Xamarin表单中快速单击按钮时多次触发事件,xamarin,xamarin.forms,mvvm,command,Xamarin,Xamarin.forms,Mvvm,Command,当快速单击按钮时,如何避免多次调用同一事件 代码如下: 我创建了一个自定义委托命令,如下所示 视图模型 CustomDelegateCommand.cs 非常感谢您的帮助 有两种解决方案。一个是当您使用MVVM时,另一个是当您不使用MVVM时。 非MVVM解决方案将方法的执行延迟一定时间,如下所示: public class SingleClickListener { private bool hasClicked; private Action<objec

当快速单击按钮时,如何避免多次调用同一事件

代码如下: 我创建了一个自定义委托命令,如下所示

  • 视图模型
  • CustomDelegateCommand.cs

非常感谢您的帮助

有两种解决方案。一个是当您使用MVVM时,另一个是当您不使用MVVM时。 非MVVM解决方案将方法的执行延迟一定时间,如下所示:

    public class SingleClickListener
{
    private bool hasClicked;
    private Action<object, EventArgs> _setOnClick;
    public SingleClickListener(Action<object, EventArgs> setOnClick)
    {
        _setOnClick = setOnClick;
    }
    public void OnClick(object v, EventArgs e)
    {
        if (!hasClicked)
        {
            _setOnClick(v, e);
            hasClicked = true;
        }
        reset();
    }
    private void reset()
    {
        Android.OS.Handler mHandler = new Android.OS.Handler();
        mHandler.PostDelayed(new Action(() => { hasClicked = false; }), 500);
    }

}
Mvvm解决方案稍微复杂一点,但并没有那么简单

            TestCommand = new Command(
            execute: async () =>
            {
                IsEditing = true;
                RefreshCanExecutes();
                //Fire Method
         TestMethod();
            },
            canExecute: () =>
            {
                return !IsEditing;
            });

        public void RefreshCanExecutes()
    {
        (TestCommand as Command).ChangeCanExecute();
    }
        public void TestMethod()
    {
        //DO something
        IsEditing = false;
        RefreshCanExecutes();
    }
显然,不要忘记将命令绑定到xaml:)
另外,第二种解决方案实际上禁用了按钮,因此用户甚至无法点击它,但第一种解决方案只会忽略进一步的点击,直到时间延迟完成。

您可以绑定按钮的
IsEnabled
,并在用户点击时将其设置为false,并在处理逻辑后将其设置为true。谢谢,上面提到的两种解决方案都可以工作,但由于我的项目中有很多命令,我希望避免为每个命令创建单独的变量(IsEditing)。我很抱歉您不能这样做。除非您使用App.xaml.cs中声明的全局变量,但一旦您点击一个按钮,就会禁用所有按钮。
MenuButtonClickCommand = new CustomDelegateCommand (async () => await ShowMenuAction().ObservesCanExecute(() => CanExecute );

private async Task ShowMenuAction()
        {
            CanExecute = false;

            //await some stuff

            CanExecute = true;
        }

    public class SingleClickListener
{
    private bool hasClicked;
    private Action<object, EventArgs> _setOnClick;
    public SingleClickListener(Action<object, EventArgs> setOnClick)
    {
        _setOnClick = setOnClick;
    }
    public void OnClick(object v, EventArgs e)
    {
        if (!hasClicked)
        {
            _setOnClick(v, e);
            hasClicked = true;
        }
        reset();
    }
    private void reset()
    {
        Android.OS.Handler mHandler = new Android.OS.Handler();
        mHandler.PostDelayed(new Action(() => { hasClicked = false; }), 500);
    }

}
                var buttonNa = new Button { Text = "Test Button" };
            buttonNa.Clicked += new SingleClickListener((sender, e) =>
            {

                //DO something
            }).OnClick;
            TestCommand = new Command(
            execute: async () =>
            {
                IsEditing = true;
                RefreshCanExecutes();
                //Fire Method
         TestMethod();
            },
            canExecute: () =>
            {
                return !IsEditing;
            });

        public void RefreshCanExecutes()
    {
        (TestCommand as Command).ChangeCanExecute();
    }
        public void TestMethod()
    {
        //DO something
        IsEditing = false;
        RefreshCanExecutes();
    }