C# Window form 自定义控件的结构和设计(三)

C# Window form 自定义控件的结构和设计(三)

一、前面介绍了如何来创建第一个自定义的控件,以及一个测试程序。下面我们来看下如何在自定义控件中添加属性。

C#和其他.NET语言支持属性作为语言的第一类成员。把属性作为语言的基础属性有两点主要的有点:

①利用属性使放射返回一个类的属性更加简单。

②编写代码时,我们可以取得或者设置属性,就像取得或者设置一个类的成员变量一样。

接下来,我们来创建一个实现许多属性的自定义控件。

Snipaste_2024-04-14_19-18-13

和之前的程序一样修改基类为System.Windows.Forms.Control。

第一步在类中添加属性值,如下所示:

  public enum TextDirection
        {
            VerticalText,
            HorizonalText
        };
        
       // 字段名称
          要输出的文本
        private string displayText;
        // 文本被输出的次数
        private int displayCount;
        // 文本被显示的颜色
        private Color textColor;
        // 用来显示文本的字体
        private Font textFont;
        // 文本显示方向
        private TextDirection textDirection;
        // 文本显示位置
        private Point startDisplayPoint;
        
        // 属性实现
        public string DisplayText
        {
            get { return displayText; }
            set { displayText = value; Invalidate(); }
        }
         public int DisplayCount
        {
            get { return displayCount; }
            set { displayCount = value; Invalidate(); }
        }
         public Color TextColor
        {
            get { return textColor; }
            set { textColor = value; Invalidate(); }
        }
         public Font TextFont
        {
            get { return textFont; }
            set { textFont = value; Invalidate(); }
        }
          public TextDirection TextDirect
        {
            get { return textDirection; }
            set { textDirection = value; Invalidate(); }
        }
         public Point StartDisplayPoint
        {
            get { return startDisplayPoint; }
            set { startDisplayPoint = value; Invalidate(); }
        }

第二步然后添加一个控件Paint事件,代码如下:

 Graphics g = e.Graphics;
            g.FillRectangle(Brushes.White, ClientRectangle);
            PointF point = StartDisplayPoint;
            Brush brush = new SolidBrush(textColor);
            StringFormat sf = new StringFormat();
            if (TextFont == null)
                TextFont = new Font("Times New Roman", 12);
            if (TextDirect == TextDirection.VerticalText)
                sf.FormatFlags = StringFormatFlags.DirectionVertical;

            for (int nCount = 0; nCount < displayCount; nCount++)
            {
                g.DrawString(displayText, TextFont, brush, point.X, point.Y, sf);
                if (TextDirect == TextDirection.VerticalText)
                    point.X += TextFont.GetHeight();
                else
                    point.Y += TextFont.GetHeight();
            }

运行程序,生成一个CustomControlWithProperties.dll。

接下来我们,我们生成一个测试程序,如下图:

Snipaste_2024-04-14_18-54-53

在窗体编辑器中可以看到我们刚才生成的控件。拖放到窗体中,在右边的控件属性窗口中,我们看到了我们刚才自定义的控件属性值。

二、属性的默认值

在上面自定义控件代码中,所有的属性都是空白的。但是在很多情况下,我们需要把属性值设置为有意义的值。我们需要注意两个问题:

①确定属性是在控件代码中初始化的。

②确定VS编译器了解默认值。

在刚才的程序中,我们添加默认的属性值。代码如下:

 private string displayText = "GoodBye,World";
        // 文本被输出的次数
        private int displayCount = 5;
        // 文本被显示的颜色
        private Color textColor = Color.Lime;
        // 用来显示文本的字体
        private Font textFont = new Font("Times New Roman", 12);
        // 文本显示方向
        private TextDirection textDirection = TextDirection.VerticalText;
        // 文本显示位置
        private Point startDisplayPoint = new Point(6, 6);

我们需要将默认值显示到VS的属性窗口中,有两种方式:

①在属性的声明前设置一个属性。

在DisplayText,DisplayCount,TextDirect属性中设置如下属性:

// 属性的实现
        [DefaultValue("Hello,World")]
        public string DisplayText
        {
            get { return displayText; }
            set { displayText = value; Invalidate(); }
        }
        [DefaultValue(3)]
        public int DisplayCount
        {
            get { return displayCount; }
            set { displayCount = value; Invalidate(); }
        }
         [DefaultValue(TextDirection.HorizonalText)]
        public TextDirection TextDirect
        {
            get { return textDirection; }
            set { textDirection = value; Invalidate(); }
        }

说明:当我们的属性值属于其值可以作为属性中一个参数的类型(一个字符串,一个数字,或者一个枚举)列出时,这种方式是很好的。

②我们使用一种基于Reset和ShouldSerialize的方法。使用这种方式,我们可以将属性重置为默认值。并将给定属性和默认值比较。更具体的说:Reset负责重置为默认属性。ShouldSerialize检查属性是否具有默认值。

  public void ResetTextColor()
        {
            TextColor = Color.Red;
        }

        public bool ShouldSerializeTextColor()
        {
            return TextColor != Color.Red;
        }

        public void ResetTextFont()
        {
            TextFont = new Font("Times New Roman",12);
        }

        public bool ShouldSerializeTextFont()
        {
            return !TextFont.Equals(new Font("Times New Roman", 12));
        }

        public void ResetStartDisplayPoint()
        {
            StartDisplayPoint = new Point(6,6);
        }

        public bool ShouldSerializeStartDisplayPoint()
        {
            return StartDisplayPoint != new Point(6, 6);
        }

运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。

image-20240414195054090
运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。

好了,自定义控件添加属性的功能就介绍到这里了。欢迎大家一起交流。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

foreach无法修改数组值解决方案

效果展示&#xff1a; 解决办法&#xff1a; this.sportList.forEach((item,index) >{let that this;if(item.idinfo.id) {that.sportList[index].sportTime e.detail.value} }) 这里小编解释下&#xff0c;将this赋值给that通常是为了在回调函数或者异步代码中保持对Vu…

Android安卓开发 - 开发基础(二)

App的工程结构 本节介绍App工程的基本结构及其常用配置&#xff0c;首先描述项目和模块的区别&#xff0c;以及工程内部各目录与配置 文件的用途说明&#xff1b;其次阐述两种级别的编译配置文件build.gradle…

吴恩达2022机器学习专项课程(一) 第二周课程实验:特征工程和多项式回归(Lab_04)

目标 探索特征工程和多项式回归&#xff0c;使用线性回归来拟合非常复杂甚至非线性的函数。 1.为什么线性回归能拟合非线性函数&#xff1f; fxw*xb&#xff0c;属于线性回归的扩展&#xff0c;这个公式在数学中不属于线性&#xff0c;因为有x&#xff0c;而在机器学习中属于…

接口的三个常见使用案例

下面的三个案例&#xff0c;都是需要实现接口&#xff0c;才能进行的操作。 目录 1.比较对象大小 2.给对象排序 3.深浅拷贝 1.比较对象大小 1.1引入 &#xff08;1&#xff09;普通类型比较 &#xff08;2&#xff09;引入类型比较 发现报错&#xff0c;因为在Java中&…

如何理解Vue 3组件的component关键字

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

新质生产力与智能制造:推动制造业转型升级的双引擎

引言 随着科技的不断进步和全球制造业的快速发展&#xff0c;新质生产力与智能制造成为推动制造业转型升级的关键驱动力。新质生产力强调的是以科技创新和制度创新为核心&#xff0c;通过提高生产效率和经济效益来推动经济发展。而智能制造则是利用现代信息技术&#xff0c;实现…

window2012等显示桌面上面的【我的电脑】图标

服务器版本&#xff0c;登录进去&#xff0c;就留个垃圾桶在桌面上&#xff0c;一点也没有用处。 如何显示经典的“我的电脑”呢。 网络介绍了几种方法都木用。这种还点用&#xff1a; win图标点右键》运行&#xff1a; rundll32.exe shell32.dll,Control_RunDLL desk.cpl,…

【系统分析师】计算机网络

文章目录 1、TCP/IP协议族1.1 DHCP协议1.2 DNS协议1.3网络故障诊断 2、网路规划与设计2.1逻辑网络设计2.2物理网络设计2.3 分层设计 3、网络接入3.1 接入方式3.2 IPv6地址 4、综合布线技术5、物联网5.1物联网概念与分层5.2 物联网关键技术 6、云计算7、网络存储技术&#xff08…

使用odbc链接dm8数据库

一、环境说明 windows11 VMware Workstation 17 Pro ubuntu22.04 docker $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy因docker版本的dm8中&#xff0c;没有…

【每日刷题】代码随想录-动规32

1. 代码随想录-动规32.LC121买卖股票的最佳时机 题目链接 不用动规。双指针法。快指针遍历&#xff0c;慢指针指向最小的。 max维护最大差值。 min第一天价格&#xff0c;如果碰到有比min低的&#xff0c;则更新min。 代码 public int maxProfit(int[] prices) {int min pr…

国内开通gpt会员方法

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

【WinForm】如何在自己的程序窗口中显示并调用外部桌面程序

当你爱上一个程序的功能&#xff0c;并且希望扩展它以满足自己的需求时&#xff0c;你可能会觉得困惑。毕竟&#xff0c;你已经为此付出了很多努力&#xff0c;并希望能够有效地整合这些功能。那么&#xff0c;是否可以将这些功能嵌套到自己的程序中呢&#xff1f; 首先&#…

三年了,期待下一个三年

第一个三年 时间好快&#xff0c;距离我发布我第一篇文章都已经三个年头了。 转眼也从大一新生变成了大四打工人。 在平台上发布博客&#xff0c;分享自己的项目、学习思路、解决的bug都带给我很多收获。 平台上的粉丝&#xff0c;阅读量等&#xff0c;也让我的简历更加出彩。…

数据结构初阶:二叉树(二)

二叉树链式结构的实现 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在对二叉树结构掌握还不够深入&#xff0c;为了降低学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二…

【MATLAB应用】去噪算法

01.引言 图像的产生是电子和光学相互作用的结果&#xff0c;而图像中的噪声则是由于成像过程中的颗粒性质而客观存在的。不同类型的噪声从不同的视角产生&#xff0c;各自具有特点。因此&#xff0c;有效地去除图像中的噪声以获得更高质量的图像具有实际意义。目前存在多种图像…

IPD集成产品开发

时间&#xff1a;2024年04月14日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 解密IPD集成产品开发_小蒋聊技术_免费在线阅读收听下载 - 喜马拉雅欢迎收听小蒋聊技术的类最新章节声音“解密IPD集成产品开发”。大家好&#xff…

MAT工具详解

简介 Java自带的JVisualVm可以用来分析Java堆内存&#xff0c;可以用来排查内存泄漏和内存浪费的问题&#xff0c;但是功能不是特别强大&#xff0c; MAT&#xff08;Memory Aanlysis Tool&#xff09;是一款更优的工具。 MAT功能 功能组 全局信息 直方图 按照类的数量倒序…

AI大模型日报#0413:谷歌引入“无限注意力”、Picsart AI 开源120秒超长AI视频模型

导读&#xff1a; 欢迎阅读《AI大模型日报》&#xff0c;内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。 标题: 速递&#xff5c;木头姐 ARK 宣布已投资 OpenAI&#xff01;还将 Anthropic 及 Figure1 等 AI 独角兽一网打尽摘要: ARK已通过其风…

Zookeeper和Kafka的部署

目录 一、Zookeeper的基本概念 1. Zookeeper定义 2. Zookeeper工作机制 3. Zookeeper特点 4. Zookeeper数据结构 5. Zookeeper应用场景 5.1 统一命名服务 5.2 统一配置管理 5.3 统一集群管理 5.4 服务器动态上下线 5.5 软负载均衡 6. Zookeeper 选举机制 6.1 第一…

MySQL——链表

主键&#xff1a;非空 唯一&#xff08;针对整列数据而言&#xff09; 为了方便管理一般主键都是设置为自增 外键&#xff1a;一张表中的一列的值是另一张表的主键&#xff0c;使用外键建立两张数据表的数据关系 一、两张表连接 将两张表格拼接成一个表 1、格式&#xff1a;s…