前言
在做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 }
View Code
檔案編輯器做好了,下面就是主窗體,首先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
附錄:小菜學習程式設計-Winform系列(初學者)
作者:田園裡的蟋蟀
微信公衆号:你好架構
出處:http://www.cnblogs.com/xishuai/
公衆号會不定時的分享有關架構的方方面面,包含并不局限于:Microservices(微服務)、Service Mesh(服務網格)、DDD/TDD、Spring Cloud、Dubbo、Service Fabric、Linkerd、Envoy、Istio、Conduit、Kubernetes、Docker、MacOS/Linux、Java、.NET Core/ASP.NET Core、Redis、RabbitMQ、MongoDB、GitLab、CI/CD(持續內建/持續部署)、DevOps等等。
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接。
分享到:
QQ空間
新浪微網誌
騰訊微網誌
微信
更多