【发布时间】:2018-06-18 07:20:59
【问题描述】:
我正在使用 Extended WPF Toolkit 和 MVVM Light 库。
我想实现 WPF 工具包繁忙指示器并定期通知用户一些信息(与视图模型中的 BusyMessage 属性绑定)。
但是,当单击“开始”按钮时,忙碌指示器(IsBusy 绑定到 viewmodel 中的 IsBusy 属性)不显示。我做错了什么? 奇怪的是,当在视图模型的构造函数中将 IsBusy 设置为 true 时,它会起作用。
App.xaml
public partial class App : Application
{
public App()
{
DispatcherHelper.Initialize();
}
}
窗口
<Window xmlns:xctk='http://schemas.xceed.com/wpf/xaml/toolkit'
DataContext='{Binding Main, Source={StaticResource Locator}}'>
<StackPanel>
<xctk:BusyIndicator IsBusy='{Binding IsBusy}'>
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<StackPanel Margin='4'>
<TextBlock Text='{Binding DataContext.BusyMessage, RelativeSource={RelativeSource AncestorType={x:Type Window}}}' />
</StackPanel>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
<Button Content='Start ...'
Command='{Binding StartCommand}'
HorizontalAlignment='Center'
VerticalAlignment='Center' />
</xctk:BusyIndicator>
视图模型
public class MainViewModel : ViewModelBase
{
private string _busyMessage;
public string BusyMessage
{
get { return _busyMessage; }
set
{
if (_busyMessage != value)
{
_busyMessage = value;
RaisePropertyChanged(nameof(_busyMessage));
}
}
}
private bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set {
if (_isBusy != value)
{
_isBusy = value;
RaisePropertyChanged(nameof(_isBusy));
}
}
}
public RelayCommand StartCommand
{
get { return new RelayCommand(() => StartExecute()); }
}
private async void StartExecute()
{
IsBusy = true;
await Task.Run(() =>
{
//update UI from worker thread
DispatcherHelper.CheckBeginInvokeOnUI(() => BusyMessage = "Work 1 Done");
Thread.Sleep(1000);
//update UI from worker thread
DispatcherHelper.CheckBeginInvokeOnUI(() => BusyMessage = "Work 2 Done");
});
IsBusy = false;
}
public MainViewModel()
{
//Works when boolean is set to 'true' in constructor
//IsBusy = true;
}
}
【问题讨论】:
-
根据经验,不要在事件处理程序之外使用 async void;返回一个任务,以便可以正确等待该方法。见stackoverflow.com/questions/12144077/…
-
@AlexPaven 更好的代码应该是 public RelayCommand StartCommand { get { return new RelayCommand(async() => await StartExecute()); } }。对吗?
-
async lambdas 有自己的缺陷,应该首先仔细研究(在某些方面它们相当于 async void)。我更喜欢创建一个单独的具有更好异步支持的 RelayCommand。见stackoverflow.com/questions/32591462/… - 我早上没有喝咖啡,所以我可能会混淆。
标签: c# wpf mvvm xceed-plus-edition