簡體   English   中英

單擊 Xamarin Forms 后如何暫時禁用按鈕?

[英]How to temporarily disable button after click in Xamarin Forms?

我正在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 function 但它沒有執行this.IsEnabled=false ;

試試這個代碼。 我希望它正在工作。

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

實際上,該應用程序正在執行您告訴它的操作。

this.IsEnabled正在工作,但這是引用頁面本身。 如果要單擊以禁用已觸發事件的按鈕,則需要:

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

在這里,我們將sender轉換為 Xamarin.Forms。 按鈕 如果轉換成功,這意味着如果發送者是我們的按鈕,那么我們可以禁用它。

如果您不想轉換它或者您想在另一種方法中使用按鈕引用(就像您再次啟用它一樣),只需在 xml 中使用Name屬性設置按鈕,如下所示:

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

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

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

編輯:在主/UI線程上調用IsEnabled = true非常重要,因為計時器邏輯是在后台線程上完成的。

這個問題的答案有點長,但很簡單。

  • 創建一個自定義按鈕組件,因為 XF 不會禁用按鈕並正確更改顏色(至少對我而言):

    • XAML:
<?xml version="1.0" encoding="utf-8"?>

<Button xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="LindeGctMobileApplication.Modules.CustomComponents.CustomButton.CustomButtonView"
        FontAttributes="Bold"
        TextColor="{StaticResource LightTextPrimary}"
        FontSize="20"
        TextTransform="Uppercase"
        CornerRadius="20"
        WidthRequest="200"
        HorizontalOptions="Center" />
  • 后面的代碼:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomButtonView
{
   #region constructors

   public CustomButtonView()
   {
      InitializeComponent();
      BackgroundColor = Color.Blue;

      Clicked += (_, args) =>
      {
         if (IsEnabled) Command?.Execute(args);
      };
   }

   #endregion

   #region Command

   public new static readonly BindableProperty CommandProperty = BindableProperty.Create(
            nameof(Command),
            typeof(ICommand),
            typeof(CustomButtonView));

   public new ICommand? Command
   {
      get => (ICommand)GetValue(CommandProperty);
      set => SetValue(CommandProperty, value);
   }


   #endregion
        
   #region IsEnabled

   public new static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(
            nameof(IsEnabled),
            typeof(bool),
            typeof(CustomButtonView),
            true,
            propertyChanged: (bindable, _, newValue) =>
   {
      var component = (CustomButtonView)bindable;

      if ((bool)newValue)
      {
         component.BackgroundColor = Color.Blue;
      }
      else
      {
         component.BackgroundColor = Color.Gray;
      }
   });

   public new bool IsEnabled
   {
      get => (bool)GetValue(IsEnabledProperty);

      set => SetValue(IsEnabledProperty, value);
   }

   #endregion
}
  • 在屏幕 XAML 中添加 CustomButton:
<customButton:CustomButtonView Text="Your Custom Button"
                               Command="{Binding ClickCommand}"
                               IsEnabled="{Binding IsEnabled}"/>
  • 創建以下 static class 來消除按鈕點擊,用戶可以點擊多次,該方法將計算最后一次點擊后的時間,稍后使用:
public static class CustomTaskExtension
{
   #region fields

   private static int _last;

   #endregion

   public static void Debounce(CancellationTokenSource throttleCts, double debounceTimeMs, Action action)
   {
      var current = Interlocked.Increment(ref _last);
      Task.Delay(TimeSpan.FromMilliseconds(debounceTimeMs), throttleCts.Token).ContinueWith(task =>
         {
            if (current == _last) action();
               task.Dispose();
         });
    }
}
  • 在 ViewModel 中添加以下屬性:
private bool _isEnabled;

public bool IsEnabled
{
   get => _isEnabled;
   set
   {
      OnPropertyChanged("IsEnabled");
      _isEnabled = value;
   }
}
  • 將以下命令添加到您的按鈕:
public ICommand ClickCommand => new Command(() => Click());

private void Click()
{
   // disable the button
   IsEnabled = false;
   
   // the debounce is used to enable the button after 5s of the last call of this method
   CustomTaskExtension.Debounce(new CancellationTokenSource(), 5000, () =>
   {
      IsEnabled = true;
   });
}

這就是所有的人!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM