• 扩展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 }
  • 相关阅读:
    jquery基础
    js知识-进阶
    css样式介绍
    html基础知识介绍
    样式初识-基本样式介绍
    数据库之mysql的基本操作
    python基础-UDP、进程、进程池、paramike模块
    python基础--接口与归一化设计、封装、异常、网络编程
    Python学习之路—2018/6/25
    Python学习之路—2018/6/20
  • 原文地址:https://www.cnblogs.com/JustYong/p/5552244.html
Copyright © 2020-2023  润新知