[英]The RelayCommand for enable/disable a button don't work like expected
這種情況是,我嘗試在單擊窗口表單中的按鈕時將其禁用,並且在一段時間(幾秒鍾)后應再次啟用它。
但這沒有用。 單擊按鈕后,該命令將啟用設置為false
,幾秒鍾后,該命令將其設置為true
(我測試了該命令,順序是正確的,並且再次將其設置為true
),但是該按鈕仍未啟用窗口形式。
對於這種情況,我使用RelayCommmand
。 RelayCommand
是您在Internet上找到的標准類,將在最后顯示。 為了組織命令,我編寫了一個稱為Testclass
的類:
class Testclass
{
private bool _testValueCanExecute;
public bool TestValueCanExecute
{
get { return _testValueCanExecute; }
set
{
_testValueCanExecute = value;
OnPropertyChanged();
}
}
public ICommand TestValueCommand { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public Testclass()
{
TestValueCommand = new RelayCommand(TestMethod, param => _testValueCanExecute);
TestValueCanExecute = true;
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private async void TestMethod(object obj)
{
TestValueCanExecute = false;
await Task.Delay(3000);
TestValueCanExecute = true;
}
}
在XAML文件中,我添加了一個按鈕,如下所示:
<Button x:Name="TestButton" Command="{Binding TestValueCommand}" Content="Test Button" HorizontalAlignment="Left" Margin="149,96,0,0" VerticalAlignment="Top" Width="75"/>
MainWindow
代碼如下所示:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Testclass();
}
}
因此, RelayCommand
使用TestMethod
方法將命令enable變量設置為false
,等待3秒鍾,然后將它們設置為true
。 但是,正如我在上方所述,窗口窗體上的按鈕仍未啟用。
很高興了解這里發生的事情以及如何解決此問題。
更新:我對RelayCommand
使用以下代碼:
public class RelayCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
}
RelayCommand
是您在Internet上找到的標准類...
沒有“在互聯網上找到的標准班級”這樣的東西。 實際上,“在Internet上”有幾種不同的RelayCommand
實現。
一個好的實現應包含一個引發CanExecuteChanged
事件的方法。 MvvmLight的實現具有執行此操作的RaiseCanExecuteChanged()
方法。 您需要調用此命令來“刷新”命令的狀態:
private async void TestMethod(object obj)
{
RelayCommand cmd = TestValueCommand as RelayCommand;
TestValueCanExecute = false;
cmd.RaiseCanExecuteChanged();
await Task.Delay(3000);
TestValueCanExecute = true;
cmd.RaiseCanExecuteChanged();
}
當您設置TestValueCanExecute
屬性並引發視圖模型的PropertyChanged
事件時, 不會自動引發該事件。
編輯:您的實現沒有任何RaiseCanExecuteChanged()
方法。 將一個添加到您的RelayCommand
類中,然后按上述方式調用它:
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
我強烈建議您使用現有的框架,而不是再費周折。 看看ReactiveUI ReactiveCommand
在您的情況下,它將自行完成所有工作:
TestValueCommand = ReactiveCommand.CreateFromTask(async () => await Task.Delay(500));
您將該命令綁定到xaml中的按鈕,並且該按鈕將被禁用,直到命令完成。
您可以輕松地添加另一個條件來禁用該命令,然后綁定將禁用按鈕
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.