官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

目录

https://www.cnblogs.com/bfyx/p/11364884.html

准备工作

自定义的分为控件和窗体2种类型,分别都有一个基类,基类实现公共的大部分工作

开始

首先从基类控件开始吧,

主要实现功能:

  1. 圆角
  2. 边框
  3. 填充颜色

添加一个用户控件,命名为UCControlBase,写入相关属性,包含圆角角度,边框颜色,边框宽度,填充颜色,背景色等

  private bool _isRadius = false;

         private int _cornerRadius = ;

         private bool _isShowRect = false;

         private Color _rectColor = Color.FromArgb(, , );

         private int _rectWidth = ;

         private Color _fillColor = Color.Transparent;
/// <summary>
/// 是否圆角
/// </summary>
[Description("是否圆角"), Category("自定义")]
public bool IsRadius
{
get
{
return this._isRadius;
}
set
{
this._isRadius = value;
}
}
//圆角角度
[Description("圆角角度"), Category("自定义")]
public int ConerRadius
{
get
{
return this._cornerRadius;
}
set
{
this._cornerRadius = value;
}
} /// <summary>
/// 是否显示边框
/// </summary>
[Description("是否显示边框"), Category("自定义")]
public bool IsShowRect
{
get
{
return this._isShowRect;
}
set
{
this._isShowRect = value;
}
}
/// <summary>
/// 边框颜色
/// </summary>
[Description("边框颜色"), Category("自定义")]
public Color RectColor
{
get
{
return this._rectColor;
}
set
{
this._rectColor = value;
this.Refresh();
}
}
/// <summary>
/// 边框宽度
/// </summary>
[Description("边框宽度"), Category("自定义")]
public int RectWidth
{
get
{
return this._rectWidth;
}
set
{
this._rectWidth = value;
}
}
/// <summary>
/// 当使用边框时填充颜色,当值为背景色或透明色或空值则不填充
/// </summary>
[Description("当使用边框时填充颜色,当值为背景色或透明色或空值则不填充"), Category("自定义")]
public Color FillColor
{
get
{
return this._fillColor;
}
set
{
this._fillColor = value;
}
}

需要做的就是重写OnPaint,来画边框以及填充颜色

 protected override void OnPaint(PaintEventArgs e)
{
if (this.Visible)
{
if (this._isRadius)
{
this.SetWindowRegion();
}
if (this._isShowRect)
{
Color rectColor = this._rectColor;
Pen pen = new Pen(rectColor, (float)this._rectWidth);
Rectangle clientRectangle = base.ClientRectangle;
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(, , _cornerRadius, _cornerRadius, 180f, 90f);
graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - , , _cornerRadius, _cornerRadius, 270f, 90f);
graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - , clientRectangle.Height - _cornerRadius - , _cornerRadius, _cornerRadius, 0f, 90f);
graphicsPath.AddArc(, clientRectangle.Height - _cornerRadius - , _cornerRadius, _cornerRadius, 90f, 90f);
graphicsPath.CloseFigure();
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
e.Graphics.DrawPath(pen, graphicsPath);
}
}
base.OnPaint(e);
} private void SetWindowRegion()
{
GraphicsPath path = new GraphicsPath();
Rectangle rect = new Rectangle(-, -, base.Width + , base.Height);
path = this.GetRoundedRectPath(rect, this._cornerRadius);
base.Region = new Region(path);
} private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
{
Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(rect2, 180f, 90f);//左上角
rect2.X = rect.Right - radius;
graphicsPath.AddArc(rect2, 270f, 90f);//右上角
rect2.Y = rect.Bottom - radius;
rect2.Width += ;
rect2.Height += ;
graphicsPath.AddArc(rect2, 360f, 90f);//右下角
rect2.X = rect.Left;
graphicsPath.AddArc(rect2, 90f, 90f);//左下角
graphicsPath.CloseFigure();
return graphicsPath;
}

至此基类控件就完成了,下面是完成代码

 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:UCControlBase.cs
// 创建日期:2019-08-15 16:04:12
// 功能描述:ControlBase
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D; namespace HZH_Controls.Controls
{
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
public partial class UCControlBase : UserControl, IContainerControl
{
private bool _isRadius = false; private int _cornerRadius = ; private bool _isShowRect = false; private Color _rectColor = Color.FromArgb(, , ); private int _rectWidth = ; private Color _fillColor = Color.Transparent;
/// <summary>
/// 是否圆角
/// </summary>
[Description("是否圆角"), Category("自定义")]
public bool IsRadius
{
get
{
return this._isRadius;
}
set
{
this._isRadius = value;
}
}
//圆角角度
[Description("圆角角度"), Category("自定义")]
public int ConerRadius
{
get
{
return this._cornerRadius;
}
set
{
this._cornerRadius = value;
}
} /// <summary>
/// 是否显示边框
/// </summary>
[Description("是否显示边框"), Category("自定义")]
public bool IsShowRect
{
get
{
return this._isShowRect;
}
set
{
this._isShowRect = value;
}
}
/// <summary>
/// 边框颜色
/// </summary>
[Description("边框颜色"), Category("自定义")]
public Color RectColor
{
get
{
return this._rectColor;
}
set
{
this._rectColor = value;
this.Refresh();
}
}
/// <summary>
/// 边框宽度
/// </summary>
[Description("边框宽度"), Category("自定义")]
public int RectWidth
{
get
{
return this._rectWidth;
}
set
{
this._rectWidth = value;
}
}
/// <summary>
/// 当使用边框时填充颜色,当值为背景色或透明色或空值则不填充
/// </summary>
[Description("当使用边框时填充颜色,当值为背景色或透明色或空值则不填充"), Category("自定义")]
public Color FillColor
{
get
{
return this._fillColor;
}
set
{
this._fillColor = value;
}
} public UCControlBase()
{
this.InitializeComponent();
base.SetStyle(ControlStyles.UserPaint, true);
base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
base.SetStyle(ControlStyles.DoubleBuffer, true);
} protected override void OnPaint(PaintEventArgs e)
{
if (this.Visible)
{
if (this._isRadius)
{
this.SetWindowRegion();
}
if (this._isShowRect)
{
Color rectColor = this._rectColor;
Pen pen = new Pen(rectColor, (float)this._rectWidth);
Rectangle clientRectangle = base.ClientRectangle;
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(, , _cornerRadius, _cornerRadius, 180f, 90f);
graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - , , _cornerRadius, _cornerRadius, 270f, 90f);
graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - , clientRectangle.Height - _cornerRadius - , _cornerRadius, _cornerRadius, 0f, 90f);
graphicsPath.AddArc(, clientRectangle.Height - _cornerRadius - , _cornerRadius, _cornerRadius, 90f, 90f);
graphicsPath.CloseFigure();
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
e.Graphics.DrawPath(pen, graphicsPath);
}
}
base.OnPaint(e);
} private void SetWindowRegion()
{
GraphicsPath path = new GraphicsPath();
Rectangle rect = new Rectangle(-, -, base.Width + , base.Height);
path = this.GetRoundedRectPath(rect, this._cornerRadius);
base.Region = new Region(path);
} private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
{
Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(rect2, 180f, 90f);//左上角
rect2.X = rect.Right - radius;
graphicsPath.AddArc(rect2, 270f, 90f);//右上角
rect2.Y = rect.Bottom - radius;
rect2.Width += ;
rect2.Height += ;
graphicsPath.AddArc(rect2, 360f, 90f);//右下角
rect2.X = rect.Left;
graphicsPath.AddArc(rect2, 90f, 90f);//左下角
graphicsPath.CloseFigure();
return graphicsPath;
} protected override void WndProc(ref Message m)
{
if (m.Msg != )
{
base.WndProc(ref m);
}
} }
}
  partial class UCControlBase
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
base.SuspendLayout();
base.AutoScaleDimensions = new SizeF(9f, 20f);
base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.DoubleBuffered = true;
this.Font = new Font("微软雅黑", 15f, FontStyle.Regular, GraphicsUnit.Pixel);
base.Margin = new Padding(, , , );
base.Name = "UCBase";
base.Size = new Size(, );
base.ResumeLayout(false);
} #endregion
}

用处及效果

用处:你可以把它当作一个panel来用,比如需要包裹一些控件并显示一个圆角边框的时候,你应该想到用这个控件

效果图:其实就是一个圆角边框的面板

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

(一)c#Winform自定义控件-基类控件的更多相关文章

  1. winform 自定义控件:半透明Loading控件

    winform  自定义控件:半透明Loading控件 by wgscd date:2015-05-05 效果: using System;using System.Drawing;using Sys ...

  2. (十七)c#Winform自定义控件-基类窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. C# 自定义控件VS用户控件

    1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container 控件,Container控件可以添加其他Con ...

  4. 自定义控件VS用户控件

    自定义控件VS用户控件 2015-06-16 1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container ...

  5. kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件

    该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...

  6. 富客户端 wpf, Winform 多线程更新UI控件

    前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...

  7. C# WinForm 跨线程访问控件

    问题出现: 在WinForm 处理多线程访问主线程的控件时候,就会出现如图所示的错误对话框:    解决方案:  方案一:去掉线程访问主线程UI控件的安全检查,使用: Control.CheckFor ...

  8. Winform跨窗体操作控件(使用委托)

    Winform跨窗体操作控件是winform开发中很常见的形式,最常见且简单有效的方式便是使用委托的方式来进行操作,下面我将通过一个小实例来说明如何使用委托跨窗体实现控件操作. 实例介绍:两个窗体,F ...

  9. Android开发技巧——自定义控件之组合控件

    Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...

随机推荐

  1. Zimg—轻量级图片服务器搭建利器

    在一个互联网应用中,图片扮演着越来越重要的角色.有稳定的可扩展的图片存储服务器就显得尤为的重要,云厂商们提供了便利的图片存储服务,花钱就可以解决了.这里简单介绍一个开源的一个分布式图片存储服务器--z ...

  2. 你懂什么叫js继承吗

    说到继承呢?肯定有很多做java的朋友都觉得是一个比较简单的东西了.毕竟面向对象的三大特征就是:封装.继承和多态嘛.但是真正对于一个javascript开发人员来说,很多时候其实你使用了继承,但其实你 ...

  3. C程序疑问解答 ——可怕的野指针

    本篇为原创,禁止任何形式的他用! 一.疑问点         指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程 ...

  4. .NET CORE上传文件到码云仓库【搭建自己的图床】

    .NET CORE上传文件到码云仓库[搭建自己的图床] 先建一个公共仓库(随意提交一个README文件或者.gitignore文件保证master分支的存在),然后到gitee的个人设置页面找到[私人 ...

  5. 【题解】导游-C++

    Description 宁波市的中小学生们在镇海中学参加程序设计比赛之余,热情的主办方邀请同学们参观镇海中学内的各处景点,已 知镇海中学内共有n处景点.现在有n位该校的学生志愿承担导游和讲解任务.每个 ...

  6. ubuntu18.04安装nvidia驱动总结经验

    本人电脑是 DELL Inspiron 3670, 系统装的是ubuntu18.04, 显卡使用的是GeForce GTX 1050 Ti, 在安装nividia显卡的时候花费两天时间,感受颇深,顾总 ...

  7. 和朱晔一起复习Java并发(三):锁(含锁性能测试)

    这个专题我发现怎么慢慢演化为性能测试了,遇到任何东西我就忍不住去测一把.本文我们会大概看一下各种锁数据结构的简单用法,顺便也会来比拼一下性能. 各种并发锁 首先,我们定一个抽象基类,用于各种锁测试的一 ...

  8. 【带着canvas去流浪(13)】用Three.js制作简易的MARVEL片头动画(下)

    目录 一. 模型的制作 1.1 生成字体模型 1.2 多表面贴图 二. 镜头及动画 三. 大作业总结 示例代码托管在:http://www.github.com/dashnowords/blogs 博 ...

  9. django中ORM的model对象和querryset 简单解析

    欢迎大家查看我的博客,我会不定时的用大白话发一些看了就能懂的文章,大家多多支持!如您对此文章内容有独特见解,欢迎与笔者练习一起探讨学习!原创文创!转载请注明出处! ORM是干嘛的? 介绍orm之前我应 ...

  10. 0004. 寻找两个有序数组的中位数(Java)

    4. 寻找两个有序数组的中位数 https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 最简单的就是用最简单的,把两个数组分别抽出然 ...