效果图:

自定义控件实现代码:

 using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms; namespace WindowsFormsApplication1
{
[ToolboxBitmap(typeof(SplitContainer))]
public partial class SplitContainerEx : SplitContainer
{
#region Field /// <summary>
/// 控制器绘制区域
/// </summary>
private Rectangle ControlRect
{
get
{
var rect = new Rectangle(); if (Orientation == Orientation.Horizontal)
{
rect.X = Width <= ? : Width / - ;
rect.Y = SplitterDistance;
rect.Width = ;
rect.Height = ;
}
else
{
rect.X = SplitterDistance;
rect.Y = Height <= ? : Height / - ;
rect.Width = ;
rect.Height = ;
}
return rect;
}
} /// <summary>
/// 鼠标状态(进入或离开)
/// </summary>
private MouseState _mouseState = MouseState.Normal; /// <summary>
/// 定义折叠或展开的是哪一个面板
/// </summary>
private SplitterPanelEnum _collpaseOrExpandPanel; /// <summary>
/// Splitter是否固定
/// </summary>
private bool _isSplitterFixed = true; /// <summary>
/// 当前是否为折叠状态
/// </summary>
private bool _collpased; #endregion #region Property /// <summary>
/// 进行折叠或展开的SplitterPanel,设置为属性,所以可以在页面进行重新设置
/// </summary>
[DefaultValue(SplitterPanelEnum.Panel1)]
public SplitterPanelEnum CollpaseOrExpandPanel
{
get
{
return _collpaseOrExpandPanel;
}
set
{
if (value != _collpaseOrExpandPanel)
{
_collpaseOrExpandPanel = value;
Invalidate(ControlRect);
}
}
} /// <summary>
/// 设定Panel1是否为默认折叠
/// </summary>
private bool _panel1Collapsed;
[DefaultValue(false)]
public new bool Panel1Collapsed
{
get
{
return _panel1Collapsed;
}
set
{
//只有当CollpaseOrExpandPanel = Panel时,Panel1Collapsed的设置才会有效
if (CollpaseOrExpandPanel == SplitterPanelEnum.Panel1 && value != _panel1Collapsed)
{
_panel1Collapsed = value;
//设置_collpased值为value的相反值,再调用CollpaseOrExpand()进行折叠或展开.
_collpased = !value; CollpaseOrExpand();
}
}
} /// <summary>
/// 设置Panel2是否为默认折叠
/// </summary>
private bool _panel2Colapsed;
[DefaultValue(false)]
public new bool Panel2Collapsed
{
get
{
return _panel2Colapsed;
}
set
{
//只有当CollpaseOrExpandPanel = Pane2时,Panel1Collapsed的设置才会有效
if (CollpaseOrExpandPanel == SplitterPanelEnum.Panel2 && value != _panel2Colapsed)
{
_panel2Colapsed = value;
//设置_collpased值为value的相反值,再调用CollpaseOrExpand()进行折叠或展开
_collpased = !value; CollpaseOrExpand();
}
}
} /// <summary>
/// 用于固定保存显式设定的SplitterDistance,因为基类的SplitterDistance属性会变动
/// </summary>
public int DefaultSplitterDistance
{
get;
set;
} #endregion #region Ctor public SplitContainerEx()
{
SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer, true); Panel1MinSize = ;
Panel2MinSize = ;
} #endregion #region Override protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e); Color color = _mouseState == MouseState.Normal ? SystemColors.ButtonShadow : SystemColors.ControlDarkDark; //需要绘制的图片
Bitmap bmp = CreateControlImage(color); //对图片进行旋转
RotateFlip(bmp); //清除绘制区域
e.Graphics.SetClip(SplitterRectangle);
e.Graphics.Clear(BackColor);
//绘制
e.Graphics.DrawImage(bmp, ControlRect);
} protected override void OnMouseMove(MouseEventArgs e)
{
//鼠标在控制按钮区域
if (SplitterRectangle.Contains(e.Location))
{
if (ControlRect.Contains(e.Location))
{
//如果拆分器可移动,则鼠标在控制按钮范围内时临时关闭拆分器
if (!IsSplitterFixed)
{
IsSplitterFixed = true; _isSplitterFixed = false;
} Cursor = Cursors.Hand;
_mouseState = MouseState.Hover;
Invalidate(ControlRect);
}
else
{
//如果拆分器为临时关闭,则开启拆分器
if (!_isSplitterFixed)
{
IsSplitterFixed = false;
Cursor = Orientation == Orientation.Horizontal ? Cursors.HSplit : Cursors.VSplit;
}
else
{
Cursor = Cursors.Default;
}
_mouseState = MouseState.Normal;
Invalidate(ControlRect);
}
}
base.OnMouseMove(e);
} protected override void OnMouseLeave(EventArgs e)
{
Cursor = Cursors.Default; _mouseState = MouseState.Normal; Invalidate(ControlRect); base.OnMouseLeave(e);
} protected override void OnMouseClick(MouseEventArgs e)
{
if (ControlRect.Contains(e.Location))
{
CollpaseOrExpand();
} base.OnMouseClick(e);
} #endregion #region Method /// <summary>
/// 折叠或展开
/// 1.当当前状态为折叠状态时,则进行展开操作
/// 2.当当前状态为展开状态时,则进行折叠操作
/// </summary>
private void CollpaseOrExpand()
{
//当前为缩小状态,进行Expand操作
if (_collpased)
{
//展开
SplitterDistance = DefaultSplitterDistance;
}
//当前为伸展状态,进行Collpase操作
else
{
//折叠
if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1)
{
SplitterDistance = ;
}
else
{
if (Orientation == Orientation.Horizontal)
{
SplitterDistance = Height - ;
}
else
{
SplitterDistance = Width - ;
}
}
} _collpased = !_collpased; Invalidate(ControlRect); //局部刷新绘制
} /// <summary>
/// 需要绘制的用于折叠窗口的按钮样式
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
private Bitmap CreateControlImage(Color color)
{
var bmp = new Bitmap(, );
for (int x = ; x <= ; x += )
{
for (int y = ; y <= ; y += )
{
bmp.SetPixel(x, y, color);
}
}
for (int x = ; x <= ; x += )
{
for (int y = ; y <= ; y += )
{
bmp.SetPixel(x, y, color);
}
} int k = ;
for (int y = ; y >= ; y--)
{
for (int x = + k; x <= - k; x++)
{
bmp.SetPixel(x, y, color);
}
k++;
} return bmp;
} private void RotateFlip(Bitmap bmp)
{
if (Orientation == Orientation.Horizontal)
{
if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1 && !_collpased ||
_collpaseOrExpandPanel == SplitterPanelEnum.Panel2 && _collpased)
{
bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
}
else
{
bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
}
}
else
{
if (_collpaseOrExpandPanel == SplitterPanelEnum.Panel1 && !_collpased ||
_collpaseOrExpandPanel == SplitterPanelEnum.Panel2 && _collpased)
{
bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
}
else
{
bmp.RotateFlip(RotateFlipType.Rotate270FlipX);
}
}
} #endregion #region Enums enum MouseState
{
/// <summary>
/// 正常
/// </summary>
Normal,
/// <summary>
/// 鼠标移入
/// </summary>
Hover
} public enum SplitterPanelEnum
{
Panel1,
Panel2
} #endregion
}
}

扩展SplitContainer控件的更多相关文章

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

    C#使用splitContainer控件制作收缩展开面板 原创 2011年07月19日 17:18:02 标签: c# / object / 扩展 / 测试 15690         最近对Squi ...

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

    引言 相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项.打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用.“Tiles”提供了一 ...

  3. 验证控件插图扩展控件ValidatorCalloutExtender(用于扩展验证控件)和TextBoxWatermarkExtender

    <asp:ScriptManager ID="ScriptManager1" runat="server">  </asp:ScriptMan ...

  4. 如何使用SplitContainer控件[转]

    原文地址:http://yinzhihua2008.blog.163.com/blog/static/794306720120511150457/ 在Windows资源管理器中,当把鼠标指针移动到Tr ...

  5. C#如何使用SplitContainer控件实现上下分隔

    C#如何使用SplitContainer控件实现上下分隔 Orientation 属性设置为Horizontal 完美世界 http://www.23cat.com/Contents_51864.ht ...

  6. 扩展GroupBox控件

    1.GroupBox的边框颜色可以自行设置: 2.GroupBox可以设置边框的为圆角: 3.设置GroupBox标题在控件中的位置. 4.设置GroupBox标题的字体和颜色. 具体实现步骤Pane ...

  7. 一个动态扩展表格控件列和行的 jQuery 插件

    一个动态扩展表格控件列和行的 jQuery 插件 不过这并不影响使用鸭! 看这里:https://github.com/zhuwansu/table-ext.js 一个简单的示范 html <t ...

  8. 扩展 easyui 控件系列:为datagrid 增加过滤行

    此功能还为真正完成,起到抛砖引玉的效果,发动大家的力量把这个功能完善起来,效果图如下: 基本上就是扩展了 datagrid.view 中的onAfterRender 这个事件,具体代码如下: $.ex ...

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

    文章摘自:http://www.cnblogs.com/zhangziqiu/archive/2009/03/18/1415005.html MVC在view页面,经常需要用到很多封装好的HTML控件 ...

随机推荐

  1. python应用:爬虫框架Scrapy系统学习第一篇——xpath详解

    HTML的三大概念:标签.元素以及属性 标签:尖括号中的文本       例:<head>……</head> 标签通常成对出现 元素:标签中的所有内容        元素中可包 ...

  2. 『Python基础-14』匿名函数 `lambda`

    匿名函数和关键字lambda 匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数 在Python中,如果要声匿名函数,则需要使用lambda关键字 使用lambda声明的匿名函数能接收任何 ...

  3. QOS-交换机拥塞管理

    QOS-交换机拥塞管理 2018年7月7日 20:29 优先级映射: 根据信任的优先级,查找映射表,标记丢弃优先级和本地优先级 如果信任端口优先级,不同产品优先级标记方式可能不同,S3610处理过程如 ...

  4. vim 对齐线

    ** 从https://github.com/Yggdroot/indentLine下载 indentLine插件 git clone https://github.com/Yggdroot/inde ...

  5. Microsoft.VisualBasic.dll的妙用(开发中肯定会用到哦)

    前言 做过VB开发的都知道,有一些VB里面的好的函数在.NET里面都没有,而Microsoft.VisualBasic.dll却给我们提供使用这些函数的功能(没用过VB的这些功能一样可以使用,大同小异 ...

  6. 青岛Uber优步司机奖励政策(8/10-8/16)

    亲爱的Uber青岛优步的大司机朋友们,又到了每周发布奖励细则的时刻啦!下一周的奖励与上周有所不同,请一定要仔细按照自己的情况阅读!另外,之前参与过投票并表示想加入新小时保底政策的老司机朋友们从本周起, ...

  7. springBoot cache操作2

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zxd1435513775/article/details/85091793一.基本项目搭建测试项目是 ...

  8. Android远程推送笔记

    Android远程推送笔记 Android推送有很多种实现方案,但都没办法和苹果的APNS比拟,这里主要来讲述一下我遇到的问题,和作出的抉择. 首先,为了快速接入,所以就没有自己搭建推送服务器,而是使 ...

  9. vim中project多标签和多窗口的使用

    1.打开多个窗口 打开多个窗口的命令以下几个: 横向切割窗口 :new+窗口名(保存后就是文件名) :split+窗口名,也可以简写为:sp+窗口名 纵向切割窗口名 :vsplit+窗口名,也可以简写 ...

  10. 「日常训练」Skills(Codeforce Round #339 Div.2 D)

    题意(CodeForces 614D) 每个人有\(n(n\le 10^5)\)个技能,技能等级都在\([0,10^9]\)的范围,每个技能有一个当前等级,所有技能的最高等级都为A.一个人的力量被记做 ...