c# 自定义多个SplitContainer 支持点击放大缩小

设计起因:最近在做winfrom自定义打印工具,其中项目中需要为打印界面分四个区 于是想到了splitcontainer,由于是在tabcontrol中放入splitcontainer,所以做成自定义splitcontainer是没毛病的

1.先介绍自定义单个SplitContainer放大缩小:

在自己的winfrom项目下新建一个组件类,名为SplitContainerEx.cs

然后写上如下代码,具体可以自己看

  1     public partial class SplitContainerEx : SplitContainer
  2     {
  3         enum MouseState
  4         {
  5             /// <summary>
  6             /// 正常
  7             /// </summary>
  8             Normal,
  9             /// <summary>
 10             /// 鼠标移入
 11             /// </summary>
 12             Hover
 13         }
 14
 15         public SplitContainerEx()
 16         {
 17             this.SetStyle(
 18                 ControlStyles.UserPaint |
 19                 ControlStyles.AllPaintingInWmPaint |
 20                 ControlStyles.OptimizedDoubleBuffer, true);
 21             this.SplitterWidth = 11;
 22             this.Panel1MinSize = 0;
 23             this.Panel2MinSize = 0;
 24             this.Orientation = Orientation.Horizontal;
 25             this.SplitterDistance = 50;
 26         }
 27
 28         [Browsable(false)]
 29         [EditorBrowsable(EditorBrowsableState.Never)]
 30         public new int SplitterWidth
 31         {
 32             get
 33             {
 34                 return base.SplitterWidth;
 35             }
 36             set
 37             {
 38                 base.SplitterWidth = 11;
 39             }
 40         }
 41
 42         [Browsable(false)]
 43         [EditorBrowsable(EditorBrowsableState.Never)]
 44         public new int Panel1MinSize
 45         {
 46             get
 47             {
 48                 return base.Panel1MinSize;
 49             }
 50             set
 51             {
 52                 base.Panel1MinSize = 0;
 53             }
 54         }
 55
 56         [Browsable(false)]
 57         [EditorBrowsable(EditorBrowsableState.Never)]
 58         public new int Panel2MinSize
 59         {
 60             get
 61             {
 62                 return base.Panel2MinSize;
 63             }
 64             set
 65             {
 66                 base.Panel2MinSize = 0;
 67             }
 68         }
 69
 70         public enum SplitterPanelEnum
 71         {
 72             Panel1,
 73             Panel2
 74         }
 75
 76         SplitterPanelEnum mCollpasePanel = SplitterPanelEnum.Panel1;
 77         /// <summary>
 78         /// 进行折叠或展开的SplitterPanel
 79         /// </summary>
 80         [DefaultValue(SplitterPanelEnum.Panel2)]
 81         public SplitterPanelEnum CollpasePanel
 82         {
 83             get
 84             {
 85                 return mCollpasePanel;
 86             }
 87             set
 88             {
 89                 if (value != mCollpasePanel)
 90                 {
 91                     mCollpasePanel = value;
 92                     this.Invalidate(this.ControlRect);
 93                 }
 94             }
 95         }
 96
 97         bool mCollpased = false;
 98         /// <summary>
 99         /// 是否为折叠状态
100         /// </summary>
101         public bool IsCollpased
102         {
103             get { return mCollpased; }
104         }
105
106         Rectangle mRect = new Rectangle();
107         /// <summary>
108         /// 控制器绘制区域
109         /// </summary>
110         private Rectangle ControlRect
111         {
112             get
113             {
114                 if (this.Orientation == Orientation.Horizontal)
115                 {
116                     mRect.X = this.Width <= 80 ? 0 : this.Width / 2 - 40;
117                     mRect.Y = this.SplitterDistance;
118                     mRect.Width = 80;
119                     mRect.Height = 11;
120                 }
121                 else
122                 {
123                     mRect.X = this.SplitterDistance;
124                     mRect.Y = this.Height <= 80 ? 0 : this.Height / 2 - 40;
125                     mRect.Width = 11;
126                     mRect.Height = 80;
127                 }
128                 return mRect;
129             }
130         }
131
132
133         private Rectangle ControlRect1
134         {
135             get
136             {
137                 mRect.X = 0;
138                 mRect.Y = this.SplitterDistance;
139                 mRect.Width = 80;
140                 mRect.Height = 11;
141                 return mRect;
142             }
143         }
144
145         /// <summary>
146         /// 鼠标状态
147         /// </summary>
148         MouseState mMouseState = MouseState.Normal;
149
150         protected override void OnPaint(PaintEventArgs e)
151         {
152             base.OnPaint(e);
153             //绘制参数
154             bool collpase = false;
155             if ((this.CollpasePanel == SplitterPanelEnum.Panel1 && mCollpased == false)
156                 || this.CollpasePanel == SplitterPanelEnum.Panel2 && mCollpased)
157             {
158                 collpase = true;
159             }
160             Color color = mMouseState == MouseState.Normal ? SystemColors.ButtonShadow : SystemColors.ControlDarkDark;
161             //需要绘制的图片
162             Bitmap bmp = CreateControlImage(collpase, color);
163             //绘制区域
164             if (this.Orientation == Orientation.Vertical)
165             {
166                 bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
167             }
168             //清除绘制区域
169             e.Graphics.SetClip(this.SplitterRectangle);   //这里需要注意一点就是需要清除拆分器整个区域,如果仅清除控制按钮区域,则会出现虚线状态
170             e.Graphics.Clear(this.BackColor);
171             //绘制
172             e.Graphics.DrawImage(bmp, this.ControlRect);
173
174             e.Graphics.DrawString("text", new System.Drawing.Font("宋体", 9), new SolidBrush(Color.Black), this.ControlRect1);
175         }
176
177         public new bool IsSplitterFixed
178         {
179             get
180             {
181                 return base.IsSplitterFixed;
182             }
183             set
184             {
185                 base.IsSplitterFixed = value;
186                 //此处设计防止运行时更改base.IsSplitterFixed属性时导致mIsSplitterFixed变量判断失效
187                 if (value && mIsSplitterFixed == false)
188                 {
189                     mIsSplitterFixed = true;
190                 }
191             }
192         }
193
194         bool mIsSplitterFixed = true;
195         protected override void OnMouseMove(MouseEventArgs e)
196         {
197             //鼠标在控制按钮区域
198             if (this.SplitterRectangle.Contains(e.Location))
199             {
200                 if (this.ControlRect.Contains(e.Location))
201                 {
202                     //如果拆分器可移动,则鼠标在控制按钮范围内时临时关闭拆分器
203                     if (this.IsSplitterFixed == false)
204                     {
205                         this.IsSplitterFixed = true;
206                         mIsSplitterFixed = false;
207                     }
208                     this.Cursor = Cursors.Hand;
209                     mMouseState = MouseState.Hover;
210                     this.Invalidate(this.ControlRect);
211                 }
212                 else
213                 {
214                     //如果拆分器为临时关闭,则开启拆分器
215                     if (mIsSplitterFixed == false)
216                     {
217                         this.IsSplitterFixed = false;
218                         if (this.Orientation == Orientation.Horizontal)
219                         {
220                             this.Cursor = Cursors.HSplit;
221                         }
222                         else
223                         {
224                             this.Cursor = Cursors.VSplit;
225                         }
226                     }
227                     else
228                     {
229                         this.Cursor = Cursors.Default;
230                     }
231                     mMouseState = MouseState.Normal;
232                     this.Invalidate(this.ControlRect);
233                 }
234             }
235             base.OnMouseMove(e);
236         }
237
238         protected override void OnMouseLeave(EventArgs e)
239         {
240             this.Cursor = Cursors.Default;
241             mMouseState = MouseState.Normal;
242             this.Invalidate(this.ControlRect);
243             base.OnMouseLeave(e);
244         }
245
246         protected override void OnMouseClick(MouseEventArgs e)
247         {
248             if (this.ControlRect.Contains(e.Location))
249             {
250                 CollpaseOrExpand();
251             }
252             base.OnMouseClick(e);
253         }
254
255         int _HeightOrWidth;
256         /// <summary>
257         /// 折叠或展开
258         /// </summary>
259         public void CollpaseOrExpand()
260         {
261             if (mCollpased)
262             {
263                 mCollpased = false;
264                 this.SplitterDistance = _HeightOrWidth;
265             }
266             else
267             {
268                 mCollpased = true;
269                 _HeightOrWidth = this.SplitterDistance;
270                 if (CollpasePanel == SplitterPanelEnum.Panel1)
271                 {
272                     this.SplitterDistance = 0;
273                 }
274                 else
275                 {
276                     if (this.Orientation == Orientation.Horizontal)
277                     {
278                         this.SplitterDistance = this.Height - 9;
279                     }
280                     else
281                     {
282                         this.SplitterDistance = this.Width - 9;
283                     }
284                 }
285             }
286             this.Invalidate(this.ControlRect); //局部刷新绘制
287         }
288
289
290         /// <summary>
291         /// 需要绘制的用于折叠窗口的按钮样式
292         /// </summary>
293         /// <param name="collapse"></param>
294         /// <param name="color"></param>
295         /// <returns></returns>
296         private Bitmap CreateControlImage(bool collapse, Color color)
297         {
298             Bitmap bmp = new Bitmap(80, 9);
299             for (int x = 5; x <= 30; x += 5)
300             {
301                 for (int y = 1; y <= 7; y += 3)
302                 {
303                     bmp.SetPixel(x, y, color);
304                 }
305             }
306             for (int x = 50; x <= 75; x += 5)
307             {
308                 for (int y = 1; y <= 7; y += 3)
309                 {
310                     bmp.SetPixel(x, y, color);
311                 }
312             }
313             //控制小三角底边向上或者向下
314             if (collapse)
315             {
316                 int k = 0;
317                 for (int y = 7; y >= 1; y--)
318                 {
319                     for (int x = 35 + k; x <= 45 - k; x++)
320                     {
321                         bmp.SetPixel(x, y, color);
322                     }
323                     k++;
324                 }
325             }
326             else
327             {
328                 int k = 0;
329                 for (int y = 1; y <= 7; y++)
330                 {
331                     for (int x = 35 + k; x <= 45 - k; x++)
332                     {
333                         bmp.SetPixel(x, y, color);
334                     }
335                     k++;
336                 }
337             }
338             return bmp;
339         }

可以在工具箱中看到就算完成了。

2.多个自定义splitcontainer

新建一个组件类,名为FreeSplit.cs,继承UserControl类 就可以任意拖动刚才自定义的splitcontainer了。效果如下

3.在tabcontrol中铺满

        private int _componentCount = 0;
        private void toolStripButton4_Click(object sender, EventArgs e)
        {

            TabPage tabpage = new TabPage("New" + _userControlCount);
            propertyGrid.FreeSplit sp = new propertyGrid.FreeSplit();
            sp.Parent = tabpage;
            sp.Dock = DockStyle.Fill;//控件的各个边缘分别停靠在其包含控件的各个边缘,并且适当调整大小
            tabControl1.TabPages.Add(tabpage);
            tabControl1.SelectedIndex = tabControl1.TabPages.Count - 1;

        }

原文地址:https://www.cnblogs.com/cxyzhangjie/p/8364854.html

时间: 2024-10-08 09:52:14

c# 自定义多个SplitContainer 支持点击放大缩小的相关文章

图片浏览(点击放大缩小支持多张图片浏览)

大神写的,我就参考参考啦! 从主布局开始了 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_pare

自定义圆形图片实现多点触控放大缩小和拖动

自定义imageview package com.bwie.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import androi

UIImageView 点击放大缩小

static CGRect oldframe; -(void)showImage:(UIImageView *)avatarImageView{ UIImage *image=avatarImageView.image; UIWindow *window=[UIApplication sharedApplication].keyWindow; UIView *backgroundView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScree

iOS 图片点击放大, 再次点击缩小

XWScanImage  是一个自定义的类, 评论留Q 发 ImageView = [[UIImageView alloc]init]; ImageView.backgroundColor = SetColor(160, 160, 160); //为UIImageView1添加点击事件 UITapGestureRecognizer *tapGestureRecognizer1 = [[UITapGestureRecognizer alloc] initWithTarget:self action

Android 自定义的数字键盘 支持随意拖动 和稳定的字符输入的控件

经过 研究 实现了自定义 键盘 ,支持随意拖动 和数字及其他字符输入 下面是主要的代码 和使用方法 import android.content.Context; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.Gravity; import android.view.Mo

源泉书签 支持 点击标签直接跳出标签下的书签

源泉书签www.yuanquanshuqian.com已经支持 点击 标签目录  直接跳出相关标签的书签了,没有任何多余操作,感兴趣的同学试试. 花了很长时间做的,进一步提高了书签的便捷性. 版权声明:本文为博主原创文章,未经博主允许不得转载.

Android自定义适配器和ListView的点击事件相结合的使用

下边演示一个使用ListView和自定义适配器的案例,点击ListView中的条目会出现一个对话框,进行成绩的修改,修改之后会立即通知适配器进行数据的重新加载,如下: (1).用于显示listView的布局文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" andro

php如何实现图片点击下载,并保存本地?-----本例子为二维码的生成图片,并支持点击下载

### 今天因为工作需要,完成了一个二维码的生成图片,并支持点击下载的 ### 控制器文件,相关代码 1 // 生成二维码 2 $url = action('Apih5\\[email protected]', ['provider' => $request->channel]); 3 // 保存二维码到本地,并返回二维码 4 $qrcode = $this->app['version']->qrcode($url); 5 $dir_path = '../public/static

图标放大缩小移动,加标注点,并带点击效果的实现

第一:了解三个类 Canvas,在英语中,这个单词的意思是帆布.在Android中,则把Canvas当做画布,只要我们借助设置好的画笔(Paint类)就可以在画布上绘制我们想要的任何东西:另外它也是显示位图(Bitmap类)的核心类.随用户的喜好,Canvas还可设置一些关于画布的属性,比如,画布的颜色.尺寸等.Canvas提供了如下一些方法: 一种就是使用普通View的canvas画图,还有一种就是使用专门的SurfaceView的canvas来画图.两种的主要是区别就是可以在SurfaceV