微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

下面是代码: 我创建了如下的自定义委托命令

  • 查看模型
namespace TestProject.viewmodels
{
    public class Testviewmodel 
    {

        public CustomDelegateCommand MenuButtonClickCommand { get; set; }


        public Testviewmodel()
        {
          MenuButtonClickCommand = new CustomDelegateCommand (async () => await ShowMenuAction());
        }

        
        private async Task ShowMenuAction()
        {
            //await some stuff
        }
    }
}


  • CustomDelegateCommand.cs

public class CustomDelegateTimerCommand : DelegateCommand
{
        public CustomDelegateTimerCommand(Action executeMethod,Func<bool> validateMethod,Action onBusy = default(Action)) : base(executeMethod)
        {
            BackgroundTaskWaitHandle = new EventWaitHandle(true,EventResetMode.ManualReset);
            _validateMethod = validateMethod;
            _onBusy = onBusy;
        }

}

我面临的问题是,每当用户快速单击按钮时,菜单列表弹出窗口就会多次打开。 我的项目中有很多命令,我需要一个可以在全球范围内使用的解决方案。

我尝试使用ObservesCanExecute()解决以下问题,但是我不喜欢为每个命令创建一个单独的变量的想法,因为我的项目中有很多命令,并且我不希望按钮当CanExecute = false时进入禁用状态。

MenuButtonClickCommand = new CustomDelegateCommand (async () => await ShowMenuAction().ObservesCanExecute(() => CanExecute );

private async Task ShowMenuAction()
        {
            CanExecute = false;

            //await some stuff

            CanExecute = true;
        }

非常感谢您的帮助!

解决方法

有2种解决方案。一种是在使用时,而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);
    }

}

然后订阅onclick事件:

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

                //DO something
            }).OnClick;

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 :) 还有第二种解决方案实际上禁用了该按钮,因此用户甚至无法点击它,但是第一个解决方案只是忽略了进一步的点击,直到延时结束为止。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。