Open lqy16 opened 1 year ago
Currently, I use IValueConverter and IsEnabled to directly bind the excutable status of the Button to the property. That works.
Hi there
In my opinion this is not a bug.
According to RelayCommand attribute - Asynchronous commands the command method should return a Task type for this.
[RelayCommand]
private async Task ChangeIndicatorAsync() { ... }
The command is then accessible in xaml as this:
Command="{Binding Path=ChangeIndicatorCommand}"
I also think you should use Dispatcher.BeginInvoke, to update the bounded Properties, when you do your work within another Task.
Here is my working example:
public partial class MainWindowViewModel : ObservableRecipient
{
public MainWindowViewModel()
{
Counter = 1;
Indicator = true;
}
[NotifyCanExecuteChangedFor(nameof(ClickCommand))]
[ObservableProperty]
public int counter;
[NotifyCanExecuteChangedFor(nameof(ClickCommand))]
[ObservableProperty]
public bool indicator;
[RelayCommand(CanExecute = nameof(Indicator))]
private void Click() => Counter++;
[RelayCommand]
private void ChangeIndicatorSync()
{
Counter = 0;
Indicator = !Indicator;
}
[RelayCommand]
private async Task ChangeIndicatorAsync()
{
var newIndicatorValue = false;
await Task.Run(() => newIndicatorValue = !Indicator);
await Task.Delay(3000);
await Dispatcher.CurrentDispatcher.BeginInvoke(() =>
{
Counter = 0;
Indicator = newIndicatorValue;
});
}
}
<Grid>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button Width="100" Height="30" Margin="10,0" Command="{Binding Path=ChangeIndicatorSyncCommand}" Content="Sync" />
<Button Width="100" Height="30" Margin="10,0" Command="{Binding Path=ChangeIndicatorCommand}" Content="Async" />
<Button Width="100" Height="30" Margin="10,0" Command="{Binding Path=ClickCommand}" Content="{Binding Counter}" />
</StackPanel>
</Grid>
best regards
It is redundant to update an observable property in Dispatcher as WPF would automatically marshal the change to UI thread no matter where the PropertyChanged
event occurs. On the other hand, the CanExecuteChanged
does not have this nice feature and I think it would be great to wrap it for parity.
Describe the bug
If a property is labeled with [ObservableProperty] and [NotifyCanExecuteChangedFor], e.g.
[NotifyCanExecuteChangedFor(nameof(ClickCommand))]
[ObservableProperty]
public bool indicator;
it should notify the property (e.g.,bool CanExecute
) which decides whetherClickCommand
is executable when it changes. WhenIndicator
is changed in Sync environment, all goes well. However, whenIndicator
is changed in Aync environment, e.g.,Task.Run(() => Indicator = false);
, it doesn't notify thatCanExecute
should change, and the executable status ofClickCommand
doesn't change.Regression
No response
Steps to reproduce
Expected behavior
when "Async" is clicked, "Test" should also become inexecutable.
Screenshots
IDE and version
VS 2022
IDE version
17.5.5
Nuget packages
Nuget package version(s)
8.2.1
Additional context
No response
Help us help you
Yes, I'd like to be assigned to work on this item