簡體   English   中英

用於啟用/禁用按鈕的RelayCommand與預期的不同

[英]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.

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