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.pswp.cn/news/284005.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284005.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284005.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

淺談 maxMemory , totalMemory , freeMemory 和 OOM 與 native Heap

作者:林冠宏 / 指尖下的幽靈 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguanh/ GitHub : https://github.com/af913337456/ 騰訊云專欄: https://cloud.tencent.com/deve…

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,更加注重機器學習整…

webpack開發Vue配置

一直以來使用webpack都是用的別人的配置,這幾天自己學習了一下。 項目地址:https://github.com/donghaohao... 新建整個工程 npm init安裝依賴,這里我們開發vue項目,npm install vue --save,然后是開發時的依賴npm ins…

ABP詳細教程——模塊類

概述模塊化是ABP vNext的最大亮點,也是ABP vNext框架的核心,而模塊類是ABP vNext框架模塊化的核心要素。這一章節,我就從模塊類的用法、運行機制、源代碼等層面,帶大家詳細了解ABP vNext的模塊類。用法在ABP的約定中,每…

[轉]Eureka工作原理

目錄 Eureka 工作原理 Eureka 核心概念 自我保護機制 Eureka 集群原理 Eurka 工作流程 總結 Eureka 工作原理 上節內容為大家介紹了,注冊中心 Eureka 產品的使用,以及如何利用 Eureka 搭建單臺和集群的注冊中心。這節課我們來繼續學習 Eureka&…

centos7下別名(alias)的特殊用法

版權聲明:轉載請注明出處:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79438200 參考:https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/ 正常情況下,定義過的別名&a…

解決WDCP3環境gbk網站編碼程序亂碼問題

因為默認WDCP V3版本環境編碼格式是UTF-8版本,如果我們程序采用的是GBK編碼肯定都會有亂碼問題。 我們到WDCP后臺,"網站管理"-"PHP設置",看到上圖所示,準備直接在線編輯PHP.INI文件。 這里我們找到"defa…

重談聯想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::一個替代側邊欄的新組件。它主要用于移動應…

MySQL添加用戶、刪除用戶與授權

MySql中添加用戶,新建數據庫,用戶授權,刪除用戶,修改密碼(注意每行后邊都跟個;表示一個命令語句結束): 1.新建用戶 1.1 登錄MYSQL: >mysql -u root -p >密碼 1.2 創建用戶: mysql> insert into mysql.user(Host,User,Password) values("lo…

[轉]高并發架構設計之--「服務降級」、「服務限流」與「服務熔斷」

目錄 服務降級 1 、簡介 2 、使用場景 3 、核心設計 3.1 分布式開關 3.2 自動降級分類 3.3 配置中心 3.4 處理策略 3.5 降級分類 3.6 服務降級要考慮的問題 4 、高級特性 4.1 分級降級 4.2 降級權值 5 、總結與展望 服務限流 一、為什么要做服務限流設計&…

【Linux】【Services】【nfs】nfs安裝與配置

1. 概念 1.1. NFS:Network File System,傳統意義上,文件系統在內核中實現。 1.2. RPC:Remote Procedure Call protocol,遠程過程調用,函數調用(遠程主機上的函數) 1.3. 端口&#xf…

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…