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

news2024/11/18 2:39:11

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

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

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

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

相关文章

Node.js 并发控制

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它使得 JavaScript 可以脱离浏览器在服务器端运行。由于 Node.js 采用单线程异步非阻塞 I/O 模型&#xff0c;它的并发处理能力也是非常强大的。本文将详细介绍 Node.js 的并发原理、概念、图解、解决方案…

洛谷-P2089 烤鸡

P2089 烤鸡 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N30; //const int M1e3*310; const int Mpow(3,10); int n; int arr[N]; //存临时方案 int res; //存方案数 int ans[M][N]; //存所有方案//x表示当前到…

k8s:kubectl 命令设置简写启用自动补全功能

k8s&#xff1a;kubectl 命令设置简写&启用自动补全功能 1、设置kubectl命令简写2、启用kubectl自动补全功能 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Kubernetes&#xff08;K8s&#xff09;是一个强大的容器编排平台&#xff0…

LangChain安装

安装步骤 1 安装Python环境 这里不介绍Python环境的配置&#xff0c;默认大家是已经安装并配置好Python运行环境的。 2 安装LangChain bash 复制代码 pip install langchain执行以上命令安装LangChain会默认安装LangChain的最新版本 3 测试安装结果 3.1 打印langchain版本…

如何获得easyrecovery软件密钥?2024最新学习步骤教程

如何获得easy recovery密钥&#xff1f;EasyRecovery是一款老牌的数据恢复软件&#xff0c;如果需要使用它来恢复数据&#xff0c;则需要购买密钥激活。然而&#xff0c;如果您只需要使用它一两次而不想花钱购买密钥&#xff0c;那么您可以使用免费的EasyRecovery密钥。请注意&…

贝乐虎儿歌v6.8.0解锁高级版亲子学习儿歌

软件介绍 贝乐虎儿歌免费版app&#xff0c;出自乐擎网络的创意工坊&#xff0c;专为孩子们雕琢了一系列富含创意的动画儿歌内容。这款app通过贝乐虎兄弟的可爱形象&#xff0c;让孩子们在愉快的观看中接触到各种儿歌和故事。不仅如此&#xff0c;app还巧妙地将古诗、英语等学习…

Java代码基础算法练习-求奇数和-2024.04.14

任务描述&#xff1a; 输入n个整数&#xff08;n从键盘输入&#xff0c;n>0&#xff0c;整数取值范围&#xff1a;0~1000&#xff09;&#xff0c;输出它们的奇数和。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;// 输入n个…

【Leetcode】1702. 修改后的最大二进制字符串

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个二进制字符串 b i n a r y binary binary &#xff0c;它仅有 0 0 0 或者 1 1 1 组成。你可以使用下面的操作任意次对它进行修改&#xff1a; 操作 1 &#xff1a;如果…

Nacos 入门篇---服务端如何处理客户端的服务注册请求?(三)

一、引言 ok呀&#xff0c;上个章节我们讲了Nacos客户端的服务自动注册&#xff0c;今天我们来看看服务端接收到了客户端的服务注册请求&#xff0c;服务端都做了哪些事情&#xff5e; 二、目录 目录 一、引言 二、目录 三、回顾上节内容&#xff1a; 四、Nacos 服务代码入…

Linux 网络排查命令

端口相关服务检查 netstat -ntpl|grep [$Port]说明&#xff1a;[$Port]为相应的端口号。 0.0.0.0代表本机上可用的任意地址。比如&#xff0c;0.0.0.0:80表示本机上所有地址的80端口。 tcp 0.0.0.0:80表示在所有的可用接口上监听TCP的80端口 如果返回结果为空&#xff0c;说明…

Java 入门教程||Java 关键字

Java 关键字 Java教程 - Java关键字 Java中的关键字完整列表 关键词是其含义由编程语言定义的词。 Java关键字和保留字&#xff1a; abstract class extends implements null strictfp true assert const false import package super try …

奥尔波特、卡特尔、大五人格的特质流派,预测你是内向还是外向

了解特质&#xff0c;可以预测人的行为&#xff0c;可以预测你的性格是内向还是外向。 特质论并不把人格分为绝对的类型&#xff0c;通常认为存在一些特质维度。人们之间的差异&#xff0c;就在于这些维度上表现程度的不同所形成的不同特质构型。 特质&#xff08;trait&…

Python数据结构与算法——算法(贪心算法、动态规划

贪心算法 介绍&#xff1a;贪心算法又称贪婪算法&#xff0c;是指在对问题求解时&#xff0c;总是做出在当前看来是最好的选择。也就是说&#xff0c;不从整体最优上加以考虑&#xff0c;它所做出的是在某种意义上的局部最优解。 贪心算法并不保证会得到最优解&#xff0c;但…

发誓不在黄金周旅游,可惜管不住自己,看看景区可视化,觉悟了。

2023-10-04 23:29贝格前端工场 景区可视化大屏可以起到以下几个作用&#xff1a; 数据监控和分析&#xff1a;景区可视化大屏可以实时监控景区的各项数据指标&#xff0c;如游客数量、门票销售情况、景区设备运行状态等&#xff0c;通过可视化展示&#xff0c;管理人员可以快…

C/C++基础----指针

指针的定义 在c/c中&#xff0c;有一个特殊的变量指向我们电脑中某个内存地址&#xff0c;进而可以让我们操作这段内存&#xff0c;指的就是指针类型 语法&#xff1a; int a 10; int* p &a;&符号是取出某个变量的内存地址 把这个内存地址赋值给一个变量p&#xff…

分享一个 git stash 的实际使用场景。

当我将新的变更记录提交为 git commit --amend 后&#xff0c;发现这需要修改云端上的提交记录&#xff0c;也就是 vscode 中会出现这张图 于是&#xff0c;我通过 git reset head^ 撤销掉刚刚的提交。 reset 前&#xff1a; reset 后&#xff1a; 但在撤销的同时&#xf…

华院计算参编《金融业人工智能平台技术要求》标准

随着人工智能技术的迅猛发展&#xff0c;金融机构正在从业务场景化向企业智能化演进&#xff0c;金融业对智能化的需求愈加迫切。为引导产业有序发展、规范行业自律、加快金融行业智能化转型&#xff0c;中国信通院依托中国人工智能产业发展联盟&#xff08;AIIA&#xff09;及…

机器学习 | 使用Scikit-Learn实现分层抽样

在本文中&#xff0c;我们将学习如何使用Scikit-Learn实现分层抽样。 什么是分层抽样&#xff1f; 分层抽样是一种抽样方法&#xff0c;首先将总体的单位按某种特征分为若干次级总体&#xff08;层&#xff09;&#xff0c;然后再从每一层内进行单纯随机抽样&#xff0c;组成…

第19讲:自定义类型:结构体

1.结构体类型的声明 2.结构体变量的创建和初始化 3.结构体变量的赋值 4.结构体成员访问操作符 5.结构体内存对齐 1.结构体类型的声明 1.1结构体声明 struct 结构体名称 { 结构体成员... } 举例&#xff1a;描述一个学生&#xff1a; 2结构体变量的创建和初始化 2.1匿…

Linux文本编辑器vim使用和分析—2

目录 1.对vim的简单理解&#xff1a; 2.看待vim的视角&#xff1a; 3.命令模式&#xff1a; 3.1vim被打开后默认的模式&#xff1a; 3.2命令模式切换插入模式&#xff1a; 3.3其他模式回到命令模式&#xff1a; 3.4光标定位&#xff1a; 4.插入模式(编辑模式)&#xff1…