11

我需要一些帮助来使用 prism 框架覆盖视图。它比这更复杂一些,所以让我解释一下。我也可能会过度思考:D

我有外壳(wpf 窗口),并且在一个模块中有 2 个视图(A 和 B - 两个用户控件)。当外壳加载时,它会加载视图 A。在视图 A 上,我有一个按钮可以“弹出”视图 B 以供某些用户输入。所以很自然地我会想到某种模式窗口/控件,甚至可能是一个弹出窗口。但是我面临的弹出窗口的问题是,当我移动外壳时,弹出窗口保持固定并且它不会阻止视图 A 中的事件。我尝试禁用视图 A 以停止触发事件,并且我也尝试使用让视图 B 随外壳移动。只有画布有效,但我现在需要一种方法来阻止它。无论如何我可以用棱镜将一个视图覆盖在另一个视图之上吗?或者其他人如何使用 prism 和 wpf 创建模态弹出窗口?任何建议或指针将不胜感激。

4

2 回答 2

15

如果您想使用没有额外窗口的嵌入式对话框,您可以使用 Prism 的 RegionManager 来实现概述的行为。诀窍是将弹出区域与视觉树中的主要区域平行放置:

<Grid>
   <ContentControl cal:RegionManager.RegionName="MainRegion" IsEnabled={Binding IsNoPopUpActive} />
   <ContentControl cal:RegionManager.RegionName="PopUpRegion"/>
</Grid>

现在使用 RegionManager 将视图“A”放入“MainRegion”。创建一个类似于 IPopUpDialogController 的控制器类。它应该负责按需将您的视图“B”(或应用程序中的任何其他 PopUpView)放入“PopUpRegion”。此外,它应该控制一个标志,指示启用或禁用底层“MainRegion”。这样,在弹出窗口关闭之前,用户将无法使用视图“A”中的控件。

这甚至可以通过在将帧推送到 Dispatcher 之前使用 ComponentDispatcher.PushModal() 以模态方式完成。但是,我建议避免使用模态对话框。


更新:根据评论中的要求,可以在后备视图模型中实现 IsNoPopUpActive。在那里,您可以将其链接到 RegionManager 的弹出区域的视图集合:

public bool IsNoPopUpActive 
{ 
    get { return _regionManager.Regions["PopUpRegion"].Views.Count() == 0; }
}

请记住在修改视图集合(添加/删除弹出窗口)后立即触发 PropertyChanged 事件。

仅供参考:现在我避免在后台禁用控件,而是插入一个透明面板。这样可以避免单击背景控件。但是,这不处理键盘输入(制表符到控件)。要修复键盘输入,您需要确保键盘焦点被困在弹出窗口中(关于 WPF 焦点概念的 MSDN)。

将以下焦点属性添加到弹出区域应该可以解决问题:

KeyboardNavigation.DirectionalNavigation="None"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.TabNavigation="Cycle"
KeyboardNavigation.TabIndex="-1"
于 2010-03-19T15:29:34.040 回答
2

如果您将 WPF + MVVM 与 Prism 一起使用,您可以查看此消息视图覆盖控制器。这种方法的好处是您可以使用模拟覆盖控制器在您的视图模型上编写单元测试,并让模拟控制器返回用户将在覆盖中选择的结果。

你可以在这里找到它:http: //presentationlayer.wordpress.com/2011/05/24/wpf-overlay-message-view-controller/

希望这可以帮助

于 2011-05-26T17:08:36.660 回答