首先声明:在此感谢给我提供思路和灵感。本文的形成也多有借鉴,再次表示感谢!在此记录一下Dockpanel框架的搭建过程(主要步骤),以及需要注意的几点。
1. 下载Dockpanel suite。
。
2. 构建主窗体(父窗体):FrmMain。
① 新建工程:VehicleMonitorSystem;
② 将WeifenLuo.WinFormsUI.Docking.dll放置当前工程文件夹下,建议:\bin\Debug\WeifenLuo.WinFormsUI.Docking.dll;
③ 在当前工程中,通过解决方案资源管理器添加引用WeifenLuo.WinFormsUI.Docking.dll到当前工程;
④ 添加主窗体:FrmMain,并设置主窗体 IsMdiContainer = true;
⑤ 在主窗体中添加dockpanel控件:DockPanelOfFrmMain,并设置dockpanel 的documentstyle :dockPanel.DocumentStyle = DocumentStyle.DockingMdi;
后台代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using WeifenLuo.WinFormsUI.Docking; namespace VehicleMonitorSystem { public partial class FrmMain : Form { #region 字段 private string m_DockPath = string.Empty; #endregion #region 构造函数 public FrmMain() { InitializeComponent(); } #endregion #region 主窗体加载 private void FrmMain_Load(object sender, EventArgs e) { this.DockPanelOfFrmMain.DocumentStyle = DocumentStyle.DockingMdi; this.m_DockPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "DockPanel.config"); this.InitDockPanel(); this.StatusBarOfFrmMain.Items.Add("就绪"); } #endregion #region DockPanel初始化与配置保存 #region 按照配置文件初始化Dockpanel private void InitDockPanel() { try { //根据配置文件动态加载浮动窗体 this.DockPanelOfFrmMain.LoadFromXml(this.m_DockPath, delegate(string persistString) { //功能窗体 if (persistString == typeof(FrmFunction).ToString()) { return FrmFunction.GetInstance(); } //主框架之外的窗体不显示 return null; }); } catch (Exception) { //配置文件不存在或配置文件有问题时 按系统默认规则加载子窗体 FrmFunction.GetInstance().Show(this.DockPanelOfFrmMain, AppConfig.ms_FrmFunction); } } #endregion #region 关闭窗体时保存界面。为了下次打开程序时,浮动窗体的显示位置和关闭时一致,可以在主窗体的frmMain_FormClosing事件中调用:dockPanel.SaveAsXml(this.m_DockPath) private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) { try { DockPanelOfFrmMain.SaveAsXml(this.m_DockPath); } catch (Exception ex) { MessageBox.Show("保存Dockpanel配置文件失败," + ex.Message); return; } } #endregion #region 退出 private void 退出EToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } #endregion #region 关于 private void 关于AToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show(" DockPanel Suite V2.1.3364.29178 \n\n VehicleMonitorSystem V1.0.0 \n\n Created by 张月华 \n\n E-mail:yichangzyh@163.com \n\n Date:2011-10-10", "车辆监控系统"); } #endregion #endregion } }
3. 构建需要浮动显示的窗体:FrmFunction。
① 在当前工程中添加窗体:FrmFunction;(注意:浮动窗体和标签窗体需要继承自DockContent);
② 为了保证在关闭某一浮动窗体之后,再打开时能够在原位置显示,要对浮动窗体处理,处理窗体的DockstateChanged事件,标签窗体dock位置改变,记录到公共类;
后台代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; namespace VehicleMonitorSystem { public partial class FrmFunction : DockContent // 浮动窗体和标签窗体需要继承自DockContent { #region 字段 private static FrmFunction Instance; #endregion #region 构造函数 public FrmFunction() { InitializeComponent(); } #endregion #region 静态实例初始化函数 public static FrmFunction GetInstance() { if (Instance == null) { Instance = new FrmFunction(); } return Instance; } #endregion #region 为了保证在关闭某一浮动窗体之后,再打开时能够在原位置显示,要对浮动窗体处理,处理窗体的DockstateChanged事件,标签窗体dock位置改变,记录到公共类 private void FrmFunction_DockStateChanged(object sender, EventArgs e) { //关闭时(dockstate为unknown) 不把dockstate保存 if (Instance != null) { if (this.DockState == DockState.Unknown || this.DockState == DockState.Hidden) { return; } AppConfig.ms_FrmFunction = this.DockState; } } #endregion #region 关闭事件 private void FrmFunction_FormClosed(object sender, FormClosedEventArgs e) { Instance = null; // 否则下次打开时报错,提示“无法访问已释放对象” } #endregion } }
4. 让窗体FrmFunction浮动起来。
① 在主窗体FrmMain中添加菜单栏(或者按钮):视图->功能窗;
② 双击菜单对应选项,添加代码如下:
#region 显示功能窗 private void 功能窗ToolStripMenuItem_Click(object sender, EventArgs e) { this.ShowFrmFunction(); } private void ShowFrmFunction() { FrmFunction frmFun = FrmFunction.GetInstance(); frmFun.Show(this.DockPanelOfFrmMain, AppConfig.ms_FrmFunction); this.StatusBarOfFrmMain.Items[0].Text = frmFun.Text; } #endregion
5. 在当前工程中添加类AppConfig。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using WeifenLuo.WinFormsUI.Docking; namespace VehicleMonitorSystem { class AppConfig { #region 字段 public static DockState ms_FrmFunction = DockState.DockLeft; // 功能窗体,左端停靠 #endregion } }
值得注意的几点:
A.
Dockpanel suite 是基于配置文件的,其配置文件Dockpanel.config可以放置到指定的位置。在主窗体的load 事件中要做加载配置文件的工作。需要执行配置文件的路径,并使用dockpanel 的LoadFromXml方法加载需要显示的浮动窗体,在initDockpanel 中自定义 装载的哪些浮动窗体。
主窗体的load事件:
private void FrmMain_Load(object sender, EventArgs e) { ... this.m_DockPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "DockPanel.config"); this.InitDockPanel(); ... }
InitDockPanel方法:
#region 按照配置文件初始化Dockpanel private void InitDockPanel() { try { //根据配置文件动态加载浮动窗体 this.DockPanelOfFrmMain.LoadFromXml(this.m_DockPath, delegate(string persistString) { //功能窗体 if (persistString == typeof(FrmFunction).ToString()) { return FrmFunction.GetInstance(); } //主框架之外的窗体不显示 return null; }); } catch (Exception) { // 配置文件不存在或配置文件有问题时 按系统默认规则加载子窗体 // 注:在此加入的特殊处理,来改进Dockpanel 的加载,如果dockpanel.config不存在(不小心删除了),可以按照Appconfig中预定义的dockstate显示。 FrmFunction.GetInstance().Show(this.DockPanelOfFrmMain, AppConfig.ms_FrmFunction); } } #endregion
B.
浮动窗体使用:frmServer.Show(this.dockPanel, dockstate);
标签窗体使用:
dummyDoc.Show(dockPanel);
C.
为了下次打开程序时,浮动窗体的显示位置和关闭时一致,可以在主窗体的frmMain_FormClosing事件中调用:dockPanel.SaveAsXml(this.m_DockPath):
#region 关闭窗体时保存界面。为了下次打开程序时,浮动窗体的显示位置和关闭时一致,可以在主窗体的frmMain_FormClosing事件中调用:dockPanel.SaveAsXml(this.m_DockPath) private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) { try { DockPanelOfFrmMain.SaveAsXml(this.m_DockPath); } catch (Exception ex) { MessageBox.Show("保存Dockpanel配置文件失败," + ex.Message); return; } } #endregion
以上几点是搭建基于dockpanel 浮动和多标签窗体系统的主要步骤