Silverlight 中的(扩展)模态窗口
对文章 "Silverlight 中的模式窗口" 中提交的代码的扩展。 此扩展将托管控件包装在窗口框架中,该框架提供各种模式功能。

引言
Knowm Ercy 的文章 Silverlight 中的模式窗口 提供了一种很好的方式来显示 Silverlight UserControl
,使其看起来和感觉起来像模式窗口。在 ProModel, Inc.,我们对这种功能(目前在 Silverlight 中原生不可用)及其在基于 Silverlight 的应用程序中的使用非常感兴趣。以 Knowm 的文章为起点,我们组合了一个扩展,将托管的 UserControl
“包装”在窗口框架中,该框架提供了调整大小、移动、最大化以及传统模式 Windows 窗体所具有的许多其他功能。
此代码按“原样”提供,我们意识到可以并且应该进行许多改进。但是,考虑到我们内部的时间限制以及目前缺乏类似的模式解决方案(无论如何,免费的解决方案),我们决定提供此源代码,供任何愿意接受挑战的人进行改进。
背景
尽管我们对原始架构进行了一些修改,但它基本上与我们发现的相同,只是进行了扩展,因此阅读 Knowm Ercy 的文章 Silverlight 中的模式窗口 应该有助于理解代码。
有两个类协同工作以提供基本的模式显示
Modal
一个简单的类,包含托管“模式”窗体的弹出控件,并提供基本的显示/隐藏功能。
ModalHost
一个类,用于托管要以模式方式显示的
UserControl
。此类呈现一个“背景画布”,该画布覆盖整个浏览器窗口并阻止与托管控件之外的任何内容进行交互,从而给人一种托管控件是模式控件的印象。此外,ModalHost
类还提供基本的鼠标拖动功能,以便如果在其表面上发生鼠标拖动,则可以移动托管控件。
我们的库(ModalControl
,WindowedModalControl
)中包含的两个模式显示类中的每一个都包含每个类的实例。对于 ModalControl
,使用简单的基类(与 Knowm 提供的项目一样)。对于 WindowedModalControl
,每个类都派生出来以提供扩展的功能。
以下是派生类中提供的功能的摘要
WindowedModal
(派生自Modal
)在此子类中所做的全部工作是对设置
Modal
类中的ModalHost
实例的方法的简单覆盖。 这使我们可以插入我们自定义的ModalHost
(WindowedModalHost
)。internal class WindowedModal : Modal { #region Method Declarations protected override void SetHost(IModal ctrl, bool useCanvasPainting) { _host = new WindowedModalHost(ctrl, useCanvasPainting); } #endregion }
WindowsModalHost
(派生自ModalHost
)此类覆盖了一些基本的
ModalHost
行为/添加了一些简单的功能- 提供
RestoreState
属性,该属性跟踪WindowedModalControl
是否已最大化。 - 覆盖
CenterWindow()
方法,以便考虑RestoreState
。 - 覆盖鼠标事件以防止基类采取任何操作。
public override void CentreWindow() { double dblX = 0.0, dblY = 0.0; UserControl modal = _modal as UserControl; if (RestoreState == RestoreState.Unmaximized) { // width if (_modal != null && !double.IsNaN (WindowHelpers.GetControlSize(modal).Width) && !double.IsNaN(Application.Current.Host.Content.ActualWidth)) { dblX = ((Application.Current.Host.Content.ActualWidth - WindowHelpers.GetControlSize(modal).Width) / 2); modal.SetValue(Canvas.LeftProperty, dblX); } // height if (_modal != null && !double.IsNaN (WindowHelpers.GetControlSize(modal).Height) && !double.IsNaN(Application.Current.Host.Content.ActualHeight)) { dblY = ((Application.Current.Host.Content.ActualHeight - WindowHelpers.GetControlSize(modal).Height) / 2); modal.SetValue(Canvas.TopProperty, dblY); } } protected override void OnMouseLeftButtonDown (object sender, MouseButtonEventArgs e) { // prevent the base class from taking action } protected override void OnMouseMove(object sender, MouseEventArgs e) { // prevent the base class from taking action }
- 提供
WindowedModalControl
类为 Known 的原始工作提供了主要的函数扩展。 这包括
- 管理托管的
UserControl
在窗口框架内的放置 - 支持最大化/还原
- 支持将窗口显示为可调整大小和不可调整大小
- 带有图像和自动截断文本标题的标题栏
- 内置的“确定”、“取消”、“应用”按钮支持
- 自动调整托管的
UserControl
的大小 - 使用自定义画笔用于窗体标题、背景和文本
Using the Code
只需在 WindowedModalControl
中托管您的 UserControl
即可,如下所示
public void ShowWindowedModal(DialogClose callback, Panel panel)
{
bool useCanvasPainting = true; // whether of not the non-modal space
// is darkened partially
WindowedModalControl wmc = new WindowedModalControl
(callback, MsgBoxButtons.OKCancelApply);
TestUserControl tc = new TestUserControl();
wmc.HostedControl = tc;
wmc.ShowModal(panel, useCanvasPainting);
}
此示例使用了一些更高级的功能
public void ShowWindowedModal(DialogClose callback, Panel panel)
{
bool useCanvasPainting = true; // whether of not the non-modal space
// is darkened partially
WindowedModalControl wmc = new WindowedModalControl
(callback, MsgBoxButtons.OKCancelApply);
TestUserControl tc = new TestUserControl();
wmc.TitleBarBrush = Resources["ModalHeaderBrush1"] as Brush;
wmc.FormBackgroundBrush = Resources["ModalBrush1"] as Brush;
wmc.TitleImage = _titleImage;
wmc.HostedControl = tc;
wmc.ShowModal(panel, useCanvasPainting);
wmc.AllowResizing = true;
wmc.AllowMaximize = true;
wmc.TitleBarText = "It's a Working Title...and it truncates if need be";
}
提供的源代码带有一个演示应用程序,其中包含源代码示例以及运行时示例。 还包括一个已编译的帮助文件。
特别感谢
感谢 Knowm Ercy 为他的文章所做的工作。