前言
在做winfrom項目的時候我們可能會用到嵌套窗體,就是說一個容器中有多個窗體,可以分別管理和應用這些窗體,.net中提供了一種機制就是MDI,可能大家都會用,這邊就簡單的介紹下。
簡單應用
winfrom中怎么用MDI呢,其實只要設置窗體的一個屬性就可以了:
IsMdiContainer屬性設置為true就表示該窗體為MDI窗體,很簡單,那我們可以在窗體加載的時候這些寫:
1 private void Form1_Load(object sender, EventArgs e) 2 { 3 Form childForm1 = new Form(); 4 childForm1.Text = "窗口1"; 5 childForm1.MdiParent = this; 6 childForm1.Show(); 7 8 Form childForm2 = new Form(); 9 childForm2.Text = "窗口2"; 10 childForm2.MdiParent = this; 11 childForm2.Show(); 12 }
childForm1.MdiParent = this;這句代碼的意思就是設置子窗體的MDI父窗體為本窗體,看下運行效果:
基本方法
關于MDI相關的方法主要是窗體的布局方法LayoutMdi(),參數是MdiLayout枚舉:
成員名稱 | 說明 | |
---|---|---|
ArrangeIcons | 所有 MDI 子圖標均排列在 MDI 父窗體的工作區內。 | |
Cascade | 所有 MDI 子窗口均層疊在 MDI 父窗體的工作區內。 | |
TileHorizontal | 所有 MDI 子窗口均水平平鋪在 MDI 父窗體的工作區內。 | |
TileVertical | 所有 MDI 子窗口均垂直平鋪在 MDI 父窗體的工作區內。 |
LayoutMdi(MdiLayout.Cascade);效果:
LayoutMdi(MdiLayout.TileHorizontal);效果:
仿Notepad小程序
我們在辦公的時候可能都用過Notepad++,很方便,其實Notepad++里面的窗體就有點MDI的感覺:
我們也可以利用MDI做出類似的感效果,Notepad++是文本編輯器,里面每個窗體其實就是單獨的Notepad,首先我們需要先建一個文件編輯器的窗體,其實就是一個RichTextBox控件,因為RichTextBox控件是富文本編輯器,所以我們可以進行字體和顏色的調整,調整字體和顏色用的是winfrom的組件,關于文本編輯器就不詳述了,貼下代碼:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 9 namespace MDINotepad 10 { 11 public partial class NotepadForm : Form 12 { 13 private int _currentCharIndex; 14 15 #region Code segment for constructors. 16 17 public NotepadForm() 18 { 19 InitializeComponent(); 20 } 21 22 public NotepadForm(string filePath): this() 23 { 24 //判斷文件的后綴名,不同的文件類型使用不同的參數打開。 25 26 if (filePath.EndsWith(".rtf", true, null)) 27 rtbEditor.LoadFile(filePath, 28 RichTextBoxStreamType.RichText); 29 else 30 rtbEditor.LoadFile(filePath, 31 RichTextBoxStreamType.PlainText); 32 33 Text = filePath; 34 } 35 36 #endregion 37 38 #region Code segment for private operations. 39 40 private void Save(string filePath) 41 { 42 try 43 { 44 //判斷文件的后綴名,不同的文件類型使用不同的參數保存。 45 46 if (filePath.EndsWith(".rtf", true, null)) 47 rtbEditor.SaveFile(filePath, 48 RichTextBoxStreamType.RichText); 49 else 50 rtbEditor.SaveFile(filePath, 51 RichTextBoxStreamType.PlainText); 52 } 53 catch (Exception ex) 54 { 55 MessageBox.Show(ex.ToString()); 56 } 57 } 58 59 private void SaveAs() 60 { 61 sfdDemo.FilterIndex = Text.EndsWith(".rtf", true, null) ? 1 : 2; 62 63 if (sfdDemo.ShowDialog() == DialogResult.OK) 64 { 65 Save(sfdDemo.FileName); 66 Text = sfdDemo.FileName; 67 } 68 } 69 70 #endregion 71 72 #region Code segment for event handlers. 73 74 private void tsmiSaveFile_Click(object sender, EventArgs e) 75 { 76 if (!System.IO.File.Exists(Text)) 77 SaveAs(); 78 else 79 Save(Text); 80 } 81 82 private void tsmiSaveAs_Click(object sender, EventArgs e) 83 { 84 SaveAs(); 85 } 86 87 private void tsmiBackColor_Click(object sender, EventArgs e) 88 { 89 cdDemo.Color = rtbEditor.SelectionBackColor; 90 if (cdDemo.ShowDialog() == DialogResult.OK) 91 { 92 rtbEditor.SelectionBackColor = cdDemo.Color; 93 } 94 } 95 96 private void rtbEditor_SelectionChanged(object sender, EventArgs e) 97 { 98 if (rtbEditor.SelectionLength == 0) 99 { 100 tsmiBackColor.Enabled = false; 101 tsmiFont.Enabled = false; 102 } 103 else 104 { 105 tsmiBackColor.Enabled = true; 106 tsmiFont.Enabled = true; 107 } 108 } 109 110 private void tsmiFont_Click(object sender, EventArgs e) 111 { 112 fdDemo.Color = rtbEditor.SelectionColor; 113 fdDemo.Font = rtbEditor.SelectionFont; 114 if (fdDemo.ShowDialog() == DialogResult.OK) 115 { 116 rtbEditor.SelectionColor = fdDemo.Color; 117 rtbEditor.SelectionFont = fdDemo.Font; 118 } 119 } 120 121 private void pdEditor_PrintPage(object sender, 122 System.Drawing.Printing.PrintPageEventArgs e) 123 { 124 //存放當前已經處理的高度 125 126 float allHeight = 0; 127 //存放當前已經處理的寬度 128 129 float allWidth = 0; 130 //存放當前行的高度 131 float lineHeight = 0; 132 //存放當前行的寬度 133 float lineWidth = e.MarginBounds.Right - e.MarginBounds.Left; 134 135 //當前頁沒有顯示滿且文件沒有打印完,進行循環 136 137 while (allHeight < e.MarginBounds.Height 138 && _currentCharIndex < rtbEditor.Text.Length) 139 { 140 //選擇一個字符 141 142 rtbEditor.Select(_currentCharIndex, 1); 143 //獲取選中的字體 144 145 Font currentFont = rtbEditor.SelectionFont; 146 //獲取文字的尺寸 147 148 SizeF currentTextSize = 149 e.Graphics.MeasureString(rtbEditor.SelectedText, currentFont); 150 151 //獲取的文字寬度,對于字母間隙可以小一些, 152 //對于空格間隙可以大些,對于漢字間隙適當調整。 153 154 if (rtbEditor.SelectedText[0] == ' ') 155 currentTextSize.Width = currentTextSize.Width * 1.5f; 156 else if (rtbEditor.SelectedText[0] < 255) 157 currentTextSize.Width = currentTextSize.Width * 0.6f; 158 else 159 currentTextSize.Width = currentTextSize.Width * 0.75f; 160 161 //初始位置修正2個像素,進行背景色填充 162 163 e.Graphics.FillRectangle(new SolidBrush(rtbEditor.SelectionBackColor), 164 e.MarginBounds.Left + allWidth + 2, e.MarginBounds.Top + allHeight, 165 currentTextSize.Width, currentTextSize.Height); 166 167 //使用指定顏色和字體畫出當前字符 168 169 e.Graphics.DrawString(rtbEditor.SelectedText, currentFont, 170 new SolidBrush(rtbEditor.SelectionColor), 171 e.MarginBounds.Left + allWidth, e.MarginBounds.Top + allHeight); 172 173 allWidth += currentTextSize.Width; 174 175 //獲取最大字體高度作為行高 176 177 if (lineHeight < currentFont.Height) 178 lineHeight = currentFont.Height; 179 180 //是換行符或當前行已滿,allHeight加上當前行高度, 181 //allWidth和lineHeight都設為0。 182 183 if (rtbEditor.SelectedText == "\n" 184 || e.MarginBounds.Right - e.MarginBounds.Left < allWidth) 185 { 186 allHeight += lineHeight; 187 allWidth = 0; 188 lineHeight = 0; 189 } 190 //繼續下一個字符 191 192 _currentCharIndex++; 193 } 194 195 //后面還有內容,則還有下一頁 196 197 if (_currentCharIndex < rtbEditor.Text.Length) 198 e.HasMorePages = true; 199 else 200 e.HasMorePages = false; 201 } 202 203 private void tsmiPrint_Click(object sender, EventArgs e) 204 { 205 if (pdDemo.ShowDialog() == DialogResult.OK) 206 { 207 //用戶確定了打印機和設置后,進行打印。 208 209 pdEditor.Print(); 210 } 211 } 212 213 private void tsmiPageSetup_Click(object sender, EventArgs e) 214 { 215 psdDemo.ShowDialog(); 216 } 217 218 private void tsmiPrintPreview_Click(object sender, EventArgs e) 219 { 220 ppdDemo.ShowDialog(); 221 } 222 223 private void pdEditor_BeginPrint(object sender, 224 System.Drawing.Printing.PrintEventArgs e) 225 { 226 _currentCharIndex = 0; 227 } 228 229 #endregion 230 } 231 }
文件編輯器做好了,下面就是主窗體,首先IsMdiContainer屬性設置為true,在上面我們加下菜單:
新建Notepad的代碼:
1 private void tsmiNewTxt_Click(object sender, EventArgs e) 2 { 3 NotepadForm childForm = new NotepadForm(); 4 childForm.Text = "新建文本文檔.txt"; 5 childForm.MdiParent = this; 6 childForm.Show(); 7 }
運行效果:
程序下載:MDI窗體.rar
文章列表