WinForm(一) WinForm入门与基本控件使用
一.Winform入门
WinForm 是 Windows Form 的简称,是基于 .NET Framework 平台的客户端(PC软件)开发技术,一般使用 C# 编程。在VS2019中,C# WinForm 编程需要创建「Windows窗体应用程序」项目。Windows 窗体应用程序是 C# 语言中的一个重要应用,也是 C# 语言最常见的应用。使用 C# 语言编写的 Windows 应用程序与 Windows 操作系统的界面类似,每个界面都是由窗体构成的,并且能通过鼠标单击、键盘输入等操作完成相应的功能。WinForm支持可视化设计,简单易上手,并可以接入大量的第三方UI库或自定义控件,给桌面应用开发带来了无限可能。
1.WinForm项目结构
1.WinForm项目结构
(1)引用:包括所有的系统库文件的引用依赖
(2)App.config:当前项目的配置文件
(3)Form1.cs:当前窗体的事件逻辑源码
- Form1.Designer.cs:当前窗体的控件布局源码
- Form1.resx:当前窗体的资源文件(图片、图标、资源等)
- 注意:
a.Form1.cs和Form1.Designer.cs都定义了Form1类,该类使用了Partial关键词声明,其定义的类可以在多个地方被定义,最后编译的时候会被当作一个类来处理。因此两个文件各司其职,最后合并为一个类编译。
b.要手动实现自定义窗体,可以添加自己的类,然后继承Form类即可
(4)Program.cs:当前项目程序的主入口Main,启动项目,运行初始窗口
namespace WindowsFormsApp_learning
{//Program.cs 入口程序解读static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>//1.[STAThread] Attributes语法,修饰Main方法。示应用程序的默认线程模型是单线程单元 (STA)[STAThread]static void Main(){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);//2.开启窗口的消息循环,初始化并启动Form1窗口Application.Run(new Form1());}}
}
2.窗口设计与控件布局
2.窗体控件布局文件
(1)操作:在设计界面拖拽控件,可以完成界面布局(控件大小、名称、类型、样式等) (2)原理:设计界面自动关联Form1.Designer.cs文件,在InitializeComponent()方法中会自动生成相关代码
(3)设计原则:
- Form1.Designer.cs文件:窗体控件布局文件,一般【不需要我们修改】,只要通过设计界面代码就会自动生成。
- Form1.cs文件:窗体事件逻辑代码的实现,一般【需要我们手动书写】,包括触发事件、回调、数据交互、跳转等等
3.手动添加控件:不通过设计界面,有两种方式
(1)在Form1.Designer.cs中添加:
private System.Windows.Forms.Button btn_design;//声明控件//默认的控件初始化方法InitializeComponent():{this.btn_design = new System.Windows.Forms.Button();//定义控件this.btn_design.Text = "自定义控件";//设置Text属性this.btn_design.Location = new Point(40,40);//设置布局位置 Point(x,y)this.btn_design.Size = new Size(100,40);//设置尺寸大小 Size(width,height)this.Controls.Add(this.btn_design);//注册控件到窗体}
(2)在Form1.cs中添加:
private Button btn_design;//声明控件public Form1(){//先调用Designer.cs中的控件初始化方法InitializeComponent();this.btn_design = new System.Windows.Forms.Button();//定义控件this.btn_design.Text = "自定义控件";//设置Text属性this.btn_design.Location = new Point(40,40);//设置布局位置 Point(x,y)this.btn_design.Size = new Size(100,40);//设置尺寸大小 Size(width,height)this.Controls.Add(this.btn_design);//注册控件到窗体}
(3)注意:
1. 一般我们都使用拖拽添加控件,当然也有特殊情况需要我们手动添加(比如自定义控件)
2. 窗体GUI中,左上角为原点(0,0),竖直向下为y轴,水平向右为x轴(宽度表示x轴上长度,高度表示y轴上长度),单位为像素。
3.窗口事件
4.WinForm 自动添加事件处理
(1)操作:在设计界面-控件属性-闪电符号(事件)-添加事件,就会在Form1.cs中自动生成该控件相应方法名称的事件触发函数
(2) MessageBox.Show():显示弹出消息提示框
(3)GUI界面下Console.WriteLine不显示,需要使用调试模式
namespace WindowsFormsApp_learning
{/*** 4.WinForm事件处理* (1)操作:在设计界面-控件属性-闪电符号(事件)-添加事件,就会自动生成相应方法名称的事件触发函数* (2) MessageBox:显示消息提示框* (3)GUI界面下Console.WriteLine不显示,需要使用调试模式*/public partial class Form1 : Form{public Form1(){InitializeComponent();}//Button的Click点击事件(自动添加)private void showMessage(object sender, EventArgs e){MessageBox.Show("Hello World!");}}
}
5.手动添加事件处理(以Btn_design为例)
(1)步骤:
添加按钮控件到布局
书写事件处理函数,必须符合 void function_name(object param1,EventArgs e){}的形式
添加注册事件,this.Btn_design.Click += new EventHandler(this.showTip);
(2)注意:事件处理机制用到了委托和事件的C#基础,有时间可以看一下
下一步的学习请前往 WindowsFormApp_demo1(实现一个显示本地时间的APP)
namespace WindowsFormsApp_learning
{/*** 5.手动添加事件处理(以Btn_design为例)* (1)步骤:* - 添加按钮控件到布局* - 书写事件处理函数,必须符合 void function_name(object param1,EventArgs e){}的形式* - 添加注册事件,this.Btn_design.Click += new EventHandler(this.showTip);* (2)注意:事件处理机制用到了委托和事件的C#基础,有时间可以看一下* 下一步的学习请前往 WindowsFormApp_demo1(实现一个显示时间的APP)*/public partial class Form1 : Form{public Form1(){InitializeComponent();//2.1 注册Click事件为手动添加的函数this.Btn_design.Click += new EventHandler(this.showTip);}//2.Button的Click点击事件(手动添加)public void showTip(Object sender,EventArgs e){MessageBox.Show("手动添加!");}}
}
4.时间显示器小练习
设计一个能获取本地时间并显示在文本框的时间查看器,设计思路就是:
1.在UI设计界面添加一个按钮Button和一个用来显示时间的文本框TextBox
2.给按钮Button添加点击事件,在事件中获取系统时间,并赋值给TextBox显示
(1)界面设计
(2)逻辑代码
namespace WindowsFormsApp_Demo1
{public partial class Form1 : Form{public Form1(){InitializeComponent();}//点击事件:获取当前时间赋值给TextBoxprivate void ShowTime(object sender, EventArgs e){string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");this.Time_filed.Text = time;}}
}
二.WinForm布局开发
1.常见的WinForm 自动界面布局(设计界面拖拽布局)
(1)操作:拖拽控件,放置在UI设计界面上布局
(2)技巧:通过ctrl+多个控件选定,可以在上方工具栏进行细节的对齐微调,比如居中对齐、左对齐等。
(3)本质:每次拖拽添加一个布局控件,就会在窗口相应的Designer.cs设计布局代码文件中的InitializeComponent()方法中自动生成布局代码(比如Location、Size等),来实现布局。
(4)存在的问题:自动布局虽然方便灵活,但是当窗口大小拉伸改变时,布局控件不能实现自动适应,仍会保持原大小,因此自动布局只适用于窗口大小不变的情况
1. 手动布局解决自适应问题
2.WinForm界面手动布局(并解决自适应问题)
(1)步骤:
- 通过设计界面拖拽/手动注册组件的方式,初始化初始界面布局(此时属于自动布局)
- 在Form.cs逻辑代码中重写Form父类的OnLayout方法,在方法内实现手动布局。OnLayout方法会在窗口大小变化时自动被回调调用,来重新设置组件的位置大小等属性实现自适应。
a.调用父类的OnLayout(),不是必须的。
b.获取当前窗口大小 CilentSize(仅客户区,不含标题栏)
c.计算和设置每一个控件新的的大小和位置,实现动态布局
(2)注意:
- Size属性指窗口大小(包括工具栏),ClientSize指客户区大小(不包含工具栏)
- 本质:OnLayout方法会在窗口大小变化时自动被调用,来设置组件的位置实现自适应
namespace WindowsFormsApp_learning
{public partial class Form1 : Form{public Form1(){InitializeComponent();}//重写父类的OnLayout方法,实现手动布局自适应protected override void OnLayout(LayoutEventArgs levent){//1.调用父类的OnLayout(),不是必须的base.OnLayout(levent);//2.获取当前客户窗口大小 ClientSizeint w = this.ClientSize.Width;int h = this.ClientSize.Height;//3.计算并设置每一个控件的大小和位置int yoff = 0;yoff = 4;this.text_box.Location = new Point(0, yoff);//坐标(0,4)this.text_box.Size = new Size(w - 80, 30);//尺寸(w-80,30)this.btn_click.Location = new Point(w - 80, yoff);//坐标(w-80,4)this.btn_click.Size = new Size(80, 30);//尺寸(80,30)yoff += 30;//第一行的高度yoff += 4;//间隔this.panel1.Location = new Point(0, yoff);this.panel1.Size = new Size(w, h - yoff - 4);}}
}
2.WinForm布局属性
3.WinForm布局属性(控件与布局相关的属性,设计界面可见)
(1)Anchor:固定、锚定(无论窗口怎么变化,控件的相对位置都不变)
- 含义:固定控件与父窗口的【上下左右边距】不变,实现控件的锚定
- 左上角固定:选定 Top,Left(默认)
- 顶部固定,水平拉伸:选定 Top,Left,Right
- 居中固定:None(取消所有)
- *注意:Anchor效果的好坏取决于控件的初始位置,因为控件的初始位置决定了控件的边距!所以要让控件固定右上角,就要初始设计时就放在右上角!
(2)Dock:停靠属性,将控件停靠在父窗口的一侧或者中央
- Top:上,控件停靠在容器上侧,宽度填满容器,高度可以调节
- Bottom:下,控件停靠在容器下侧,宽度填满容器,高度可以调节
- Left:左,控件停靠在容器左侧,高度填满容器,宽度可以调节
- Right:右,控件停靠在容器右侧,高度填满容器,宽度可以调节
- Fill,中,控件填满容器中间剩余部分(所以说与控件添加顺序有关)
- None,无,不使用Dock属性
- *注意:
a.容器之间可以嵌套,使用布局属性(容器就是存放组件的,比如Panel)
b.Dock属性与Anchor属性不能同时使用
c.Dock属性不是固定边距了,就是相对位置填充
3.WinForm布局器
4.布局器 LayoutEngine
(1)含义:布局器就是容器内部组件的默认排列方式,所有的容器都带有一个默认的布局器
(2)自定义控件如何加入设计界面:
- 工具 -> 选项 -> Windows窗体设计器 -> 常规 -> 自动填充工具箱 -> True
- 添加自定义的控件类源码到项目下
- 生成/重新生成结局方案 F7
- 重新打开设计界面,在工具箱就可以看到自己的控件
(3)系统提供的布局器-FlowLayoutPanel(流式布局):
- 含义:普通的Panel面板容器控件,使用了FlowLayout流式布局,即所有内部组件按照顺序从左到右从上到下依次排列
- FlowLayoutPanel也可以使用Anchor、Dock等属性,因为他也是窗体容器内的一个组件
- 控件的选择技巧:多个控件叠加到一起时,可以右键最上层控件,来进行重叠控件的选择
(4)系统提供的布局器-TableLayoutPanel(表格布局):
- 含义:普通的Panel面板容器,使用了TableLayout表格布局,即所有内部组件可以放置到不同的表格中(每个表格只能放置一个控件)
- TableLayoutPanel也可以使用Anchor、Dock等属性,因为他也是窗体容器内的一个组件。搭配布局与布局属性,可以实现很多不同的布局效果。
- 删除/添加行、列:右键表格Panel,可以添加、删除行/列
- 调整表格大小:表格属性Columns可以通过绝对值、百分比、自动调整等方式来调整单元格的大小
a.绝对:固定像素值大小
b.百分比:除去绝对大小后,单元格占剩余大小的百分比
c.自动调整:根据内部控件的大小生成
- 跨行/列控件:在控件的ColumnSpan/RowSpan调整控件可以跨行/跨列布局
- *注意: TableLayoutPanel 控件每个单元格只能包含一个子控件。
(5)系统提供的布局工具-默认布局:默认布局可以通过控件拖拽放置,并可以使用Anchor、Dock来调整
(6)自定义布局器:用户可以自己设计实现布局器,这属于WinForm高级的内容,后面学习。
三.WinForm常用控件
1.Winform 组件的使用
(1)TextBox:输入文本框
- 常用属性:尺寸Size、单行/多行Multiline、密码输入PasswordChar、只读ReadOnly、显示/获取文本Text等
- 常用事件:KeyPress按下按键(常用于输出完成点击回车,box.Text取输入值,事件e.keyChar取按下哪个键)
(2)CheckBox:复选框
- 常用属性:尺寸Size、显示文本Text、Checked是否勾选
- 常用事件:Click点击事件、CheckedChanged勾选状态改变事件
(3)ComboBox:下拉列表(只能单选)
- 常用属性:
a.添加数据项:设计器编辑添加(属性->数据->Items,一行表示一个数据项)、程序手工添加(comboBox.Items.Add("some");)
b.其他设置:Size尺寸、Text提示文本等
- 常用事件:
a.获取选中的项:SelectedItem(选中项的值)、SelectedIndex(选中项的索引,-1表示未选中)
b.选项改变事件:SelectedIndexChanged
- 注意:Item可以添加字符串,也可以添加任意object类型(比如自定义对象),对象会以object.toString显示
(4)ListBox:列表框(展示数据、可单选/多选)
- 常用属性:SelectionMode(单选/多选模式)
a.单选模式获取选项:SelectedItem/SelectedIndex(选中项的值/索引)
b.多选模式获取选项:SelectedIndices/SelectedItems(选中项的索引集合/值集合)
c.添加数据项:设计器编辑添加(属性->数据->Items)、程序手工添加(listBox.Items.Add("some");)
- 常用事件:SelectedIndexChanged(选项改变)
- 注意:Item可以添加字符串,也可以添加任意object类型(比如自定义对象),对象会以object.toString显示
(5)练习:学生信息编辑器实例(本代码)
1.界面展示
2.实体类 Student(封装信息)
1.C# 类的属性与字段
(1)字段:字段是类的成员变量,用于类内特征的数据存储(静态) 比如private int Id;
(2)属性:属性是对字段特征的动态描述,用于向外界提供数据,本质上就是get、set方法。
- 完整属性用法:private string sdu_name;//声明字段public string StudentName{//声明属性get{ return sdu_name; }set{if(value==null)sdu_name = "admin";sdu_name = value;} }
- get访问器:get访问器必须包含return语句,返回字段‘realValue'。用于获取数据,如果没有get则字段为只写的
- set访问器:set访问器接受它的输入参数--value,并把它赋给字段,value是隐式参数。用于设置数据,如果没有set则字段为只读的
(3)使用方式:直接使用Class.StudentName来获取和设置数据,就像是直接使用公开的属性一样
(4)自动属性:简化字段和属性的关系
- 用法:public 数据类型 属性名{ get; set; }
- *原理:c# 允许只声明属性而不声明后备字段,编译器会创建隐藏的后备字段。并且自动挂接到get,set访问器上。
(5)注意:
- 属性也可以不与字段关联,可以当作函数进行复杂计算,比较自由灵活
- 属性也可不用显示声明相应的字段,直接用于存贮数据。(自动属性)
- 也可以通定义其他set、get函数来实现访问private字段的功能
namespace WindowsFormsApp_learning
{class Student{//属性访问器public int SduId { get; set; }public string SduName { get; set; }public bool SduSex { get; set; }public string SduPhone{get; set;}public Student(int sduId, string sduName, bool sduSex, string sduPhone){SduId = sduId;SduName = sduName;SduSex = sduSex;SduPhone = sduPhone;}public Student(){}}
}
3.逻辑事件代码Form.cs
namespace WindowsFormsApp_learning
{public partial class Form4 : Form{public Form4(){InitializeComponent();//初始化数据LoadData();}/*** 保存按钮触发事件-保存学生信息到本地文件*/private void save_student(object sender, EventArgs e){Student student = new Student();student.SduId =Convert.ToInt32(sdu_Id.Text.Trim()); //Convert格式转换student.SduName = sdu_Name.Text.Trim();student.SduSex = (sdu_sex.SelectedIndex == 1);student.SduPhone = sdu_phone.Text.Trim();//以Json格式保存到本地文件string JsonStr = JsonConvert.SerializeObject(student, Formatting.Indented);AfTextFile.Write("student.txt", JsonStr,AfTextFile.UTF8);MessageBox.Show("操作成功");}//读取文件,加载数据private void LoadData(){string JsonStr = AfTextFile.Read("student.txt", AfTextFile.UTF8);if (JsonStr == null) return;Student student = JsonConvert.DeserializeObject<Student>(JsonStr);sdu_Id.Text = Convert.ToString(student.SduId);sdu_Name.Text = student.SduName;sdu_sex.SelectedIndex = student.SduSex?1:0;sdu_phone.Text = student.SduPhone;}}
}
四.图片框与项目资源
1.图片框与资源
(1)添加资源来源:
- 本地文件 : 本地资源路径,比如"D\\Resources\\123.jpg"(注意使用Windows路径格式)
- 项目资源文件:Properties/Resources.resx(项目资源文件夹下)
a.如何添加项目资源文件:双击Properties/Resources.resx->添加资源->添加现有文件->选择本地图片->重命名(规范化,以后使用时直接调用名字使用资源)
b.能添加什么类型的资源:字符串、文本文档、图片、视频、音频等
c.原理:Resources.resx将添加的资源整合到了项目exe当中,因此就算删除源文件也不影响项目运行。在调用资源时,是通过自动生成的方法来获取资源。
d.优点:将资源统一到项目中来,并且可以通过规范化的命名直接调用资源。
e.使用:通过 Properties.Resources.资源名称; 来直接调用你的资源,方便快捷
- 网络资源:比如"http://baidu/image/meinv.jpg"(2)图片资源加载类:
- C# 提供了Image抽象类,作为所有图片资源的总称
- C# 提供了Image抽象类的具体实现类 Bitmap(位图、像素图),来具体加载读取图像。
a.比如Bitmap img = new Bitmap("D\\Resources\\123.jpg");
b.比如Bitmap img = Properties.Resources.img_Conv;
(3)图片框控件:PictureBox
- Size、Location属性:尺寸、位置
- Image属性:图片资源(可以通过本地/项目资源文件导入)
- SizeMode属性:图片的适应模式(StretchImage拉伸图片和图片框相同尺寸、Zoom缩放等)
- ErrorImage、InitialImage属性:加载失败、加载图片显示之前所显示的图片
(4)图片框控件可视化配置:在设计里拖动PictureBox并配置属性即可。
(5)图片框代码手动配置:Bitmap img = Properties.Resources.img_Conv; //读取图片资源 pictureBox.Image = img;//手动设置图片框控件 Image来源 pictureBox.SizeMode = PictureBoxSizeMode.Zoom;//手动设置图片格式
1.添加资源
2.图片框控件展示
界面设计就是简单的放置了一个PictureBox控件,没有过多的设计。图片来源的设置使用代码方式,原因是在以后开发中图片往往不是固定的,需要动态变化,因此使用代码方式动态设置图片来源是比较推荐的。
namespace WindowsFormsApp_learning
{public partial class Form2 : Form{public Form2(){//初始化所有组件InitializeComponent();//初始化PictureBox控件-图片资源Bitmap img = Properties.Resources.img_Conv;pictureBox.Image = img;pictureBox.SizeMode = PictureBoxSizeMode.Zoom;}}
}
WinForm(一) WinForm入门与基本控件使用相关推荐
- Winform开发框架之肖像显示保存控件的实现
我们在开发一些Winform程序的时候,除了常规的显示普通数据外,有的时候需要显示一些人员肖像或者一些车辆等物体的图片,一般这些内容较小,所以以二进制存储在数据库是一个不错的方案.但由于它们虽然很常用 ...
- c#winform演练 ktv项目 关注MediaPlayer控件的状态
c#winform演练 ktv项目 关注MediaPlayer控件的状态 获取媒体控件的状态 一般情况下需要int类型的值,用于方便的判断 (int)媒体控件.playState 例子 弹出媒体控件的 ...
- 在Winform中使用MoonPdfLib(Wpf控件)
在Winform中使用MoonPdfLib(Wpf控件) 引用WindowsFormsIntegration.dll,使用ElementHost类的Child属性关联wpf控件 1.新建winform ...
- (一)C#Winform导入Excel数据到datagridview控件
C#Winform导入Excel数据到datagridview控件 #此次导入Excel数据借助了ExcelDataReader插件.(由于我需要的是打开工作簿时能够选择工作表绑定于datagridv ...
- winform设置Sunny 主题按钮等控件文字图标
winform设置Sunny 主题按钮等控件文字图标 设置Symbol 属性 如果不显示字体图标就设置为0
- 基于OpenCV+WinForm开发的图形图像渲染控件
基于OpenCV+WinForm开发的图形图像渲染控件 WinForm版图形图像渲染控件 图像居中渲染 图像放大 图像缩小 绘制图形 点 线 矩形 圆形 旋转矩形 多边形 资源连接 WinForm版图 ...
- java的显示图片的控件_java Swing GUI 入门-图片和控件可视化
java Swing GUI 入门-图片和控件可视化 觉得有用的话,欢迎一起讨论相互学习~ 加入一张图片 一个Imagelabel 设置居中,命名为logoLabel,Custom Create 打勾 ...
- C#在WinForm中实现清空指定类型控件的内容
实现在Winform中递归控件来清空指定类型控件的内容(因为在Winform中,各个控件是有层次关系的,不能简单地依靠遍历this.controls) private void ClearConten ...
- C# WinForm给Button按钮或其它控件添加快捷键响应
就在这介绍三种添加快捷键的方式. 第一种Alt + *(按钮快捷键) 在大家给button.label.menuStrip等控件设置Text属性时在名字后边加&键名就可以了,比如button1 ...
- WinForm组件开发:构造ImageButton控件
.NET自带的Button按钮和PictureBox在做某种特效的时候很难控制,除了调节属性之外,还要写代码,是不是很麻烦.如果你的开发团队让你构造一个Button组件,来换掉.NET自带的哪个But ...
最新文章
- ITK:将所有像素的总和缩放为常数
- 循环首次适应算法_面向6G的极化编码链路自适应技术
- HALCON示例程序gray_features.hdev提取灰度图的不同特征(area_center_gray 、elliptic_axis_gray)
- 数据结构-栈5-栈的应用-后缀转中缀
- CentOS7.1 KVM虚拟化之经常使用管理虚拟机命令(3)
- C++STL笔记(四):vector详解
- Win32 改变鼠标的光标图片
- python EXCEL表格数据对比
- 第一季 停课模拟考试整理(完结)
- 03系统服务器下安装WMP10实际经验分析
- 8.13.2020 excel表格筛选按钮位置设置
- 我的大学十年 (转)
- ubuntu中的文件管理器
- 网卡驱动收包代码分析之 page reuse
- Synchronized锁升级:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁
- Python开发qq批量登陆
- SAS聚类分析(系统聚类cluster,动态聚类fastclus,变量聚类varclus)
- (zz)计算复杂性:NP=P?
- 机器学习——15分钟透彻理解感知机
- 计算机一级调薪后的工资,义务教育教师基本工资提高10%取消!2019年调资后你的待遇是涨还是降?...
热门文章
- MySQL(5)-----DQL语句的基本查询与高级查询
- strace/linux
- 【java】io流之字符输出流:java.io.Writer类及子类的子类java.io.FileWriter
- 敏捷开发总结(2)开发过程活动
- iOS runtime实用篇解决常见Crash
- 敏感词的字典树匹配(lua版)
- 我的css reset
- 搭建php环境,更换织梦服务器
- 黑马程序员-学习日记(单例设计模式的两种类型)
- 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型...