WPF和棱镜视图叠加

时间:2010-03-19 13:09:31

标签: c# wpf modal-dialog prism-2

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

我有shell(wpf窗口),我在模块中有2个视图(A& B - 两个用户控件)。 当shell加载时,它加载视图A.在视图A上我有一个“弹出”视图B的按钮 对于一些用户输入。所以我自然会想到某种模态窗口/控件,甚至可能是一个弹出窗口。然而我面对弹出窗口的问题是,当我移动shell时,弹出窗口仍然是固定的,它不会阻止视图A中的事件。我已经尝试禁用视图A来停止被触发的事件,我也尝试使用一个来获取视图B随shell移动。只有画布可以工作,但我现在需要一种方法来阻止它'。无论如何,我可以用棱镜将视图覆盖在另一个视图的顶部吗?或者其他人如何使用棱镜和放大器创建模态弹出窗口WPF?任何建议或指示将不胜感激。

2 个答案:

答案 0 :(得分:14)

如果要在没有额外窗口的情况下使用嵌入式对话框,可以使用Prism的RegionManager来实现概述的行为。诀窍是将PopUp区域与可视树中的主区域平行:

<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的弹出区域的View集合:

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

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

仅供参考:现在我避免在后台禁用控件,而是插入透明面板。这可以避免单击背景控件。但是,这不处理键盘输入(标签到控件)。要修复键盘输入,您需要确保弹出窗口(MSDN on WPF Focus concepts)中的键盘焦点被捕获

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

KeyboardNavigation.DirectionalNavigation="None"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.TabNavigation="Cycle"
KeyboardNavigation.TabIndex="-1"

答案 1 :(得分:2)

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

您可以在此处找到它:http://presentationlayer.wordpress.com/2011/05/24/wpf-overlay-message-view-controller/

希望这有帮助