我正在构建一个 WPF 应用程序,当您从列表中选择一个时,它会将 powerpoint 转换为 WPF 元素。我正在使用 MVVM 灯将 ViewModel 绑定到我的视图并添加 ViewModel 之间的通信。
我有两个视图:OpenLocalView 和 PresentationView。当我在 OpenLocalView 中选择一个 powerpoint 时,MVVM 灯将向 PresentationView 的 ViewModel 和 MainViewModel 发送一条消息,其中包含该 powerpoint 的路径。MainViewModel 将视图切换到 PresentationView,PresentationViewModel 执行此代码以转换 powerpoint,完成后,设置当前幻灯片,使其显示在 PresentationView 中:
public void StartPresentation(string location)
{
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Loading = true;
Task.Factory.StartNew(() =>
{
var converterFactory = new ConverterFactory();
var converter = converterFactory.CreatePowerPointConverter();
_slides = converter.Convert(location).Slides;
},
CancellationToken.None,
TaskCreationOptions.LongRunning,
scheduler).ContinueWith(x =>
{
Loading = false;
CurrentSlide = _slides.First();
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
scheduler);
}
设置 Loading 属性后,视图会使用“正在加载”消息进行更新,以使 UI 响应更快:
public Boolean Loading
{
get { return _loading; }
set
{
_loading = value;
RaisePropertyChanged("Loading");
}
}
问题是,这在我第一次加载 powerpoint 时正确执行:视图切换到 PresentationView,显示“正在加载”消息,转换完成后,消息消失并显示幻灯片。但是当我回到 OpenLocalView 并选择另一个 powerpoint 时,OpenLocalView 挂起,并在转换器完成后切换到 PresentationView,根本没有显示“正在加载”消息。
作为参考,我将添加一些更相关的代码。
这在 OpenLocalViewModel 中选择了一个 powerpoint 时执行:
private void PerformOpenPresentation(string location)
{
Messenger.Default.Send<OpenPowerPointMessage>(new OpenPowerPointMessage {Location = location});
}
MainViewModel 订阅了 messenger 并切换视图:
Messenger.Default.Register<OpenPowerPointMessage>(this,
delegate
{
if (_presentation == null) _presentation = new PresentationView();
CurrentView = _presentation;
});
PresentationViewModel 也订阅了 messenger 并执行上面显示的方法:
Messenger.Default.Register<OpenPowerPointMessage>(this, message => StartPresentation(message.Location));
那么,我做错了什么?再次,它执行一次很好,然后不再执行,尽管执行了相同的代码。