![](/img/trans.png)
[英]How to temporarily disable button after click in Xamarin Forms even when navigating through the app?
[英]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 不會禁用按鈕並正確更改顏色(至少對我而言):
<?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
}
<customButton:CustomButtonView Text="Your Custom Button"
Command="{Binding ClickCommand}"
IsEnabled="{Binding IsEnabled}"/>
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();
});
}
}
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.