我有一个WPF / MVVM应用程序,它由一个窗口有几个按钮。
每个按钮的触发到外部装置的呼叫(一个USB导弹发射 ),它需要几秒钟。
当设备运行时,GUI被冻结。
( 这是正常的 ,因为应用程序的唯一目的就是调用USB设备,并在设备移动你不能做别的呢!)
这是一个有点难看的唯一的事情是,冷冻GUI仍接受额外的点击,而设备在移动。
当设备依然继续和我同一个按钮上点击第二次时,设备会立即重新开始,一旦第一个“运行”完成移动。
所以我想在GUI尽快禁用所有的按钮作为一个按钮被点击,并再次启用它们时按钮的命令已经完成运行。
我已经找到了一个解决方案,看起来MVVM-一致。
(至少对我来说...请注意,我仍然是一个WPF / MVVM初学者!)
问题是,这种解决方案不工作(如:按钮没有被禁用)当我打电话,与USB设备通信的外部库。
但实际的代码来禁用GUI是正确的,因为它的工作,当我更换由外部库调用MessageBox.Show()
我已经构建了(重现问题的最小工作示例这里完整的演示项目 ):
这是视图:
<Window x:Class="WpfDatabindingQuestion.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<Button Content="MessageBox" Command="{Binding MessageCommand}" Height="50"></Button>
<Button Content="Simulate external device" Command="{Binding DeviceCommand}" Height="50" Margin="0 10"></Button>
</StackPanel>
</Grid>
</Window>
......这是(使用视图模型RelayCommand
从约什-史密斯的MSDN文章 ):
using System.Threading;
using System.Windows;
using System.Windows.Input;
namespace WpfDatabindingQuestion
{
public class MainWindowViewModel
{
private bool disableGui;
public ICommand MessageCommand
{
get
{
return new RelayCommand(this.ShowMessage, this.IsGuiEnabled);
}
}
public ICommand DeviceCommand
{
get
{
return new RelayCommand(this.CallExternalDevice, this.IsGuiEnabled);
}
}
// here, the buttons are disabled while the MessageBox is open
private void ShowMessage(object obj)
{
this.disableGui = true;
MessageBox.Show("test");
this.disableGui = false;
}
// here, the buttons are NOT disabled while the app pauses
private void CallExternalDevice(object obj)
{
this.disableGui = true;
// simulate call to external device (USB missile launcher),
// which takes a few seconds and pauses the app
Thread.Sleep(3000);
this.disableGui = false;
}
private bool IsGuiEnabled(object obj)
{
return !this.disableGui;
}
}
}
我怀疑打开一个MessageBox
触发一些东西时,我只是调用外部库, 不会发生的背景。
但我不能够找到一个解决方案。
我也曾尝试:
- 实施
INotifyPropertyChanged
(和制作this.disableGui
的属性,并调用OnPropertyChanged
时改变它) - 调用
CommandManager.InvalidateRequerySuggested()
所有的地方
(我发现几个答案类似的问题在这里SO)
有什么建议?