在伍華聰的博客中,看到布局控件"WeifenLuo.WinFormsUI.Docking",發現的確是一個非常棒的開源控件,用過的人都深有體會,該控件之強大、美觀、不亞於商業控件。而且控件使用也是比較簡單的今天在這里,我想與大家一起分這一偉大的控件。有興趣的同學,可以一同探討與學習一下,否則就略過吧。
一、引用方法:
1.建立一個WinForm工程,默認生成了一個WinForm窗體。
2.引用—>添加引用—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll。
3.窗體屬性IsMdiContainer:True。
4.工具箱—>右鍵—>選擇項—>.net組件—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll—>在工具箱出現dockPanel。
5.將dockPanel拖到窗體上,設置Dock屬性,我設置的是:Fill。在這里要注意,在先增加菜單工具條,后增加dockpanel否則,會出現布局介面顯示不全的問題。
以下為具體的設計介面:
左側加入一窗體,並設計成outlookbar的樣式。它其實也是在一個停靠的窗體中的,繼承自WeifenLuo.WinFormsUI.Docking.DockContent
二、加入其它兩個控件配合介面的設計:(UtilityLibrary+ IrisSkin2)
UtilityLibrary.dll為可以產生outlookbar這樣的效果
IrisSkin2.dll為引入皮膚控件
三.設計完成后的介面如下:
四.其它部分就是代碼部分:
private string m_strConfigFile;
private DeserializeDockContent m_deserializeDockContent;
public frmMain()
{
InitializeComponent();
InitializeLeftBar();
}
private void InitializeLeftBar()
{
m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
frmTemp = this;
m_strConfigFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), " DockPanel.config ");
m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
}
private IDockContent GetContentFromPersistString( string persistString)
{
if (persistString == typeof(frmLeftBar).ToString())
{
return frmLeftBar;
}
else
{
// 可以加的其它子窗體
return null;
}
}
2.加載主窗口
private void frmMain_Load( object sender, EventArgs e)
{
globalcolor = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue( " config.xml ", " Color ", " UserColor ")));
globalcolor2 = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue( " config.xml ", " Color ", " IMColor ")));
CreditControl = Convert.ToBoolean(C_BaseInfo.GetsysConf().Tables[ 0].Rows[ 0][ " CreditControl "]);
// 設置時間和日期
tssl1.Text = " 今天日期: " + DateTime.Now.ToString( " yyyy-MM-dd ");
tssl2.Text = " 登錄時間: " + System.DateTime.Now.ToLongTimeString();
tsslLoginUser.Text = " 當前用戶: " + " " + frmLogin.C_UserInfo.SysUser;
MenuStrip ms = (MenuStrip) this.Controls[ " menuStrip1 "];
ArrayList arr = new ArrayList();
dsright = C_BaseInfo.UserRight(frmLogin.C_UserInfo);
GetMenuAllName(arr, null, 0, ms); // 調用遞歸函數
if (File.Exists(m_strConfigFile))
{
dockPanel1.LoadFromXml(m_strConfigFile, m_deserializeDockContent);
}
frmLeftBar.Show( this.dockPanel1, DockState.DockLeft);
this.dockPanel1.BackgroundImage = global::ECM.Properties.Resources.cable_16_92;
}
3.顯示子窗口
private ECM.Purchase.frmPO frmpo = null;
private void mnuPO_Click( object sender, EventArgs e)
{
if (FindFormName( " frmPO ") == null)
{
frmpo = new ECM.Purchase.frmPO( this);
frmpo.MdiParent = this;
frmpo.Show(frmMain.frmTemp.dockPanel1);
frmpo.Focus();
}
else
{
Form f = FindFormName( " frmPO ") as Form;
f.Focus();
}
}
以下為其它同學編寫有關該控件的技術文檔,供大家參考
1. DockPanel的一點點改進:
在瀏覽網上的一些技術文章發現,的確有些地方還是可以進一步改進,如當雙擊Tab時,原先是直接把當前Tab所表示的這個窗體,從主窗體的框架上分離現來,成為一個浮動的窗體。這不是我們想要的,有些同學修改源代碼,把它改成了雙擊關閉。(測試Ok)
以下鏈接為官方共享代碼的出處,大家可以利用svn下載到最新的代碼。所有的修改全部建立在源代碼基礎上的
http://sourceforge.net/projects/dockpanelsuite
雙擊關閉標簽代碼 主要是修改 DockPaneStripBase.cs 類里的protected override void WndProc(ref Message m)函數 代碼如下
在DockPaneStripBase.cs 的WndProc方法里,對於左鍵雙擊消息重新作了處理(下面注釋掉的一行是原先的寫法,它下面那行是改的):
protected override void WndProc( ref Message m)
{
if (m.Msg == ( int)Win32.Msgs.WM_LBUTTONDBLCLK)
{
base.WndProc( ref m);
int index = HitTest();
if (DockPane.DockPanel.AllowEndUserDocking && index != - 1)
{
IDockContent content = Tabs[index].Content;
// if (content.DockHandler.CheckDockState(!content.DockHandler.IsFloat) != DockState.Unknown)
// content.DockHandler.IsFloat = !content.DockHandler.IsFloat; // 這句表示窗口還原初始大小並且脫離任何停靠
if (content.DockHandler.HideOnClose)
content.DockHandler.Hide(); // 隱藏
else
content.DockHandler.Close(); // 關閉
}
return;
}
base.WndProc( ref m);
return;
}
2、很多窗體都在Tab中有個右鍵菜單,右擊的里面有關閉,所以最好繼承一下DockContent,讓其它窗體只要繼承這個就有了這個右鍵菜單,在里面加入ContextMenuStrip菜單工具並加入關閉全部關閉除此之外全部關閉三個菜單(這個我是從網上其它網友處復制出來的,未作測試)
/// 很多窗體都在Tab中有個右鍵菜單,右擊的里面有關閉,所以最好繼承一下DockContent,
/// 讓其它窗體只要繼承這個就有了這個右鍵菜單
/// </summary>
public class DockContentEx : DockContent
{
// 在標簽上點擊右鍵顯示關閉菜單
public DockContentEx( )
{
System.Windows.Forms.ContextMenuStrip cms = new System.Windows.Forms.ContextMenuStrip();
//
// tsmiClose
//
System.Windows.Forms.ToolStripMenuItem tsmiClose = new System.Windows.Forms.ToolStripMenuItem();
tsmiClose.Name = " cms ";
tsmiClose.Size = new System.Drawing.Size( 98, 22);
tsmiClose.Text = " 關閉 ";
tsmiClose.Click += new System.EventHandler( this.tsmiClose_Click);
//
// tsmiALLClose
//
System.Windows.Forms.ToolStripMenuItem tsmiALLClose = new System.Windows.Forms.ToolStripMenuItem();
tsmiALLClose.Name = " cms ";
tsmiALLClose.Size = new System.Drawing.Size( 98, 22);
tsmiALLClose.Text = " 全部關閉 ";
tsmiALLClose.Click += new System.EventHandler( this.tsmiALLClose_Click);
//
// tsmiApartFromClose
//
System.Windows.Forms.ToolStripMenuItem tsmiApartFromClose = new System.Windows.Forms.ToolStripMenuItem();
tsmiApartFromClose.Name = " cms ";
tsmiApartFromClose.Size = new System.Drawing.Size( 98, 22);
tsmiApartFromClose.Text = " 除此之外全部關閉 ";
tsmiApartFromClose.Click += new System.EventHandler( this.tsmiApartFromClose_Click);
//
// tsmiClose
//
cms.Items.AddRange( new System.Windows.Forms.ToolStripItem[] {
tsmiClose,tsmiApartFromClose,tsmiALLClose});
cms.Name = " tsmiClose ";
cms.Size = new System.Drawing.Size( 99, 26);
this.TabPageContextMenuStrip = cms;
}
private void tsmiClose_Click( object sender, EventArgs e)
{
this.Close();
}
private void tsmiALLClose_Click( object sender, EventArgs e)
{
DockContentCollection contents = DockPanel.Contents;
int num = 0;
while (num < contents.Count)
{
if (contents[num].DockHandler.DockState == DockState.Document)
{
contents[num].DockHandler.Hide();
}
else
{
num++;
}
}
}
private void tsmiApartFromClose_Click( object sender, EventArgs e)
{
DockContentCollection contents = DockPanel.Contents;
int num = 0;
while (num < contents.Count)
{
if (contents[num].DockHandler.DockState == DockState.Document && DockPanel.ActiveContent != contents[num])
{
contents[num].DockHandler.Hide();
}
else
{
num++;
}
}
}
}
以下為其它同學編寫有關該控件的技術文檔,供大家參考
http://www.cnblogs.com/luomingui/archive/2013/09/19/3329763.html
http://blog.csdn.net/dqvega/article/details/7594923
以下是修改后的dll供大家下載:
http://download.csdn.net/detail/shilei07068124/4506742
在伍華聰的博客中,看到布局控件"WeifenLuo.WinFormsUI.Docking",發現的確是一個非常棒的開源控件,用過的人都深有體會,該控件之強大、美觀、不亞於商業控件。而且控件使用也是比較簡單的今天在這里,我想與大家一起分這一偉大的控件。有興趣的同學,可以一同探討與學習一下,否則就略過吧。
一、引用方法:
1.建立一個WinForm工程,默認生成了一個WinForm窗體。
2.引用—>添加引用—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll。
3.窗體屬性IsMdiContainer:True。
4.工具箱—>右鍵—>選擇項—>.net組件—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll—>在工具箱出現dockPanel。
5.將dockPanel拖到窗體上,設置Dock屬性,我設置的是:Fill。在這里要注意,在先增加菜單工具條,后增加dockpanel否則,會出現布局介面顯示不全的問題。
以下為具體的設計介面:
左側加入一窗體,並設計成outlookbar的樣式。它其實也是在一個停靠的窗體中的,繼承自WeifenLuo.WinFormsUI.Docking.DockContent
二、加入其它兩個控件配合介面的設計:(UtilityLibrary+ IrisSkin2)
UtilityLibrary.dll為可以產生outlookbar這樣的效果
IrisSkin2.dll為引入皮膚控件
三.設計完成后的介面如下:
四.其它部分就是代碼部分:
private string m_strConfigFile;
private DeserializeDockContent m_deserializeDockContent;
public frmMain()
{
InitializeComponent();
InitializeLeftBar();
}
private void InitializeLeftBar()
{
m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
frmTemp = this;
m_strConfigFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), " DockPanel.config ");
m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
}
private IDockContent GetContentFromPersistString( string persistString)
{
if (persistString == typeof(frmLeftBar).ToString())
{
return frmLeftBar;
}
else
{
// 可以加的其它子窗體
return null;
}
}
2.加載主窗口
private void frmMain_Load( object sender, EventArgs e)
{
globalcolor = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue( " config.xml ", " Color ", " UserColor ")));
globalcolor2 = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue( " config.xml ", " Color ", " IMColor ")));
CreditControl = Convert.ToBoolean(C_BaseInfo.GetsysConf().Tables[ 0].Rows[ 0][ " CreditControl "]);
// 設置時間和日期
tssl1.Text = " 今天日期: " + DateTime.Now.ToString( " yyyy-MM-dd ");
tssl2.Text = " 登錄時間: " + System.DateTime.Now.ToLongTimeString();
tsslLoginUser.Text = " 當前用戶: " + " " + frmLogin.C_UserInfo.SysUser;
MenuStrip ms = (MenuStrip) this.Controls[ " menuStrip1 "];
ArrayList arr = new ArrayList();
dsright = C_BaseInfo.UserRight(frmLogin.C_UserInfo);
GetMenuAllName(arr, null, 0, ms); // 調用遞歸函數
if (File.Exists(m_strConfigFile))
{
dockPanel1.LoadFromXml(m_strConfigFile, m_deserializeDockContent);
}
frmLeftBar.Show( this.dockPanel1, DockState.DockLeft);
this.dockPanel1.BackgroundImage = global::ECM.Properties.Resources.cable_16_92;
}
3.顯示子窗口
private ECM.Purchase.frmPO frmpo = null;
private void mnuPO_Click( object sender, EventArgs e)
{
if (FindFormName( " frmPO ") == null)
{
frmpo = new ECM.Purchase.frmPO( this);
frmpo.MdiParent = this;
frmpo.Show(frmMain.frmTemp.dockPanel1);
frmpo.Focus();
}
else
{
Form f = FindFormName( " frmPO ") as Form;
f.Focus();
}
}
以下為其它同學編寫有關該控件的技術文檔,供大家參考