棱镜区域切换与容器实例同步



我正在使用具有(棱镜)区域"MainViewRegion"的MainWindow在WPF中工作。这将基于用户所需的视图进行切换,当它这样做时,MainWindow 会调整大小以对齐到嵌入视图的新尺寸。

我有一些代码可以在区域切换后保持窗口在桌面上完全可见。代码如下:

private void WindowModeChange(string uri)            
{
IRegion mviewRegion = regionManager.Regions[RegionNames.MainViewRegion];
if (mviewRegion == null) return;
regionManager.RequestNavigate(mviewRegion.Name, new Uri(uri, UriKind.Relative));
//Get the MainWindow instance from the container
var uc = container.Resolve<MainWindow>(InstanceNames.MainWindowView);
//Make sure the entire window is visible onscreen
ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(uc);
}

问题是"uc"变量将始终等于区域更改之前的 MainWindow 参数。"uc"总是比我想要的落后一步,所以"对齐"代码总是关闭的。

我错过了什么?

通常,当您有一段代码在某个事件上执行时,并且您需要确保 UI 已经在某种程度上响应了该事件,最好的办法是使用Dispatcher来延迟执行。从您提供的代码来看,UI 更改是由regionManager.RequestNavigate调用触发的。现在我不能指出你一个文档来说明这一点,但我从经验中知道框架将异步处理这个请求,即在由这个请求引起的所有工作之前,控件将返回到你的方法(允许它继续)(因此你的问题)。这是(据我所知)通过使用上述Dispatcher框架在内部完成的。

根据您需要框架处理触发更改的程度,您应该使用适当的DispatcherPriority枚举值来确保在执行代码后完成某些操作。根据您的问题,我认为DispatcherPriority.Loaded是一个不错的选择(从文档中,调度程序将在呈现 UI 后执行此类代码(这对您来说至关重要的条件),但在处理任何用户输入之前)。我个人倾向于最大化优先级,直到它停止工作(可能避免由用户输入等引起的一些意外行为)。

因此,对代码的这种修改应该足以实现您的目标:

var uc = container.Resolve<MainWindow>(InstanceNames.MainWindowView);
uc.Dispatcher.InvokeAsync(() =>
ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(uc),
DispatcherPriority.Loaded);

现在我注意到您最终选择了Dispatcher.Invoke而不是Dispatcher.InvokeAsync- 我想在您的情况下没关系,因为这是您方法中的最后一条指令,但通常安全的方法是使用Dispatcher.InvokeAsync(我个人经历过Dispatcher.Invoke没有切芥末的情况)。

感谢Grx70在我的问题的评论中,他给了我解决方案。该方法的主体现在为:

IRegion mviewRegion = regionManager.Regions[RegionNames.MainViewRegion];
if (mviewRegion == null) return;

mviewRegion.RequestNavigate(new Uri(uri, UriKind.Relative), (x =>
{
var uc = container.Resolve<MainWindow>(InstanceNames.MainWindowView);
uc.Dispatcher.Invoke(() => ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(uc), DispatcherPriority.Loaded);
}));

我不确定为什么我必须在 RequestNavigate() 的回调参数中调用调度程序,但没有它它就无法工作。

相关内容

  • 没有找到相关文章

最新更新