C#实例:多功能Windows窗体应用程序Helloworld_WinForm

有了创建一个Windows窗体应用程序的经验,就可以开始尝试运用更多的控件实现更多丰富的功能界面。以下分享我基于项目Helloworld_WinForm使用常用C#Windows窗体控件实现一些小功能。

每一节标题为所用到的控件,全文以实际制作过程为序编制。


目录

  • WinForm窗体应用程序开发步骤
  • 常用控件实例
    • MenuStrip 菜单栏
    • richTextBox富文本框
    • SaveFileDialog保存对话框
    • FontDialog字体对话框
    • richTextBox的属性WordWrap
    • ColorDialog颜色对话框
    • Timer计时器
    • PictureBox-如何加文字
    • PictureBox-画图
  • 问题与解决
    • 解决子窗体被父窗体控件挡住问题
  • 发布做好的程序


WinForm窗体应用程序开发步骤

1、创建窗体Form

项目创建时会默认创建一个窗体,默认为父窗体。
新建的其他窗体为子窗体,子窗体调用时会在父窗体中显示。
项目创建方法见:Helloworld_WinForm,本文直接基于之前创建的项目搭建功能。

2、创建控件Control

控件显示在工具箱中,通过双击或拖拽的方式显示在当前打开的设计窗口中,可在属性栏修改其属性。

3、指定布局Layout

根据应用拖动控件位置,或在属性中调整坐标等。

4、响应事件Event

事件包括双击控件、按下鼠标、向文本框输入内容等等,可以在控件属性中点击事件图标查看所有事件。
响应是指发生事件后,触发的操作,通常以代码的形式实现功能。

描述还是比较抽象,建议动手实践。

常用控件实例

MenuStrip 菜单栏

新建MenuStrip控件,修改属性如下

  • Name:tools
  • Text:工具
    在工具下,继续新建TextBox,修改它们属性的Text。

如果在子窗体中也加入Menustrip,则需在父窗体的Menustrip属性中按下图所示修改,否则子窗体菜单栏不会显示出来,默认二者菜单栏合并。
在这里插入图片描述
父窗体:
在这里插入图片描述
子窗体:
在这里插入图片描述

richTextBox富文本框

参考链接
在项目中右键添加子窗体,命名Text。
Anchor属性选择“Top,Bottom,Left,Right”,这样当窗体大小改变时,RichTextBox控件的大小也会跟着改变
在这里插入图片描述

新建 richTextBox控件。属性BackColor改为ControlLightLiight,ReadOnly改为True。修改Dock属性为Fill,使控件铺满窗口。
在这里插入图片描述

将父窗体属性中的IsMdiContainer改为true。
并双击父窗体菜单栏的“新建”,编辑程序,使点击新建时打开子窗体。

private void toolStripTextBox3_Click(object sender, EventArgs e)
        {
            Text newMDIChild = new Helloworld_WinForm.Text();
            // Set the Parent Form of the Child window.
            newMDIChild.MdiParent = this;
            // Display the new form.
            newMDIChild.Show();
        }

SaveFileDialog保存对话框

参考链接:c#保存textbox中的字符串到txt文件中
点击记事本的【文件】→【保存】菜单项时,使用SaveFileDialog保存文件。

用程序创建SaveFileDialog及修改属性。

		// 菜单栏中的保存按钮。也可用Button
		private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
        	// 新建SaveFileDialog,Name为saveFileDialog
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            // 修改属性,定义保存文件类型
            saveFileDialog.Filter = "(*.txt)|*.txt|(*.*)|*.*|97-2003Word文档|*.doc";
            // 文件名是日期时间
            saveFileDialog.FileName = "D:\\text\\" + DateTime.Now.ToString("yyyyMMddHHmm") + ".txt";
            // 对话框打开
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
            	// 新建数据流
                StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName, true);
                // 写入数据
                streamWriter.Write(this.richTextBox1.Text);
                // 关闭当前streamWriter对象和基础流
                streamWriter.Close();
            }
        }

		// 富文本,Name为richTextBox1
        private void richTextBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

上述程序启动后,点击保存,会弹出保存窗口,如下:
在这里插入图片描述
可以选择保存为txt或doc格式。

试一试效果:
在这里插入图片描述

FontDialog字体对话框

继续增加菜单栏选项:字体。其属性Name为字体ToolStripMenuItem。
在这里插入图片描述
双击字体,编写代码,新建字体对话框,并将设置的字体赋给富文本中的Text。

		private void 字体ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FontDialog fontDialog = new FontDialog();
            if(fontDialog.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.SelectionFont = fontDialog.Font;
            }
        }

试一下效果:
先设置字体,再输入文本。也可在输入文本后,选中需要修改字体的文本,再点击字体修改。
在这里插入图片描述
在这里插入图片描述

richTextBox的属性WordWrap

增加菜单栏选项:自动换行。其Name属性为自动换行ToolStripMenuItem。

自动换行的Checked属性默认为“False”,文本内容按照文本框的宽度自动换行,否则只按段落标记换行。

可以修改富文本属性WordWrap,以决定是否默认自动换行,此处为默认自动换行:
在这里插入图片描述
将自动换行选项的默认状态Checked改为被点击的True状态:
在这里插入图片描述
双击自动换行,编辑代码如下:

        private void 自动换行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
        	// 判断自动换行状态标记
            if(自动换行ToolStripMenuItem.Checked == false)
            {
            	// 被按下后更新状态
                自动换行ToolStripMenuItem.Checked = true;
                // 自动换行
                richTextBox1.WordWrap = true;
            }
            else
            {
            	// 被按下后更新状态
                自动换行ToolStripMenuItem.Checked = false;
                // 不自动换行
                richTextBox1.WordWrap = false;
            }
        }

实现的效果就是默认自动换行,点击自动换行后取消自动换行,再次点击则变为自动换行。

ColorDialog颜色对话框

利用ColorDialog修改字体颜色。
增加菜单栏字体颜色,其Name属性为字体颜色ToolStripMenuItem。

双击它编辑代码如下:

// 第一种
		private void 字体颜色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.SelectionColor = colorDialog.Color;
            }
        }

试一下效果:
若先设置字体颜色,再输入文本,则此前输入的文本不会变化,变更只适用于此后输入的文本。
也可在输入文本后,选中需要修改字体颜色的文本,再点击字体颜色修改,变更适用于选中的文本。
在这里插入图片描述
修改为橙色:
在这里插入图片描述

如果在未选中文本时修改字体颜色,要将所有文本字体颜色同时修改,则可以这样写:
选中文本再修改颜色,只会修改选中文本的颜色。

// 第二种
		private void 字体颜色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog colorDialog = new ColorDialog();
            if (this.colorDialog1.ShowDialog() == DialogResult.OK)
            {
                if (this.richTextBox1.SelectedText == "") // 若未选中文本,则将设置颜色适用于所有文本
                {
                    this.richTextBox1.ForeColor = this.colorDialog1.Color;
                }
                else
                {
                    this.richTextBox1.SelectionColor = this.colorDialog1.Color;
                }
            }
        }

Timer计时器

参考链接
在项目中新建Windows窗体,命名为Clock.cs。
在父窗体中,双击菜单栏Clock,编写代码,添加子窗体Clock。属性BackColor改为ControlLightLiight,ReadOnly改为True。
代码如下:

		private void toolStripTextBox2_Click(object sender, EventArgs e)
        {
            Clock newMDIChild = new Helloworld_WinForm.Clock();
            // Set the Parent Form of the Child window.
            newMDIChild.MdiParent = this;
            // Display the new form.
            newMDIChild.Show();
        }

在Clock窗体中,拖拽Label控件,Name为label1,修改属性字体颜色为喜欢的字体。修改属性Text为yyyy-MM-dd HH:mm:ss。
在这里插入图片描述
拖拽Timer计时器控件,Name为timer1,修改属性Enable为True,Interval为1000。使能定时,每1000ms执行一次函数timer1_Tick中的内容。
在这里插入图片描述
双击timer1,编写代码,使其显示实时时间。

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");  //年-月-日 小时:分钟:秒
        }

其中,HH为24小时进制,hh为12小时进制。

让Label文字居中的方法:设置Autosize的值为false,拉大这个label框的宽度,设置label属性里的TextAlign为MiddleCenter,意思是让框里的文字内容居中。
在这里插入图片描述
启动后效果如下:每过一秒,时间更新一次。
在这里插入图片描述

PictureBox-如何加文字

参考链接
在父窗口的菜单栏工具中添加一项:Panel。并添加子菜单 加水印 和 清屏。本节实现加水印的功能,后一节实现清屏。
在这里插入图片描述

从工具箱拖拽一个PictureBox控件到窗口,属性Dock改为Fill。
属性BackgroundImage可以上传一个图片,使PictureBox控件区域默认显示该图片。
还有SizeMode属性选Zoom,SizeMode属性包含:

  • Normal:图片大小不变;
  • strechImage:拉伸图片适应PictureBox(图片会变形)
  • AutoSize:PictureBox适应图片;
  • CenterImage:图片居中显示;
  • Zoom:图片填充PictureBox(不变形)

双击“加水印”,编辑程序如下:实现将文字显示在对应坐标。

		private void 加水印ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 在pictureBox上创建画图板
            Graphics g = pictureBox1.CreateGraphics();
            // 设置字体的样式
            Font f = new Font("黑体", 24);
            // 实例化一个实心画刷,颜色是白色
            SolidBrush brush = new SolidBrush(Color.White);
            // 与左上角坐标的距离
            PointF point = new PointF(400, 300);
            // 开始绘制
            g.DrawString("From: Electrical_IT", f, brush, point);
        }

启动运行,点击加水印,效果如下:
在这里插入图片描述

PictureBox-画图

参考链接:C#控件picturebox实现画图功能
C#控件画图方法
打开指定路径图片的方法
本部分实现鼠标在PictureBox区域中使用鼠标绘制的功能。
PictureBox控件属性设置参考上一节。菜单栏也如上一节添加。

要实现绘图功能,需要用到PictureBox的事件响应,位置在PictureBox的属性框中,点击PictureBox,点击事件图标即可看到:
在这里插入图片描述
重命名事件MouseDown为drawstart,事件MouseMove为drawmove,事件MouseUp为drawstop。
每次命名后会自动切换到代码编辑界面。

修改代码如下:

        private void 清屏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Graphics g = pictureBox1.CreateGraphics();
            // 用原背景图清屏
            g.DrawImage(pictureBox1.BackgroundImage, 0, 0);
        }

        // 定义鼠标绘制的终点(起点永远是鼠标当前坐标)
        private Point endpoint;
        // 绘制标志
        private static bool drawing = false;
        private void drawstart(object sender, MouseEventArgs e)
        {
            // 创建终点
            endpoint = new Point(e.X, e.Y);
            // 鼠标按下开始绘制
            drawing = true;
        }

        private void drawstop(object sender, MouseEventArgs e)
        {
            // 鼠标松开结束绘制
            drawing = false; 
        }

        private void drawmove(object sender, MouseEventArgs e)
        {
            // 鼠标移动进行绘制,创建画布
            Graphics g = pictureBox1.CreateGraphics();
            // 显示时消除锯齿
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            // 如果鼠标按下的按钮是左键
            if(e.Button == MouseButtons.Left)
            {
                if(drawing)
                {
                    // 当前坐标
                    Point currentpoint = new Point(e.X, e.Y);
                    // 用白蓝色笔绘制连接p2和当前坐标的线
                    g.DrawLine(new Pen(Color.AliceBlue, 2), endpoint, currentpoint);
                    // 更新终点坐标
                    endpoint.X = currentpoint.X;
                    endpoint.Y = currentpoint.Y;
                }
            }
        }

用鼠标画一画,绘制效果如下:
在这里插入图片描述
点击清屏后效果如下:(清屏也会把水印清掉)
在这里插入图片描述
如果清屏想用白色清屏,参考以下代码:

		private void 清屏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Graphics g = pictureBox1.CreateGraphics();
            g.Clear(Color.White);
        }

问题与解决

解决子窗体被父窗体控件挡住问题

上述实例先创建了子窗体Hello、Clock和Text,再在父窗体中添加了控件PictureBox。
启动后,点击菜单栏Hello、Clock和文件新建时,子窗体无法显示在PictureBox控件前,原因是被父窗口的控件挡住了。

我的解决方法是在打开子窗体前,将父窗体中的控件PictureBox隐藏,点击Panel后再显示PictureBox控件。

隐藏:pictureBox1.Hide();
显示:pictureBox1.Show();

首先将HelloWorld.cs中,菜单点击事件的响应程序里添加隐藏控件的函数:

		 private void toolStripTextBox1_Click(object sender, EventArgs e)
        {
            Hello newMDIChild = new Helloworld_WinForm.Hello();
            // Set the Parent Form of the Child window.
            newMDIChild.MdiParent = this;
            // Hide the pictureBox1
            pictureBox1.Hide();
            // Display the new form.
            newMDIChild.Show();
        }

        private void toolStripTextBox3_Click(object sender, EventArgs e)
        {
            Text newMDIChild = new Helloworld_WinForm.Text();
            // Set the Parent Form of the Child window.
            newMDIChild.MdiParent = this;
            //Hide the pictureBox1
            pictureBox1.Hide();
            // Display the new form.
            newMDIChild.Show();
        }

        private void toolStripTextBox2_Click(object sender, EventArgs e)
        {
            Clock newMDIChild = new Helloworld_WinForm.Clock();
            // Set the Parent Form of the Child window.
            newMDIChild.MdiParent = this;
            //Hide the pictureBox1
            pictureBox1.Hide();
            // Display the new form.
            newMDIChild.Show();
        }

其次,在点击菜单中需要响应主窗口控件pictureBox1的程序中,增加显示控件函数:

		private void 加水印ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 设置字体的样式
            Font f = new Font("黑体", 24);
            // 实例化一个实心画刷,颜色是白色
            SolidBrush brush = new SolidBrush(Color.White);
            // 与左上角坐标的距离
            PointF point = new PointF(400, 300);
            // 显示pictureBox1控件
            pictureBox1.Show();
            // 在pictureBox上创建画图板
            Graphics g = pictureBox1.CreateGraphics();
            // 开始绘制
            g.DrawString("From: Electrical_IT", f, brush, point);
        }

        private void 清屏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 显示pictureBox1控件
            pictureBox1.Show();
            Graphics g = pictureBox1.CreateGraphics();
            // 用原背景图清屏
            g.DrawImage(pictureBox1.BackgroundImage, 0, 0);
        }

测试后发现还一个问题:pictureBox1被隐藏后,点击菜单中的加水印,会显示pictureBox1控件背景,但不会显示水印,还需要第二次点击,才会显示水印。不清楚为什么,还希望有大神评论指点。

另外,如果主窗口中控件非常多,不建议使用这种方式,建议将主窗口的控件放在Panel控件中,使子窗口的父类设置为Panel。参考链接

发布做好的程序

如果想将程序发给朋友玩一下,就需要发布。

首先,配置设置为Release、Any CPU。
在这里插入图片描述
找到生成,点击发布。
在这里插入图片描述
根据发布向导,指定发布的位置。
在这里插入图片描述
选择用户下载的方式,这里选从ROM。
在这里插入图片描述
选择不检查更新,并点击完成。
在这里插入图片描述
等待片刻,就可以在路径里找到setup.exe安装包。双击运行,就可以得到应用配置文件夹和应用程序。双击Helloworld_WinForm.application就可以运行了。
在这里插入图片描述
如果想卸载,可以在控制面板的应用中找到并卸载它。
在这里插入图片描述

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

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

相关文章

来了解一下白盒测试,黑盒测试,灰盒测试吧(超详解~)

根据被测对象的不同,软件测试可以分为白盒测试、黑盒测试、灰盒测试三种方式。那么,这三种测试方式具体是如何运行的?各有什么特点?下面,跟着静姐一起了解一下吧! 01、白盒测试 WHITE BOX ●概念&#x…

PACS影像解决方案

现代医学影像技术的迅猛发展,使得PACS系统已逐渐成为各级医院实现信息化建设的重要组成部分。医学影像技术的进步也提升了医学影像的清晰度,推动二维PACS向三维升级转变。这一切都使得医学影像数据量激增,加之医疗行业法规的数据保存要求&…

Android平台OpenCV入门

一、导入OpenCV 别忘记把libopencv_java3.so添加进来。 二、初始化 OpenCVLoader.initDebug();三、常用方法 1. CvType 数据类型 以CV_64FC2为例,64指64位,F指浮点数,C指通道,2为2通道。 数值具体类型取值范围CV_8U8 位无符…

软件工程导论(四)软件编码测试与维护

一、软件编程 1.1良好的编程习惯 变量命名有意义并且使用统一的命名规则 编写自文档代码(序言性注释 or 行内注释) 提前进行可维护性考量(可以用常量的方式存在的数值最好以变量的方式存在) 良好的视觉安排可以提高代码的可读性(…

SOLIDWORKS技巧培训-绘制零件滚花的两种方法

最近常有朋友咨询SolidWorks零件如何做滚花的效果,下面给大家整理了绘制零件滚花的一个培训教程: 作为机械设计师,滚花应该都不陌生,真要说起来,滚花绘制其实也不算难,跟着我们一步一步来,应该…

ThreeJS 炫酷特效旋转多面体Web页 Demo 01《ThreeJS 炫酷特效制作》

本案例为一个 threejs 的特效网页,大小球体进行包裹,外球体为透明材质,但是进行了线框渲染,使其能够通过外球踢查看其内球体。 注:案例参考源于互联网,在此做代码解释,侵删 本案例除 ThreeJS 外…

chatgpt赋能python:Python如何分割列表

Python如何分割列表 介绍 在Python编程中,列表是一种非常常见的数据类型。有时候我们需要将一个大的列表分割成几个小的列表,以便更好地处理数据。Python提供了多种方法来实现这个目的。在本文中,我们将介绍Python中如何分割列表的几种方法…

活动预告 | 中国数据库联盟(ACDU)中国行定档深圳,一起揭秘数据库前沿技术

在当今数字化时代,数据库是各行各业中最核心的信息管理系统之一。随着技术的飞速发展,数据库领域也不断涌现出新的前沿技术和创新应用。数据库运维和开发人员需要紧跟前沿技术,才能保持竞争力,并实现更高效、更智能、更人性化的应…

pytorch实战 -- 神经网络

softmax的基本概念 交叉熵损失函数 模型训练和预测 在训练好softmax回归模型后,给定任一样本特征,就可以预测每个输出类别的概率。通常,我们把预测概率最大的类别作为输出类别。如果它与真实类别(标签)一致&#xff0…

Java 数组

文章目录 一、Java 数组总结 一、Java 数组 Java 语言中提供的数组是用来存储固定大小的同类型元素。 你可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0,number1,…,number99。 Java 数组的声明、…

Linux内存初始化-启动阶段的内存初始化

本文代码基于ARM64平台, Linux kernel 5.15 在加载kernel 之前, kernel对于系统是有一定要求的,明确规定了boot阶段必须要把MMU关闭: arch/arm64/kernel/head.S/** Kernel startup entry point.* ---------------------------** The require…

黑马Redis视频教程实战篇(六)

目录 一、附近商户 1.1、GEO数据结构的基本用法 1.2、导入店铺数据到GEO 1.3、实现附近商户功能 二、用户签到 2.1、BitMap功能演示 2.2、实现签到功能 2.3、签到统计 2.4、关于使用bitmap来解决缓存穿透的方案 三、UV统计 3.1、HyperLogLog 3.2、测试百万数据的统…

【HarmonyOS】初识低代码平台开发元服务

【关键字】 HarmonyOS、低代码平台、元服务开发、拖拽式开发 【写在前面】 今天要分享的是HarmonyOS中的低代码开发相关的内容,低代码开发是DevEco Studio提供的一种UI界面可视化的构建方式,通过图形化的自由拖拽数据的参数化配置,可以快速…

2419286-92-1,Sulfo-Cy5.5 NHS ester,磺酸基Cyanine5.5-活性酯,用于标记抗体

Sulfo-Cyanine5.5 NHS ester,sulfo Cy5.5(Et) NHS,sulfo Cy5.5 SE,磺酸基Cy5.5-活性酯 (文章资料汇总来源于:陕西新研博美生物科技有限公司小编MISSwu)​ 产品结构式: 产品规格: 1…

SAP-MM-发票-采购附加成本处理简介

一.采购附加成本处理: 原材料的采购成本包括采购成本(采购单价*采购数量)和相关采购附加成本(运输费、保险费、报关费、仓储费、滞期费、租船费、码头费及代理费等费用),对于采购附加成本主要有…

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建 文章目录 基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建1. 传统推荐系统模型2. 协同过滤算法3. 基于双视角图表示学习算法的模型构建3.1 数据输入3.2 双视角交互图的构建3.3 混合偏好传播策略3.4 对于双向意…

git使用X篇_2_Git全套教程IDEA版(git、GitHub、Gitee码云、搭建公司内部GitLab、与IDEA集成等内容)

本文是根据以下视频及网上总结进行更新后的介绍git使用的博文。包含了git、GitHub、Gitee码云、搭建公司内部GitLab、与IDEA集成等内容。 笔记来源:【尚硅谷】5h打通Git全套教程IDEA版(涵盖GitHub\Gitee码云\GitLab) 文章目录 初识 Git0、内容…

ReadDataByIdentifier(0x22)服务

ReadDataByIdentifier(0x22)服务 ReadDataByIdentifier服务允许客户端从一个或多个dataIdentifiers标识的服务器请求数据记录值。 客户端请求消息包含一个或多个两字节的dataIdentifier值,用于标识服务器维护的数据记录 允许的dataIdentifie…

Vue3小兔鲜:组合式写法入门

Vue3&#xff1a;组合式写法入门 Date: May 11, 2023 认识Vue3 1. Vue3组合式API体验 通过 Counter 案例 体验Vue3新引入的组合式API <script> export default {data(){return {count:0}},methods:{addCount(){this.count}} } </script><script setup> imp…

Linux 高级篇-定制自己的Linux 系统

Linux 高级篇-定制自己的Linux 系统 基本介绍 通过裁剪现有Linux 系统(CentOS7.6)&#xff0c;创建属于自己的min Linux 小系统&#xff0c;可以加深我们对linux 的理解。利用centos7.6&#xff0c;搭建一个小小linux 系统, 很有趣。 基本原理 启动流程介绍&#xff1a; 制…