文章出處

前言

  在做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系列(初學者)

 


文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()