小菜学习Winform(四)MDI窗体(附示例)

前言

  在做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的组件,关于文本编辑器就不详述了,贴下代码:

小菜学习Winform(四)MDI窗体(附示例)
  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系列(初学者)

 

你可能感兴趣的:(WinForm)