最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在winform下實現(xiàn)左右布局多窗口界面的方法

 更新時間:2016年02月29日 09:48:25   作者:夢在旅途  
在web頁面上我們可以通過frameset,iframe嵌套框架很容易實現(xiàn)各種導航+內(nèi)容的布局界面,而在winform、WPF中實現(xiàn)其實也很容易,通過本文給大家介紹在winform下實現(xiàn)左右布局多窗口界面的方法,本文介紹的非常詳細,對winform布局相關(guān)知識感興趣的朋友一起學習吧

在web頁面上我們可以通過frameset,iframe嵌套框架很容易實現(xiàn)各種導航+內(nèi)容的布局界面,而在winform、WPF中實現(xiàn)其實也很容易,我這里就分享一個:在winform下實現(xiàn)左右布局多窗口界面。

我這里說的多窗口是指一個父窗口包含多個子窗口,在winform中實現(xiàn)這種效果很簡單,即將某個窗口的IsMdiContainer設(shè)為true,然后將其它子窗口的MdiParent設(shè)為其父窗口對象即可,這樣就完成了一個多窗口界面,效果如下:


點擊NEW新打開一個窗口,其效果如下:


請看我上圖紅色標注的地方,Windows菜單項下面顯示的是當前所有已打開的子窗口,點擊某個菜單,即可快速切換到其它窗口,若關(guān)閉某個子窗口,與之相對應(yīng)的菜單項也會自動被移除,實現(xiàn)這個功能也很簡單,只需要將菜單的MdiWindowListItem屬性設(shè)為需要顯示活動窗口列表的菜單項即可,如:this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;

上述示例完整的實現(xiàn)代碼如下:

public partial class FormMdi : Form
{
private int formCount = 0;
public FormMdi()
{
InitializeComponent();
this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowChildForm<FormChild>();
}
private void ShowChildForm<TForm>() where TForm : Form, new()
{
TForm childForm = new TForm();
childForm.Name = "frm" + Guid.NewGuid().ToString("N");
childForm.Text = string.Format("Child Form -{0}", ++formCount);
childForm.MdiParent = this;
childForm.WindowState = FormWindowState.Maximized;
childForm.Show();
}
}

相信實現(xiàn)上面這部份功能一般用過winform的人都會操作,我這里就當是復(fù)習順便給新手一個參考,同時也為下面要實現(xiàn)的左右布局功能做一個鋪墊吧。

要實現(xiàn)左右布局,并且能夠支持可動態(tài)調(diào)整左右占比的功能,非SplitContainer控件莫屬了,如果不了解該控件用法請自行在網(wǎng)上查找相關(guān)資料,我這里就不作說明,如果要顯示W(wǎng)INDOWS已打開的子窗口情況,同樣也需要用到MenuStrip控件,

最終設(shè)計的主窗口(FormMain)效果如下:


我這里因為只是演示,所以菜單控件上我只添加了兩個菜單項,分別為:WINDOWS,用于顯示W(wǎng)INDOWS已打開的子窗口列表,NEW,用于打開一個子窗口;SplitContainer控件全部采用默認的,沒有放置任何控件在其中,如果用在正式系統(tǒng)中,一般左邊Panel1中會放置一個樹形菜單,右邊Panel2中保持空即可,因為這個是用來作為子窗口的容器。

控件層次結(jié)構(gòu)如下圖示:


界面設(shè)計好了,下面就實現(xiàn)最重要的兩個功能。

第一個功能:在右邊Panel2中顯示子窗口,實現(xiàn)代碼如下:

public FormMain()
{
this.IsMdiContainer = true;
}
private void ShowChildForm<TForm>() where TForm : Form, new()
{
TForm childForm = new TForm();
childForm.Name = "frm" + Guid.NewGuid().ToString("N");
childForm.Text = string.Format("Child Form -{0}", ++formCount);
childForm.MdiParent = this;
childForm.Parent = splitContainer1.Panel2;
childForm.WindowState = FormWindowState.Maximized;
childForm.Show();
}

簡要說明:

1.在窗口構(gòu)造函數(shù)中動態(tài)的將IsMdiContainer設(shè)為true,當然也可以設(shè)計視圖中設(shè)置;

2.編寫一個顯示寫子窗口的方法,方法中需注意的地方:childForm.MdiParent = this;childForm.Parent = splitContainer1.Panel2,意思是:將當前窗口作為子窗口的父窗口,同時將Panel2指定為子窗口的父對象,這樣就能實現(xiàn)子窗口在Panel2中打開了。

第二個功能:在WINDOWS菜單項下顯示已打開的子窗口列表,這里實現(xiàn)就沒有像文章一開始介紹的那樣簡單,使用那個方法是無效的,需要我們來自行實現(xiàn),稍微有點復(fù)雜,但如果明白其實現(xiàn)原理,也就簡單明白了。

實現(xiàn)思路:當childForm加載到Panel2時,會觸發(fā)Panel2.ControlAdded事件,當childForm被關(guān)閉時,會觸發(fā)Panel2.ControlRemoved事件,我們可以統(tǒng)一訂閱這兩個事件,當childForm加載時,那么就在WINDOWS菜單項下增加一個菜單項,反之則移除該菜單項,實現(xiàn)代碼如下:

this.splitContainer1.Panel2.ControlAdded += Panel2_ControlChanged;
this.splitContainer1.Panel2.ControlRemoved += Panel2_ControlChanged;
void Panel2_ControlChanged(object sender, ControlEventArgs e)
{
var frm = e.Control as Form;
string menuName = "menu_" + frm.Name;
bool exists = this.splitContainer1.Panel2.Controls.Contains(frm);
if (exists)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
frm.BringToFront();
frm.Focus();
}
else
{
windowsToolStripMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = frm.Text, Name = menuName, Tag = frm, Checked = true });
}
}
else
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
windowsToolStripMenuItem.DropDownItems.Remove(menuItem);
menuItem.Dispose();
}
}
}
private ToolStripMenuItem GetMenuItem(string menuName)
{
var menuItems = windowsToolStripMenuItem.DropDownItems.Cast<ToolStripMenuItem>();
menuItems.ToList().ForEach(m => m.Checked = false);
return menuItems.Where(m => m.Name == menuName).SingleOrDefault();
}

同時為了實現(xiàn)點擊WINDOWS菜單項的子菜單能夠快速切換子窗口,需要訂閱WINDOWS菜單項的DropDownItemClicked事件,當然也可以為新增的子菜單項訂閱Click事件,實現(xiàn)代碼如下:

windowsToolStripMenuItem.DropDownItemClicked += windowsToolStripMenuItem_DropDownItemClicked;
void windowsToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
var menuItem = GetMenuItem(e.ClickedItem.Name);
menuItem.Checked = true;
var childForm = menuItem.Tag as Form;
childForm.BringToFront();
childForm.Focus();
}
private void CheckWindowsMenuItem(string menuName)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
}
} 

這樣就基本實現(xiàn)了在WINDOWS菜單項下顯示已打開的子窗口列表,并點擊指定的菜單項能夠切換當前活動的子窗口,但仍有一個不足的地方,那就是,當直接點擊子窗口來切換當前活動窗口時(說白了就是當點擊某個子窗口標題欄,該窗口就顯示在其它所有的子窗口最前面),WINDOWS菜單項下的子菜單勾選項沒有同步更新,一開始想到的是用Activated事件來進行處理,結(jié)果經(jīng)測試發(fā)現(xiàn)有效,該Activated事件在點擊子窗口標題欄時并不會被觸發(fā),所以只能換種方法,經(jīng)過多次測試,發(fā)現(xiàn)當窗口從后面切換到前面時(稱為Z順序改變),子窗口就會發(fā)生重繪,從而觸發(fā)Paint方法,我們可以訂閱該事件,并進行處理,實現(xiàn)代碼如下:

private string currentChildFormName = null; //記錄當前活動子窗口名稱
childForm.Paint += (s, e) => { 
var frm=s as Form;
if (!frm.Name.Equals(currentChildFormName) && this.splitContainer1.Panel2.Controls[0].Equals(frm)) //當容器中第一個控件就是當前的窗口,則表明該窗口處于所有窗口之上
{
CheckWindowsMenuItem("menu_" + frm.Name);
currentChildFormName = frm.Name;
}
}; 

最后貼出完整的實現(xiàn)代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class FormMain : Form
{
private int formCount = 0;
private string currentChildFormName = null;
public FormMain()
{
InitializeComponent();
this.IsMdiContainer = true;
this.splitContainer1.Panel2.ControlAdded += Panel2_ControlChanged;
this.splitContainer1.Panel2.ControlRemoved += Panel2_ControlChanged;
windowsToolStripMenuItem.DropDownItemClicked += windowsToolStripMenuItem_DropDownItemClicked;
}
void windowsToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
var menuItem = GetMenuItem(e.ClickedItem.Name);
menuItem.Checked = true;
var childForm = menuItem.Tag as Form;
childForm.BringToFront();
childForm.Focus();
}
private void FormMain_Load(object sender, EventArgs e)
{
ShowChildForm<FormChild>();
}
private void ShowChildForm<TForm>() where TForm : Form, new()
{
TForm childForm = new TForm();
childForm.Name = "frm" + Guid.NewGuid().ToString("N");
childForm.Text = string.Format("Child Form -{0}", ++formCount);
childForm.MdiParent = this;
childForm.Parent = splitContainer1.Panel2;
childForm.WindowState = FormWindowState.Maximized;
childForm.Paint += (s, e) => { 
var frm=s as Form;
if (!frm.Name.Equals(currentChildFormName) && this.splitContainer1.Panel2.Controls[0].Equals(frm)) //當容器中第一個控件就是當前的窗口,則表明該窗口處于所有窗口之上
{
CheckWindowsMenuItem("menu_" + frm.Name);
currentChildFormName = frm.Name;
}
};
childForm.Show();
}
private void CheckWindowsMenuItem(string menuName)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
}
}
void Panel2_ControlChanged(object sender, ControlEventArgs e)
{
var frm = e.Control as Form;
string menuName = "menu_" + frm.Name;
bool exists = this.splitContainer1.Panel2.Controls.Contains(frm);
if (exists)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
frm.BringToFront();
frm.Focus();
}
else
{
windowsToolStripMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = frm.Text, Name = menuName, Tag = frm, Checked = true });
}
}
else
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
windowsToolStripMenuItem.DropDownItems.Remove(menuItem);
menuItem.Dispose();
}
}
}
private ToolStripMenuItem GetMenuItem(string menuName)
{
var menuItems = windowsToolStripMenuItem.DropDownItems.Cast<ToolStripMenuItem>();
menuItems.ToList().ForEach(m => m.Checked = false);
return menuItems.Where(m => m.Name == menuName).SingleOrDefault();
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowChildForm<FormChild>();
}
}
} 

以下是系統(tǒng)自動生成的代碼:

namespace WindowsFormsApplication1
{
partial class FormMain
{
/// <summary>
/// 必需的設(shè)計器變量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
/// <param name="disposing">如果應(yīng)釋放托管資源,為 true;否則為 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗體設(shè)計器生成的代碼
/// <summary>
/// 設(shè)計器支持所需的方法 - 不要
/// 使用代碼編輯器修改此方法的內(nèi)容。
/// </summary>
private void InitializeComponent()
{
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.windowsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
// 
// menuStrip1
// 
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.windowsToolStripMenuItem,
this.newToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(1069, 25);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
// 
// windowsToolStripMenuItem
// 
this.windowsToolStripMenuItem.Name = "windowsToolStripMenuItem";
this.windowsToolStripMenuItem.Size = new System.Drawing.Size(73, 21);
this.windowsToolStripMenuItem.Text = "Windows";
this.windowsToolStripMenuItem.Click += new System.EventHandler(this.windowsToolStripMenuItem_Click);
// 
// newToolStripMenuItem
// 
this.newToolStripMenuItem.Name = "newToolStripMenuItem";
this.newToolStripMenuItem.Size = new System.Drawing.Size(46, 21);
this.newToolStripMenuItem.Text = "New";
this.newToolStripMenuItem.Click += new System.EventHandler(this.newToolStripMenuItem_Click);
// 
// splitContainer1
// 
this.splitContainer1.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 25);
this.splitContainer1.Name = "splitContainer1";
// 
// splitContainer1.Panel2
// 
this.splitContainer1.Panel2.BackColor = System.Drawing.SystemColors.ScrollBar;
this.splitContainer1.Size = new System.Drawing.Size(1069, 526);
this.splitContainer1.SplitterDistance = 356;
this.splitContainer1.TabIndex = 2;
// 
// FormMain
// 
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1069, 551);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.Name = "FormMain";
this.Text = "FormMain";
this.Load += new System.EventHandler(this.FormMain_Load);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem windowsToolStripMenuItem;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem;
}
}

以下是效果演示截圖:

以上內(nèi)容給大家分享了在winform下實現(xiàn)左右布局多窗口界面的方法,有什么更好的實現(xiàn)方法可以在下方評論,不足之處也歡迎指出,謝謝!下面將給大家介紹在winform下實現(xiàn)左右布局多窗口界面的方法之續(xù)篇,感興趣的朋友繼續(xù)關(guān)注。

相關(guān)文章

  • C#利用RabbitMQ實現(xiàn)點對點消息傳輸

    C#利用RabbitMQ實現(xiàn)點對點消息傳輸

    RabbitMQ做為消息代理,負責接收和轉(zhuǎn)發(fā)消息,可以將RabbitMQ比喻為一個郵筒、一個郵局和一個郵遞員。本文主要以一個簡單的小例子,簡述RabbitMQ實現(xiàn)消息傳輸?shù)南嚓P(guān)內(nèi)容,僅供學習分享使用,如有不足之處,還請指正。
    2021-05-05
  • C# 使用SHA1算法對密碼進行加密

    C# 使用SHA1算法對密碼進行加密

    這篇文章主要介紹了C# 使用SHA1算法對密碼進行加密,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-03-03
  • C#實現(xiàn)txt定位指定行完整實例

    C#實現(xiàn)txt定位指定行完整實例

    這篇文章主要介紹了C#實現(xiàn)txt定位指定行的方法,涉及C#針對文本文件進行光標定位的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • 基于C#實現(xiàn)FTP下載文件

    基于C#實現(xiàn)FTP下載文件

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)FTP下載文件,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#中的正則表達式介紹

    C#中的正則表達式介紹

    關(guān)于正則表達式,我們都知道挺繁瑣的。本文介紹的是C#中的正則表達式,希望對你有幫助,一起來看。
    2015-10-10
  • 基于params,ref,out的參數(shù)問題詳解

    基于params,ref,out的參數(shù)問題詳解

    本篇文章是對params,ref,out的參數(shù)問題進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • 漢字轉(zhuǎn)拼音軟件制件示例(漢字轉(zhuǎn)字母)

    漢字轉(zhuǎn)拼音軟件制件示例(漢字轉(zhuǎn)字母)

    這篇文章主要介紹了c#漢字轉(zhuǎn)拼音的方法,但不能判斷多音字,大家可以參考修改使用
    2014-01-01
  • unity實現(xiàn)物體延時出現(xiàn)

    unity實現(xiàn)物體延時出現(xiàn)

    這篇文章主要為大家詳細介紹了unity實現(xiàn)物體延時出現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Silverlight將圖片轉(zhuǎn)換為byte的實現(xiàn)代碼

    Silverlight將圖片轉(zhuǎn)換為byte的實現(xiàn)代碼

    這篇文章主要介紹了Silverlight將圖片轉(zhuǎn)換為byte的實現(xiàn)代碼,需要的朋友可以參考下
    2015-11-11
  • 可空類型Nullable<T>用法詳解

    可空類型Nullable<T>用法詳解

    本文詳細講解了可空類型Nullable<T>的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02

最新評論

襄汾县| 永春县| 清苑县| 富民县| 时尚| 寿光市| 新宁县| 鄢陵县| 宝山区| 新干县| 台安县| 呼图壁县| 西城区| 兴仁县| 潍坊市| 白银市| 四川省| 嘉善县| 奈曼旗| 凌云县| 井冈山市| 安吉县| 宽城| 娄烦县| 南木林县| 谷城县| 饶阳县| 枣阳市| 乌苏市| 桂阳县| 新巴尔虎左旗| 侯马市| 江永县| 高雄市| 黄石市| 镇坪县| 葫芦岛市| 岐山县| 麦盖提县| 筠连县| 聂拉木县|