在异步方法中引发 OnPropertyChanged
Raise OnPropertyChanged in an async method
在我的 WPF 应用程序中,我的视图模型中有一个方法
- 应该运行异步
- 根据是否按下取消,将按钮的内容从 "Connect" 更改为 "Cancel" 再到 "Cancelling"。
取消本身有效,但按钮的内容未更新。
这是我的代码的摘录:
public async void Execute(object parameter)
{
if (cts == null)
{
cts = new CancellationTokenSource();
OnPropertyChanged(nameof(Name));
await ConnectDevice(self.CurrentScannedDevice, cts.Token);
cts = null;
OnPropertyChanged(nameof(Name));
}
else
{
cts.Cancel();
OnPropertyChanged(nameof(Name));
}
}
private CancellationTokenSource cts;
public string Name { get // bound to the content of the button
{
return cts == null
? "Connect Device"
: cts.IsCancellationRequested
? "Cancelling Connecting To Device"
: "Cancel Connecting To Device";
}
}
private async Task ConnectDevice(object currentScannedDevice, CancellationToken ct)
{
//...
}
XAML
<Button
HorizontalAlignment="Left"
Command="{Binding Path=ScanCommand}"
Content="{Binding Path=Name}" />
找到原因了
在 "real" 代码中,Execute
方法存在于命令 class ScanCommandImpl
中。此 ICommand class 的 属性 如下所示:
public ICommand ScanCommand => new ScanCommandImpl();
它以某种方式重新创建了 ScanCommandImpl,因此 cts 的变量在此过程中发生了变化。
从构造函数初始化它解决了问题。
在我的 WPF 应用程序中,我的视图模型中有一个方法
- 应该运行异步
- 根据是否按下取消,将按钮的内容从 "Connect" 更改为 "Cancel" 再到 "Cancelling"。
取消本身有效,但按钮的内容未更新。 这是我的代码的摘录:
public async void Execute(object parameter)
{
if (cts == null)
{
cts = new CancellationTokenSource();
OnPropertyChanged(nameof(Name));
await ConnectDevice(self.CurrentScannedDevice, cts.Token);
cts = null;
OnPropertyChanged(nameof(Name));
}
else
{
cts.Cancel();
OnPropertyChanged(nameof(Name));
}
}
private CancellationTokenSource cts;
public string Name { get // bound to the content of the button
{
return cts == null
? "Connect Device"
: cts.IsCancellationRequested
? "Cancelling Connecting To Device"
: "Cancel Connecting To Device";
}
}
private async Task ConnectDevice(object currentScannedDevice, CancellationToken ct)
{
//...
}
XAML
<Button
HorizontalAlignment="Left"
Command="{Binding Path=ScanCommand}"
Content="{Binding Path=Name}" />
找到原因了
在 "real" 代码中,Execute
方法存在于命令 class ScanCommandImpl
中。此 ICommand class 的 属性 如下所示:
public ICommand ScanCommand => new ScanCommandImpl();
它以某种方式重新创建了 ScanCommandImpl,因此 cts 的变量在此过程中发生了变化。
从构造函数初始化它解决了问题。