首页 > 其他分享 >Winform控件优化之自定义控件的本质【从圆角控件看自定义的本质,Region区域无法反锯齿的问题】

Winform控件优化之自定义控件的本质【从圆角控件看自定义的本质,Region区域无法反锯齿的问题】

时间:2024-09-30 17:46:12浏览次数:10  
标签:控件 圆角 自定义 Region roundBorderSize 本质 绘制

自定义控件的本质

自定义控件的本质只有两点:

  • 重绘控件Region区域(圆角、多边形、图片等),这是整个控件的真实范围。缺点是Region无法抗锯齿,自定义的Region范围是有锯齿的,无法消除;此外新的Region还会和绘制的背景产生1像素的白边(在圆角或图形拐角部分),且几乎无法有效的消除。【后续会介绍FillRegion填充区域,而不是绘制图形与Region产生'白边'】
  • 重绘图形,在原有Region【矩形区域】范围内,重绘不同的图形(圆角、多边形、图片等)作为背景,因为绘制图形时可以实现抗锯齿,因此看起来像无锯齿控件一样。本质上是在固定Region内绘制的尽可能大的无锯齿图形,因此需要注意设置透明背景(透明自定义图形外的Region部分)。

如果再加一条的话,自定义控件还有一点,就是:

  • 在原有控件上通过设置图片/图标、背景颜色、布局大小、多个不同控件组合等,同时结合重绘图形(或重绘Region区域),实现一定的自定义。

在其实现方法上,都是使用GDI/GDI+进行绘制,并添加一些默认的功能、事件或属性;组合控件也可能不需要使用GDI+绘制;还有一些基于基础控件的扩展控件,在原控件的基础上进行一些扩展,也用不到绘制方法。

赋值新Region和直接重绘图形的区别

无论是在控件的Paint事件方法中,还是通过继承控件在OnPaint方法中,重绘控件的两种方式:赋值新Region和直接重绘图形,在进行绘制时都有两个相同的区别。

  • 仅仅赋值新Region原则上不需要再重新绘制背景颜色、文本等;
  • 只要发生了绘制(无论直接在原Region上绘制图形、还是赋值了新Region后绘制图形),都需要再重新绘制文本。即绘制图形会覆盖原来的内容,需要背景、文本都进行绘制

不要使用e.ClipRectangle、不要直接修改Region

无论是在继承控件的OnPaint方法中,还是在控件的Paint事件方法中,都不要使用参数e.ClipRectangle作为控件重绘的区域(绘制图形或重新创建Region),原因之前文章已经介绍。

另外,对于赋值新Region,不要直接在代码中实现,原因和上面一样,在发生控件大小、位置、拖动等变化时,会发生显示错乱或不完全的部分(直接赋值Region则固定了Region区域),正确的做法还是要在Paint事件或OnPaint方法中。

Region区域无法反锯齿

没有最佳圆角最佳自定义控件的实现,除非可以创建无锯齿Region。

无法对Region反锯齿

【目前来说,自定义控件时新建Region没有最优雅或最优实现】,任何创建新Region的方法都是有锯齿的【个人所知

标签:控件,圆角,自定义,Region,roundBorderSize,本质,绘制
From: https://www.cnblogs.com/soliang/p/18442259

相关文章

  • Qt项目中,在main.cpp中定义了一个自定义组件,但是在编译的时候报错`undefined reference
    1、问题描述我在测试Qt项目的main.cpp中编写了如下代码:classMyWidget1:publicQWidget{Q_OBJECT};//main程序入口argc命令行变量的数量argv命令行变量的数组intmain(intargc,char*argv[]){//应用程序对象,在Qt中应用程序对象有且仅有一个QAppl......
  • PbootCMS默认面包屑导航样式修改及自定义的设置方法
    在使用PbootCMS建站时,如果需要对系统默认的面包屑(breadcrumb)标签样式进行修改,可以通过自定义参数来实现。下面详细介绍如何使用 {pboot:position} 标签,并自定义相关的参数。自定义面包屑标签基本语法{pboot:position}[position:breadcrumb]{/pboot:position}......
  • 用自定义函数镶嵌求解某年某月的天数
    首先分析年份年份分为1.平年2.闰年对于闰年的定义为可以被4整除并且不被100整除,或者可以被400整除部分代码如下​if((y%4==0&&y%100!=0)||y%400==0)//if判断年份是否是闰年​ 月份的判断一年有12个月,1~12个月中天数不同,其中可以用数组来表示自定......
  • ASP.NET WebApi OWIN 实现 OAuth 2.0(自定义获取 Token)
    ASP.NETWebApiOWIN实现OAuth2.0(自定义获取Token) 相关文章:ASP.NETWebApiOWIN实现OAuth2.0之前的项目实现,Token放在请求头的Headers里面,类似于这样:Accept:application/jsonContent-Type:application/jsonAuthorization:BearerpADKsjwMv927u...虽然这是......
  • vue2 自定义empty指令
    主要思路定义一个echarts图标,数据为空,image采用base64编码图标宽高根据父宽高自适应渲染echarts函数,切换清除图例定义暂无数据指令定义option/***暂无数据*@param{number}width*@param{number}height*@returnsoption*/functionemptyChartOptionFn(w......
  • UNICODE环境下,RichEditCtrl 控件 RTF字符串的读写
    UNICODE编译环境:RTF字符串的显示:如果是CRichEditView,可以直接用SetWindowText,输入的RTF字符串是UNCODE编码。如果是CRichEditCtrl,可以发消息显示,输入的字符串是UNCODE编码intCNoteView::SetRTF(TCHAR*pRtf) { intlen=_tcslen(pRtf); //::SendMessage(m_hWndREdit,EM_SE......
  • java-快速将普通main类变为javafx类,并加载自定义fxml
    java-快速将普通main类变为javafx类,并加载自定义fxml前提步骤1.普通类继承Application2.实现main方法3.写一个controller4.写一个fxml文件5.写start方法加载fxml6.具体代码7.运行即可前提使用自带javafx的jdk,这里使用的是jdk1.834,当然你可以使用其他的可行......
  • 开源模型应用落地-LangChain实用小技巧-文档分割器-自定义文档分割器(十三)
    一、前言  在LangChain框架中,文档分割器是一种将大段文本拆分成较小块或片段的算法或方法。其目标是创建可单独处理的可管理的片段,这在处理大型文档或数据集时通常是必要的。  而自定义文档分割器可以根据特定的需求和数据类型进行定制和配置,以便更好地适应应用程......
  • 【Ambari自定义组件集成】Ambari汉化,源码级修改手把手教程
    传统方式注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0Step1、找到代码位置:ambari-project\ambari-web\app\messages.js逐一替换Step2、下载我提供的汉化好的:message.jshttps://gitee.com/tt-bigdata/ambari-en-cn/blob/ma......
  • spring 常见注解记录+ 使用自定义注解与aop 记录接口请求参数
    注解定义:importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;importorg.springframework.core.annotation.Alias......