【问题标题】:How to temporarily disable button after click in Xamarin Forms?在 Xamarin Forms 中单击后如何暂时禁用按钮?
【发布时间】:2020-05-13 19:34:06
【问题描述】:

我正在Xamarin Forms 中进行投票申请,我希望用户每天只能投票一次。在 UI 页面上,我创建了一个 ImageButton,我希望用户能够每天点击一次。我尝试使用计时器,并尝试以 5 秒的间隔对其进行测试。应用程序在我第一次单击它时禁用了该按钮,但 5 秒后我可以再次单击它并且它不会禁用该按钮。

private void ImageButton_Clicked(object sender, EventArgs e)
{
   this.IsEnabled = false;
   Timer aTimer = new Timer();
   aTimer.Interval = 5000; //ms
   aTimer.Enabled = true;
   aTimer.Elapsed += ATimer_Elapsed;
}

private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
  this.IsEnabled = true;       
}

看到应用一直进入ImageButton_Clicked函数却没有执行this.IsEnabled=false

【问题讨论】:

    标签: c# .net xamarin.forms


    【解决方案1】:

    实际上,应用程序正在按照您的指示进行操作。

    this.IsEnabled 正在工作,但 this 正在引用页面本身。如果你想点击禁用触发事件的按钮,那么你需要这个:

    private void ImageButton_Clicked(object sender, EventArgs e)
    {
        if (sender is Button button)
        {
            button.IsEnabled = false;
            // the rest of the logic
        }
    }
    

    在这里,我们将 sender 转换为 Xamarin.Forms.Button。如果转换成功,即如果发送者是我们的按钮,那么我们可以禁用它。

    如果您不想强制转换它或者您想在其他方法中使用按钮引用(就像您再次启用它一样),只需在 xml 中使用 Name 属性设置按钮,如下所示:

    <Button 
        x:Name="myButton"
        Clicked="ImageButton_Clicked" />
    

    然后,您可以在 ATimer_Elapsed 方法的代码隐藏中使用它,如下所示:

    private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        Device.BeginInvokeOnMainThread(() => { myButton.IsEnabled = true; });
    }
    

    编辑:在 ma​​in/UI 线程上调用IsEnabled = true 这里非常很重要,因为计时器逻辑是在后台线程上完成的。

    【讨论】:

    • 我试着按你说的命名按钮并写myButton.IsEnabled=true;,但它仍然不起作用。我之前尝试过,但结果是一样的,它是第一次禁用,之后我可以再次单击它而不会被禁用。
    • 当然可以。每次单击按钮后,您将启动一个新计时器,该计时器将在 5 秒后再次启用该按钮。这就是您的代码对其当前实现的假设。
    • private void ImageButton_Clicked(object sender, EventArgs e) { if(sender is Button button) { button.IsEnabled = false; Timer aTimer = new Timer(); aTimer.Interval = 5000; aTimer.Enabled = true; aTimer.Elapsed += ATimer_Elapsed; } } private void ATimer_Elapsed(object sender, ElapsedEventArgs e) { b.IsEnabled = true; } 这是我的代码,但它不能按我的意愿工作
    • 是的,这段代码可以工作。当你点击一个按钮时,它的作用是:1)禁用按钮; 2)启动定时器5秒; 3) 5 秒后,按钮将再次启用。如果这是您想要实现的目标,那么是的 - 这会奏效。
    • 1) 禁用按钮; 2)启动定时器5秒; 3) 5 秒后,按钮将再次启用。在这一切重新开始之后。也许我没有像你说的那样写代码,但它不起作用。它第一次完成了这项工作,然后我可以按我想要的次数多次按下按钮,它不会发生任何事情。对不起,如果我是一个假人,这是我第一次遇到这个。感谢您的帮助!
    【解决方案2】:

    试试这个代码。 我希望它有效。

        private void ImageButton_Clicked(object sender, EventArgs e)
        {
               var btn = sender as ImageButton;
               btn.IsEnabled = false;
               Device.StartTimer(TimeSpan.FromSeconds(5), () =>
               {
    
                        btn.IsEnabled = true;
                        return false;
               });
        }
    

    【讨论】:

    • 它给了我这个错误错误 CS1643 并非所有代码路径都返回 lambda 表达式中的值'Func'
    • 这不是一个好方法,因为 Device.StartTimer 需要回调 Func 如果您返回 true,则计时器将继续重复,这不是 OP 的要求。供参考:docs.microsoft.com/en-us/dotnet/api/…
    • 现在我已经返回 false,根据你的说法,它现在不再重复了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2019-10-25
    • 1970-01-01
    • 2019-05-16
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多