扩展SplitContainer控件

效果图:

自定义控件实现代码:

  1 using System;
  2 using System.ComponentModel;
  3 using System.Drawing;
  4 using System.Windows.Forms;
  5
  6 namespace WindowsFormsApplication1
  7 {
  8     [ToolboxBitmap(typeof(SplitContainer))]
  9     public partial class SplitContainerEx : SplitContainer
 10     {
 11         #region Field
 12
 13         /// <summary>
 14         /// 控制器绘制区域
 15         /// </summary>
 16         private Rectangle ControlRect
 17         {
 18             get
 19             {
 20                 var rect = new Rectangle();
 21
 22                 if (Orientation == Orientation.Horizontal)
 23                 {
 24                     rect.X = Width <= 80 ? 0 : Width / 2 - 40;
 25                     rect.Y = SplitterDistance;
 26                     rect.Width = 80;
 27                     rect.Height = 9;
 28                 }
 29                 else
 30                 {
 31                     rect.X = SplitterDistance;
 32                     rect.Y = Height <= 80 ? 0 : Height / 2 - 40;
 33                     rect.Width = 9;
 34                     rect.Height = 80;
 35                 }
 36                 return rect;
 37             }
 38         }
 39
 40         /// <summary>
 41         /// 鼠标状态(进入或离开)
 42         /// </summary>
 43         private MouseState _mouseState = MouseState.Normal;
 44
 45         /// <summary>
 46         /// 定义折叠或展开的是哪一个面板
 47         /// </summary>
 48         private SplitterPanelEnum _collpaseOrExpandPanel;
 49
 50         /// <summary>
 51         /// Splitter是否固定
 52         /// </summary>
 53         private bool _isSplitterFixed = true;
 54
 55         /// <summary>
 56         /// 当前是否为折叠状态
 57         /// </summary>
 58         private bool _collpased;
 59
 60         #endregion
 61
 62         #region Property
 63
 64         /// <summary>
 65         /// 进行折叠或展开的SplitterPanel,设置为属性,所以可以在页面进行重新设置
 66         /// </summary>
 67         [DefaultValue(SplitterPanelEnum.Panel1)]
 68         public SplitterPanelEnum CollpaseOrExpandPanel
 69         {
 70             get
 71             {
 72                 return _collpaseOrExpandPanel;
 73             }
 74             set
 75             {
 76                 if (value != _collpaseOrExpandPanel)
 77                 {
 78                     _collpaseOrExpandPanel = value;
 79                     Invalidate(ControlRect);
 80                 }
 81             }
 82         }
 83
 84         /// <summary>
 85         /// 设定Panel1是否为默认折叠
 86         /// </summary>
 87         private bool _panel1Collapsed;
 88         [DefaultValue(false)]
 89         public new bool Panel1Collapsed
 90         {
 91             get
 92             {
 93                 return _panel1Collapsed;
 94             }
 95             set
 96             {
 97                 //只有当CollpaseOrExpandPanel = Panel时,Panel1Collapsed的设置才会有效
 98                 if (CollpaseOrExpandPanel == SplitterPanelEnum.Panel1 && value != _panel1Collapsed)
 99                 {
100                     _panel1Collapsed = value;
101                     //设置_collpased值为value的相反值,再调用CollpaseOrExpand()进行折叠或展开.
102                     _collpased = !value;
103
104                     CollpaseOrExpand();
105                 }
106             }
107         }
108
109         /// <summary>
110         /// 设置Panel2是否为默认折叠
111         /// </summary>
112         private bool _panel2Colapsed;
113         [DefaultValue(false)]
114         public new bool Panel2Collapsed
115         {
116             get
117             {
118                 return _panel2Colapsed;
119             }
120             set
121             {
122                 //只有当CollpaseOrExpandPanel = Pane2时,Panel1Collapsed的设置才会有效
123                 if (CollpaseOrExpandPanel == SplitterPanelEnum.Panel2 && value != _panel2Colapsed)
124                 {
125                     _panel2Colapsed = value;
126                     //设置_collpased值为value的相反值,再调用CollpaseOrExpand()进行折叠或展开
127                     _collpased = !value;
128
129                     CollpaseOrExpand();
130                 }
131             }
132         }
133
134         /// <summary>
135         /// 用于固定保存显式设定的SplitterDistance,因为基类的SplitterDistance属性会变动
136         /// </summary>
137         public int DefaultSplitterDistance
138         {
139             get;
140             set;
141         }
142
143         #endregion
144
145         #region Ctor
146
147         public SplitContainerEx()
148         {
149             SetStyle(
150                 ControlStyles.UserPaint |
151                 ControlStyles.AllPaintingInWmPaint |
152                 ControlStyles.OptimizedDoubleBuffer, true);
153
154             Panel1MinSize = 0;
155             Panel2MinSize = 0;
156         }
157
158         #endregion
159
160         #region Override
161
162         protected override void OnPaint(PaintEventArgs e)
163         {
164             base.OnPaint(e);
165
166             Color color = _mouseState == MouseState.Normal ? SystemColors.ButtonShadow : SystemColors.ControlDarkDark;
167
168             //需要绘制的图片
169             Bitmap bmp = CreateControlImage(color);
170
171             //对图片进行旋转
172             RotateFlip(bmp);
173
174             //清除绘制区域
175             e.Graphics.SetClip(SplitterRectangle);
176             e.Graphics.Clear(BackColor);
177             //绘制
178             e.Graphics.DrawImage(bmp, ControlRect);
179         }
180
181         protected override void OnMouseMove(MouseEventArgs e)
182         {
183             //鼠标在控制按钮区域
184             if (SplitterRectangle.Contains(e.Location))
185             {
186                 if (ControlRect.Contains(e.Location))
187                 {
188                     //如果拆分器可移动,则鼠标在控制按钮范围内时临时关闭拆分器
189                     if (!IsSplitterFixed)
190                     {
191                         IsSplitterFixed = true;
192
193                         _isSplitterFixed = false;
194                     }
195
196                     Cursor = Cursors.Hand;
197                     _mouseState = MouseState.Hover;
198                     Invalidate(ControlRect);
199                 }
200                 else
201                 {
202                     //如果拆分器为临时关闭,则开启拆分器
203                     if (!_isSplitterFixed)
204                     {
205                         IsSplitterFixed = false;
206                         Cursor = Orientation == Orientation.Horizontal ? Cursors.HSplit : Cursors.VSplit;
207                     }
208                     else
209                     {
210                         Cursor = Cursors.Default;
211                     }
212                     _mouseState = MouseState.Normal;
213                     Invalidate(ControlRect);
214                 }
215             }
216             base.OnMouseMove(e);
217         }
218
219         protected override void OnMouseLeave(EventArgs e)
220         {
221             Cursor = Cursors.Default;
222
223             _mouseState = MouseState.Normal;
224
225             Invalidate(ControlRect);
226
227             base.OnMouseLeave(e);
228         }
229
230         protected override void OnMouseClick(MouseEventArgs e)
231         {
232             if (ControlRect.Contains(e.Location))
233             {
234                 CollpaseOrExpand();
235             }
236
237             base.OnMouseClick(e);
238         }
239
240         #endregion
241
242         #region Method
243
244         /// <summary>
245         /// 折叠或展开
246         /// 1.当当前状态为折叠状态时,则进行展开操作
247         /// 2.当当前状态为展开状态时,则进行折叠操作
248         /// </summary>
249         private void CollpaseOrExpand()
250         {
251             //当前为缩小状态,进行Expand操作
252             if (_collpased)
253             {
254                 //展开
255                 SplitterDistance = DefaultSplitterDistance;
256             }
257             //当前为伸展状态,进行Collpase操作
258             else
259             {
260                 //折叠
261                 if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1)
262                 {
263                     SplitterDistance = 0;
264                 }
265                 else
266                 {
267                     if (Orientation == Orientation.Horizontal)
268                     {
269                         SplitterDistance = Height - 9;
270                     }
271                     else
272                     {
273                         SplitterDistance = Width - 9;
274                     }
275                 }
276             }
277
278             _collpased = !_collpased;
279
280             Invalidate(ControlRect); //局部刷新绘制
281         }
282
283         /// <summary>
284         /// 需要绘制的用于折叠窗口的按钮样式
285         /// </summary>
286         /// <param name="color"></param>
287         /// <returns></returns>
288         private Bitmap CreateControlImage(Color color)
289         {
290             var bmp = new Bitmap(80, 9);
291             for (int x = 5; x <= 30; x += 5)
292             {
293                 for (int y = 1; y <= 7; y += 3)
294                 {
295                     bmp.SetPixel(x, y, color);
296                 }
297             }
298             for (int x = 50; x <= 75; x += 5)
299             {
300                 for (int y = 1; y <= 7; y += 3)
301                 {
302                     bmp.SetPixel(x, y, color);
303                 }
304             }
305
306             int k = 0;
307             for (int y = 7; y >= 1; y--)
308             {
309                 for (int x = 35 + k; x <= 45 - k; x++)
310                 {
311                     bmp.SetPixel(x, y, color);
312                 }
313                 k++;
314             }
315
316             return bmp;
317         }
318
319         private void RotateFlip(Bitmap bmp)
320         {
321             if (Orientation == Orientation.Horizontal)
322             {
323                 if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1 && !_collpased ||
324                     _collpaseOrExpandPanel == SplitterPanelEnum.Panel2 && _collpased)
325                 {
326                     bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
327                 }
328                 else
329                 {
330                     bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
331                 }
332             }
333             else
334             {
335                 if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1 && !_collpased ||
336                     _collpaseOrExpandPanel == SplitterPanelEnum.Panel2 && _collpased)
337                 {
338                     bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
339                 }
340                 else
341                 {
342                     bmp.RotateFlip(RotateFlipType.Rotate270FlipX);
343                 }
344             }
345         }
346
347         #endregion
348
349         #region Enums
350
351         enum MouseState
352         {
353             /// <summary>
354             /// 正常
355             /// </summary>
356             Normal,
357             /// <summary>
358             /// 鼠标移入
359             /// </summary>
360             Hover
361         }
362
363         public enum SplitterPanelEnum
364         {
365             Panel1,
366             Panel2
367         }
368
369         #endregion
370     }
371 }
时间: 2024-08-08 13:45:21

扩展SplitContainer控件的相关文章

C#使用splitContainer控件制作收缩展开面板

C#使用splitContainer控件制作收缩展开面板 原创 2011年07月19日 17:18:02 标签: c# / object / 扩展 / 测试 15690 最近对Squid Ink公司的一款PC端软件系统上的一个收缩伸展面板很感兴趣,加上自己做的喷码机数据管理系统的界面非常单调,想在现在界面的基础上将这个功能加上去.我个人只是写c#的一个菜鸟,在网上查了C#的很多控件,很多人都是用GroupBox和SplitContainer实现的,于是就对这两个控件进行了测试.附Squid In

SplitContainer 控件详细用法(转)

1.可以将 Windows 窗体 SplitContainer 控件看作是一个复合体,它是由一个可移动的拆分条分隔的两个面板.当鼠标指针悬停在该拆分条上时,指针将相应地改变形状以显示该拆分条是可移动的.使用 SplitContainer 控件,可以创建复合的用户界面(通常,在一个面板中的选择决定了在另一个面板中显示哪些对象).这种排列对于显示和浏览信息非常有用.拥有两个面板使您可以聚合不同区域中的信息,并且用户可以轻松地使用拆分条(也称为"拆分器")调整面板的大小.另外,还可以嵌套多个

扩展GridView控件——为内容项添加拖放及分组功能

引言 相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项.打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用."Tiles"提供了一个简单易用,平铺方式来组织内容显示.Windows8的开始菜单是最典型的GridView 示例."开始菜单"显示了系统中安装的所有应用程序,而且支持重新排列. 本文源于我们项目的开发人员,他们想在项目中提供与GridView相同的用户体验,想要创建类GridView控件

使用SplitContainer控件

8.6 使用SplitContainer控件 在Windows资源管理器中,当把鼠标指针移动到TreeView控件和ListView控件之间时,可以左右拖动鼠标调整TreeView控件和ListView控件在主窗口中的大小比例,以适应不同显示内容的需要.我们可以使用SplitContainer控件实现这种功能. 可以将SplitContainer控件看做是一个复合体,它是由一个可移动的拆分条分隔的两个面板.当鼠标指针悬停在该拆分条上时,指针将相应地改变形状以显示该拆分条是可移动的.使用Split

扩展GroupBox控件

1.GroupBox的边框颜色可以自行设置: 2.GroupBox可以设置边框的为圆角: 3.设置GroupBox标题在控件中的位置. 4.设置GroupBox标题的字体和颜色. 具体实现步骤Panel扩展一样,直接看具体的代码,代码如下: public class GroupBoxEx : GroupBox { private Font _titleFont = new Font("宋体", 10, FontStyle.Regular); private Color _titleCo

[Silverlight] 仿Excel扩展C1FlexGrid控件

一  分析阶段 根据Excel表格区域的划分,如下图,基本上以4行*3列的框架搭建: 第一行为列头区域     ==>  C1FlexGrid.ColumnHeaders 第二行为单元格区域  ==>  C1FlexGrid.Cells 第三行为列尾区域     ==>  C1FlexGrid.ColumnFooters 第四行为横向滚动条区域,在Excel里还有工作簿页签等: 第一列为行头区域     ==>  C1FlexGrid.RowHeaders 第二列为单元格区域 第三

MVC中使用HTML Helper类扩展HTML控件

文章摘自:http://www.cnblogs.com/zhangziqiu/archive/2009/03/18/1415005.html MVC在view页面,经常需要用到很多封装好的HTML控件,这篇文章主要讲述,怎么自己扩展和定制自己需要的控件. ---------------------------------------------------------- HTML Helper类是ASP.NET MVC框架中提供的生成HTML控件代码的类. 本质上与第一种方式一样, 只是我们可以

布局 -- SplitContainer控件

示例: DbEditor的主窗口 步骤: 1 SplitContainer: 选择容器: 法1 右键 --  选择   法2 属性窗口 顶层底层: 在左上角处右键 水平垂直:orientation属性 填充置顶: dock属性. 2  注意: -工具栏与容器重叠.选择工具栏和菜单栏,置于底层 -注意,dock时父容器不用指定,vs自动寻找.若不行,刷新几次即可 -若删除SplitContainer, 先将其包含的控件脱离,然后缩小contianer, 移到边角处删除.

WinForms中TreeView控件的扩展与使用

EXE文件方便大家测试   源码下载 TreeView控件非常的好用,在我的公文系统中,使用TreeView控件选择接收公文的人员,支持单选,可多选 现提取出来,方便大家使用 涉及到的知识点 1:从Xml文件中加载内容显示到TreeView控件中 <?xml version="1.0" encoding="utf-8"?> <根目录> <组 名称="校长" 用户ID="1000"> <