C#自定义控件—转换开关
C#用户控件之转换开关
如何自定义一个转换键(Toggle)?
三步绘制一个精美控件:
- 定义属性;
- 画布重绘;
- 添加事件;
主要技能:
- 如何自定义属性;
- 画布重绘的一般格式;
- 控件的事件触发过程;
- 技能扩展
转换按钮使能时添加二次确认弹框?
在From窗体中应用控件时,点击事件没有触发?
属性名称在控件属性树中的排列如何定义?
添加一个字体更改属性?
1.定义属性
- 字体(Font)
- 颜色(Color)
- 字符串(String)
- 枚举(Enum)
- 属性说明 [Browsable(true)]
#region 属性
private Font displayFont = new Font("Segoe UI", 12);
[Browsable(true)]
[Category("布局_G")]
[Description("字体格式")]
public Font DisplayFont
{
get { return displayFont; }
set
{
if (value != null)
{
displayFont = value;
this.Invalidate(); // Trigger redraw
}
}
}
private bool _checked = false;
[Browsable(true)] //说明(需放在属性前边):是否选中
[Category("布局_G")]
[Description("是否选中")]
public bool Checked
{
get { return _checked; }
set
{
_checked = value;
this.Invalidate();
//激活触发事件
this.MouseDown_G?.Invoke(this, null);
}
}
private string falseText = "关闭";
[Browsable(true)] //说明:文本关闭
[Category("布局_G")]
[Description("文本关闭")]
public string FalseText
{
get { return falseText; }
set { falseText = value; this.Invalidate(); }
}
//样式切换
public enum SwType
{
Ellipse, //椭圆
Rectangle, //矩形
}
private SwType switchType = SwType.Ellipse;
[Browsable(true)] //说明:切换样式
[Category("布局_G")]
[Description("切换样式")]
public SwType SwitchType
{
get { return switchType; }
set { switchType = value; this.Invalidate(); }
}
private Color sliderColor = Color.White; //Color.White
[Browsable(true)] //说明:滑块颜色
[Category("布局_G")]
[Description("滑块颜色")]
public Color SliderColor
{
get { return sliderColor; }
set { sliderColor = value; this.Invalidate(); }
}
#endregion
属性名称在控件属性树中的排列如何定义?
答:根据属性说明安装A~Z的字母顺序排列
2.画布重绘
- 画带四角圆弧的矩形、滑块、文本;
- 画椭圆、滑块、文本
#region 画布
private Graphics graphics;
private int width;
private int height;
//矩形绘制
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
graphics = e.Graphics;
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
this.width = this.Width;
this.height = this.Height;
if (this.switchType == SwType.Rectangle) //字段选择为矩形时
{
//填充色
Color fillColor = this._checked ? trueColor : falseColor;
//带四角圆弧的矩形
GraphicsPath path = new GraphicsPath();
int diameter = 10; //默认圆弧直径
//左上角圆弧:起始坐标,宽,高,开始角度,扫描角度
path.AddArc(0, 0, diameter, diameter, 180f, 90f);
path.AddArc(this.width - diameter, 0, diameter, diameter, 270f, 90f); //右上角
path.AddArc(this.width - diameter, this.height - diameter, diameter, diameter, 0f, 90f); //右下角
path.AddArc(0, this.height - diameter, diameter, diameter, 90f, 90f); //左下角
graphics.FillPath(new SolidBrush(fillColor), path); //填充色
//文本
string strText = this._checked ? trueText : falseText;
//滑块(true\false 两种形态)
if (_checked)
{
//绘制滑块
path = new GraphicsPath();
int sliderwidth = this.height - 4;
path.AddArc(this.width - sliderwidth - 2, 2, diameter, diameter, 180f, 90f);
path.AddArc(this.width - diameter - 2, 2, diameter, diameter, 270f, 90f);
path.AddArc(this.width - diameter - 2, this.height - diameter - 2, diameter, diameter, 0f, 90f);
path.AddArc(this.width - sliderwidth - 2, this.height - diameter - 2, diameter, diameter, 90f, 90f);
graphics.FillPath(new SolidBrush(sliderColor), path);
//绘制文本
Rectangle rec = new Rectangle(0, 0, this.width - sliderwidth - 2, this.height);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
graphics.DrawString(strText, DisplayFont, new SolidBrush(sliderColor), rec, sf);
}
else
{
//绘制滑块
path = new GraphicsPath();
int sliderwidth = this.height - 4;
path.AddArc(2, 2, diameter, diameter, 180f, 90f);
path.AddArc(sliderwidth - diameter + 2, 2, diameter, diameter, 270f, 90f);
path.AddArc(sliderwidth - diameter + 2, sliderwidth - diameter + 2, diameter, diameter, 0f, 90f);
path.AddArc(2, sliderwidth - diameter + 2, diameter, diameter, 90f, 90f);
graphics.FillPath(new SolidBrush(sliderColor), path);
//绘制文本
Rectangle rec = new Rectangle(sliderwidth + 2, 0, this.width - sliderwidth - 2, this.height);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
graphics.DrawString(strText, DisplayFont, new SolidBrush(sliderColor), rec, sf);
}
}
else if (this.switchType == SwType.Ellipse) //字段选择为椭圆时
{
//填充色
Color fillColor = this._checked ? trueColor : falseColor;
//椭圆形
GraphicsPath path = new GraphicsPath();
path.AddArc(1, 1, this.height - 2, this.height - 2, 90f, 180f);
path.AddArc(this.width - (this.height - 2) - 1, 1, this.height - 2, this.height - 2, 270f, 180f);
graphics.FillPath(new SolidBrush(fillColor), path); //填充色
//文本
string strText = this._checked ? TrueText : falseText;
//滑块(true\false 两种形态)
if (_checked)
{
//绘制滑块
int ciclewidth = this.height - 6;
graphics.FillEllipse(new SolidBrush(sliderColor), new Rectangle(this.width - ciclewidth - 3, 3, ciclewidth, ciclewidth));
//绘制文本
Rectangle rec = new Rectangle(0, 0, this.width - ciclewidth - 3, this.height);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
graphics.DrawString(strText, DisplayFont, new SolidBrush(sliderColor), rec, sf);
}
else
{
//绘制滑块
int ciclewidth = this.height - 6;
graphics.FillEllipse(new SolidBrush(sliderColor), new Rectangle(3, 3, ciclewidth, ciclewidth));
//绘制文本
Rectangle rec = new Rectangle(ciclewidth + 3, 0, this.width - ciclewidth - 3, this.height);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
graphics.DrawString(strText, DisplayFont, new SolidBrush(sliderColor), rec, sf);
}
}
}
#endregion
3.添加事件
理解 :在From中控件的鼠标点击事件的执行过程
先执行控件内部的MouseDown方法——其方法内部的属性——其属性中的触发事件——最后执行From后台的点击生成的自定义方法(可自定义)
其他技巧: 应用控件时拉出来双击即可生成自定义方法
<From中双击控件默认是Load方法,想让他自动生成自己设置的事件需要在控件代码中添加:[DefaultEvent("MouseDown_G")]>。
//指定默认事件(双击控件进入)
[DefaultEvent("MouseDown_G")]
关键代码:点击控件弹出框确认后再执行From的事件中的代码
//事件声明 public event EventHandler MouseDown_G;
//激活事件 this.MouseDown_G?.Invoke(this, null); ——执行完成跳转到From中的双击事件方法中
//构造函数添加鼠标点击事件——点击控件事件处理
this.MouseDown += Toggle_MouseDown;
//构造函数添加事件处理后自动生成此方法(无需在控件的属性中双击)
private void Toggle_MouseDown(object sender, MouseEventArgs e)
{
DialogResult dr = MessageBox.Show("二次确认操作?", "提示您", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (dr == DialogResult.OK)
{
Checked = !Checked;
}
else return;
}
发现一个错误,当应用该控件时,在From中点击无效;经过两天的查询(断点查询)才发现问题所在,在Form的设计器中的From属性的Enable为False,改为true才可使能
原因:控件更新后没有及时生成导致From崩盘后(空窗口后没在意),导致Designer的默认代码更改。
End
讨论交流请留言
C#自定义控件—转换开关的更多相关文章
- android自定义控件一站式入门
自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...
- ASP.NET MVC学习之母版页和自定义控件的使用
一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...
- C# 自定义控件VS用户控件
1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container 控件,Container控件可以添加其他Con ...
- 自定义控件之 圆形 / 圆角 ImageView
一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的: 二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...
- 如何开发FineReport的自定义控件?
FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...
- WPF自定义控件第二 - 转盘按钮控件
继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...
- 【Win 10应用开发】AdaptiveTrigger在自定义控件中是可以触发的
前些天,看到有网友给我留言,说AdaptiveTrigger在自定义控件(模板化控件)中不能触发.因为当时我正在写其他的代码,就没有去做实验来验证,于是我就给这位网友提了使用GotoVisualSta ...
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- Android自定义控件之自定义ViewGroup实现标签云
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
- Android自定义控件之自定义组合控件
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
随机推荐
- python3 webssh
简介 webssh 是 一个简单的 Web 应用程序,用作 ssh 客户端来连接到 ssh 服务器.它是用Python编写的,基于tornado.paramiko和xterm.js.下面简单搭建一个网 ...
- Maven的依赖详解和打包方式
设置maven maven下载与安装教程: https://blog.csdn.net/YOL888666/article/details/122008374 1. 在File->setting ...
- Spring的xml和注解对比
常用注解 bean定义 XML方式:<bean></bean> 注解方式:@Component 通用组件 @Controller(web层) @Service(service层 ...
- C++ Cast And Go Cast
C++ A static_cast can be used to explicitly convert between related pointer types, such as void* and ...
- openGL之多线程渲染
随着Vulkan的引入,我们的图形技术的发展到达了一个新的顶点,但是呢,我们的老干爹OpenGL作为落日余晖,他在一些Vulkan才有的新功能上,也提供了一些支持,现在我们来讨论一下OpenGL之多线 ...
- 关于android的图像视图的基本了解
最好直接复制进去而不是拖进去 图片直接导入最好用小写字母命名,数字与字母之间要用_,而且数字好像不可以连用 centerInside,fitCenter,center的区别: centerInside ...
- 假期小结3Hadoop学习
学习Hadoop是一个很好的选择,因为它是大数据处理和分析领域最流行的框架之一.Hadoop提供了可靠.可扩展的分布式数据处理能力,适用于处理大规模数据和构建可靠的数据管道. 在学习Hadoop时,以 ...
- python 音频处理(1)——重采样、音高提取
采集数据->采样率调整 使用torchaudio进行重采样(cpu版) 首先导入相关包,既然使用torch作为我们的选项,安装torch环境我就不必多说了,如果你不想用torch可以使用后文提到 ...
- LangChain的LCEL和Runnable你搞懂了吗
LangChain的LCEL估计行业内的朋友都听过,但是LCEL里的RunnablePassthrough.RunnableParallel.RunnableBranch.RunnableLambda ...
- 【MySQL】DB-Link 跨库访问
相关说明: https://blog.csdn.net/qq_48721706/article/details/124088963 DB-LINK以一个远程访问方式访问其他MYSQL实例 连接实例和被 ...