WinForm(三)揭开可视化控件的面纱

WinForm所见即所得的UI设计框架,开发效率确实有所提升,同时降低了编程门槛,让WinForm更普及。拖拖拽拽就能设计出一个界面,那么我们拖拽的这些东西是什么?它们是什么原理?。

WinForm我觉得很好的一点是,把所有东西都对像化(毕竟C#是面向对象的语言),包括可视化的窗体,控件等,当然有的控件在运行时是能看见的,比如按钮,文本框,下拉列表框等等,还有一类是在运时看不见的,比如Timers,FileSystemWatcher等。这些全都构建成了对象,那么看得见的控件是怎么看得见的呢?答案是绘制出来的,画出来才能看得见。是用GDI+技术画出来的。

为了能够让大家更深入的理解,我们现在画一个Switch控件,Switch是苹果体系里的控件,在WinForm中,系统控件是没有的。Switch的作用非常像CheckBox,所以我们就参照CheckBoxRenderer来画,只不过画的形状不一样,具体代码如下:

using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;namespace WinFormDemo02
{public class Switch : Control{private Rectangle textRectangleValue = new Rectangle();private CheckBoxState state = CheckBoxState.UncheckedNormal;public Switch(): base(){this.Location = new Point(50, 50);this.Size = new Size(50, 25);this.Font = SystemFonts.IconTitleFont;DoubleBuffered = true;SetStyle(ControlStyles.OptimizedDoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.AllPaintingInWmPaint, true);}public bool Checked{get; set;} = false;void DrawSwitch(Graphics g){var x = 0;var y = 0;var width = 25;g.SmoothingMode = SmoothingMode.HighQuality;g.PixelOffsetMode = PixelOffsetMode.HighQuality;g.InterpolationMode = InterpolationMode.High;g.CompositingQuality = CompositingQuality.HighQuality;SolidBrush brush;if (Checked){brush = new SolidBrush(Color.MediumSeaGreen);}else{brush = new SolidBrush(Color.DarkRed);}g.FillPie(brush, new Rectangle(x, y, width, width), 90, 180);g.FillRectangle(brush, new Rectangle(x + width / 2 - 1, y, width, width));g.FillPie(brush, new Rectangle(x + width - 2, y, width, width), -90, 180);if (Checked){var selectBrush = new SolidBrush(Color.White);g.FillEllipse(selectBrush, new Rectangle(x + 2, y + 2, width - 4, width - 4));}else{var selectBrush = new SolidBrush(Color.White);g.FillEllipse(selectBrush, new Rectangle(x + width, y + 2, width - 4, width - 4));}}public Rectangle TextRectangle{get{using (Graphics g = this.CreateGraphics()){textRectangleValue.X = ClientRectangle.X +CheckBoxRenderer.GetGlyphSize(g,CheckBoxState.UncheckedNormal).Width;textRectangleValue.Y = ClientRectangle.Y;textRectangleValue.Width = ClientRectangle.Width -CheckBoxRenderer.GetGlyphSize(g,CheckBoxState.UncheckedNormal).Width;textRectangleValue.Height = ClientRectangle.Height;}return textRectangleValue;}}protected override void OnPaint(PaintEventArgs e){DrawSwitch(e.Graphics);base.OnPaint(e);}public event EventHandler CheckedChanged;protected override void OnMouseDown(MouseEventArgs e){base.OnMouseDown(e);if (!Checked){Checked = true;state = CheckBoxState.CheckedPressed;Invalidate();}else{Checked = false;state = CheckBoxState.UncheckedNormal;Invalidate();}CheckedChanged(this,new EventArgs());}protected override void OnMouseHover(EventArgs e){base.OnMouseHover(e);state = Checked ? CheckBoxState.CheckedHot :CheckBoxState.UncheckedHot;Invalidate();}protected override void OnMouseUp(MouseEventArgs e){base.OnMouseUp(e);this.OnMouseHover(e);}protected override void OnMouseLeave(EventArgs e){base.OnMouseLeave(e);state = Checked ? CheckBoxState.CheckedNormal :CheckBoxState.UncheckedNormal;Invalidate();}}
}

我只是简单的实现了一下,重点在DrawSwitch这个方法,就是画两个半圆,中间是一个正方形,然后在上面画一个白圆,根据Checked属性,最上面的白圆在两边切换,仅此而以。

看一下运行结果吧(自行点击播放):

通过上面例子,不知你是否了解了可视化控件的实现方式。如果你是初学者,完整的思路不太通,没关系,理解到控件是画出来的就够了f83264a3298c8dba814c17f301318f6f.png,后面应该会说到GDI+的详细技术点。如果你是WinForm老手,可以自己实现一套自己的专用控件,把Window上的应用Run出Mac的感觉,甚至IOS的感觉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RestTemplate 详解

在项目中,当我们需要远程调用一个 HTTP 接口时,我们经常会用到 RestTemplate 这个类。这个类是 Spring 框架提供的一个工具类。Spring 官网对它的介绍如下: RestTemplate: The original Spring REST client with a synchronous, template met…

初识Spark2.0之Spark SQL

内存计算平台Spark在今年6月份的时候正式发布了spark2.0,相比上一版本的spark1.6版本,在内存优化,数据组织,流计算等方面都做出了较大的改变,同时更加注重基于DataFrame数据组织的MLlib,更加注重机器学习整…

ABP详细教程——模块类

概述模块化是ABP vNext的最大亮点,也是ABP vNext框架的核心,而模块类是ABP vNext框架模块化的核心要素。这一章节,我就从模块类的用法、运行机制、源代码等层面,带大家详细了解ABP vNext的模块类。用法在ABP的约定中,每…

[转]Eureka工作原理

目录 Eureka 工作原理 Eureka 核心概念 自我保护机制 Eureka 集群原理 Eurka 工作流程 总结 Eureka 工作原理 上节内容为大家介绍了,注册中心 Eureka 产品的使用,以及如何利用 Eureka 搭建单台和集群的注册中心。这节课我们来继续学习 Eureka&…

重谈联想5G编码投票事件

此前,司马南谈了联想好几个问题,其中最尖锐的要属国有资产流失,这是联想管理层无法回避的死穴。不过,司马南批判联想5G投票背刺H公司,这基本就是造谣了。当年,媒体把编码投票炒作的很厉害,抨击联…

JStorm2.1.1集群的安装和使用

为什么80%的码农都做不了架构师?>>> JStorm2.1.1集群的安装和使用 Storm是一个免费开源、分布式、高容错的实时计算系统,而JStorm是阿里巴巴开源的基于Storm采用Java重写的一套分布式实时流计算框架,在性能和支持的集群规模上做了…

Hystrix 原理

Hystrix是什么? Hystrix是Netflix开源库,这是一个针对分布式系统的延迟和容错库。 Hystrix 供分布式系统使用,提供延迟和容错功能,隔离远程系统、访问和第三方程序库的访问点,防止级联失败,保证复杂的分布…

「深度」无人机实名制政策特稿|市场看好、资本关注,“反黑飞”正在崛起

从政策和需求来看,“反黑飞”越来越重要,市场也正在不断崛起。 对于大多数人来说,今天是最适合明目张胆“装嫩”的六一儿童节。不过,在无人机厂商和无人机玩家的眼里,今天是无人机实名制政策正式实施的日子。 近年来&…

在navicat中新建数据库

前言: 在本地新建一个名为editor的数据库; 过程: 1.; 2.选择:utf8mb4 -- UTF-8 Unicode字符集,原因在于:utf8mb4兼容utf8,且比utf8能表示更多的字符。,而且它支持表情符号…

MASA Stack 第三期社区例会

MASA Blazor 0.5.0发版内容功能Autocomplete:支持通过设置AutoSelectFirst参数开启自动选择第一项的功能,支持CacheItems参数,增强使用上下键的用户体验。BottomNavigation::一个替代侧边栏的新组件。它主要用于移动应…

[转]高并发架构设计之--「服务降级」、「服务限流」与「服务熔断」

目录 服务降级 1 、简介 2 、使用场景 3 、核心设计 3.1 分布式开关 3.2 自动降级分类 3.3 配置中心 3.4 处理策略 3.5 降级分类 3.6 服务降级要考虑的问题 4 、高级特性 4.1 分级降级 4.2 降级权值 5 、总结与展望 服务限流 一、为什么要做服务限流设计&…

SpringBoot获取ApplicationContext

2019独角兽企业重金招聘Python工程师标准>>> 有两种方法: 创建Component实现ApplicationContextAware接口,SpringBoot会自动调用这个类的setApplicationConext()方法。鼓励使用这种方式。SpringApplication.run(MyApplication.class, args)这…

SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)

此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错。投篮小游戏规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮…

zuul集成ribbon完成服务通信和负载均衡

目录 Zuul2服务通信 超时相关 默认超时配置 自定义超时配置 负载均衡 Zuul2服务通信 描述:zuul2通过Ribbon完成客户端负载均衡以及与服务器群集进行通信。 zuul2的通信是集成Ribbon实现的,在Origin中集成Ribbon基本配置(例如IClientCo…

时任上海来伊份互联网事业群总裁王戈钧 :传统企业(线上+线下)移动互联网改造...

2017年12月22日-23日,第13届信息化领袖峰会暨2017中国数字化贡献人物颁奖盛典在上海盛大开幕。本次峰会由上海市经济和信息化委员会指导,上海市国有资产信息中心、上海市计算机用户协会、上海市信息服务业行业协会、上海大数据联盟、上海市高等教育学会支…

【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信

接下来的内容,我会以从头开发一个简单的基于modbus tcp通信的案例,来实现一个基础的通信功能。有关环境:开发环境:VS 2022企业版运行环境:Win 10 专业版.NET 环境版本:.NET 6【备注】 源码在文末 1、新建一…

源码深度剖析Eureka与Ribbon服务发现原理

本文基于 spring cloud dalston,同时文章较长,请选择舒服姿势进行阅读。 Eureka 与 Ribbon 是什么?和服务发现什么关系? Eureka 与 Ribbon 都是 Netflix 提供的微服务组件,分别用于服务注册与发现、负载均衡。同时&a…

std的find和reverse_iterator联合使用

上代码&#xff1a; // test2013.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include<iostream> #include<vector> #include<map> #include<string> using namespace …

论如何提升学习的能力

为啥要学习如果有一件事情是能改变你自己的&#xff0c;我想这件事情必然就是学习&#xff0c;我的人生重要的转折点也是从学习这件事情始发的&#xff0c;那么&#xff0c;我们就从这里开始。学习不仅仅是为了找到答案&#xff0c;而是为了找到方法&#xff0c;找到一个可以找…

CSS布局解决方案(终结版)

前端布局非常重要的一环就是页面框架的搭建&#xff0c;也是最基础的一环。在页面框架的搭建之中&#xff0c;又有居中布局、多列布局以及全局布局&#xff0c;今天我们就来总结总结前端干货中的CSS布局。 居中布局 水平居中 1&#xff09;使用inline-blocktext-align&#xff…