C#-WinForm图形界面学习笔记

基础语法笔记

1.Parse 方法用于将字符串类型转换成任意类型
2.Convert 方法是数据类型转换中最灵活的方法,它能够将任意数据类型的值转换成任意数据类型,前提是不要超出指定数据类型的范围。
3.C#正则表达式(Regex类)
正则表达式的符号主要分为元字符和表示重复的字符,分别如下表所示。

Using的用法

1.在文件顶部引用命名空间,如:using System;

2.为命名空间或类型定义别名; :using ElseName = This.Is.Very.Very.Long.NamespaceName;

3.使用using,定义范围,在该范围结束时回收资源。

​ 使用前提:该对象必须继承了IDisposable接口,功能等同于try{}Finally{}。

正则表达式中的 元字符

1 . 匹配除换行符以外的所有字符
2 \w 匹配字母、数字、下画线
3 \s 匹配空白符(空格)
4 \d 匹配数字
5 \b 匹配表达式的开始或结束
6 ^ 匹配表达式的开始
7 $ 匹配表达式的结束

正则表达式中 表示重复的字符
1 * 0次或多次字符
2 ? 0次或1次字符
3 + 1次或多次字符
4 {n} n次字符
5 {n,M} n到M次字符
6 {n, } n次以上字符

此外,在正则表达式中使用|分隔符表示多个正则表达式之间的或者关系,也就是在匹配某一个字符串时满足其中一个正则表达式即可。

例如使用正则表达式来验证身份证信息,第一代身份证是由 15 个数字构成的,第二代身份证是由 18 个数字构成的,正则表达式可以写成 \d{15}|\d{18}

在 C# 语言中使用正则表达式时要用到 Regex 类,该类在 System.Text.RegularExpressions 名称空间中。

在 Regex 类中使用 IsMatch 方法判断所匹配的字符串是否满足正则表达式的要求。

1
2
3
4
5
6
7
8
9
10
11
Console.WriteLine("请输入一个邮箱");
string email = Console.ReadLine();
Regex regex = new Regex(@"^(\w)+(\.\w)*@(\w)+((\.\w+)+)$");
if (regex.IsMatch(email))
{
Console.WriteLine("邮箱格式正确。");
}
else
{
Console.WriteLine("邮箱格式不正确。");
}

更多:http://c.biancheng.net/view/2846.html

定义枚举类型的变量的语法形式如下。

1
2
3
4
5
访问修饰符 enum 变量名 : 数据类型
{
值l,
2,
}

结构体类型

1
2
3
4
5
访问修饰符  struct  结构体名称
{
//结构体成员
}

委托

委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。

委托定义

1
public delegate void MyDelegate();

匿名委托

在 C# 语言中匿名委托是指使用匿名方法注册在委托上,实际上是在委托中通过定义代码块来实现委托的作用,具体的语法形式如下。

1
2
3
4
5
6
7
8
//1. 定义委托
修饰符 delegate 返回值类型 委托名 ( 参数列表 );

//2. 定义匿名委托
委托名 委托对象 = delegate
{
//代码块
};

事件

事件定义的语法形式如下。

1
访问修饰符 event 委托名 事件名 ;

C#委托+回调

线程间安全

//通过委托回调

文件操作

C# Driveinfo:获取计算机驱动器信息

C# Directoryinfo类:文件夹操作

C# Directory类:文件夹操作

C# FileInfo类:文件操作

C# File类:文件操作

C# Path类:文件路径操作

C#流简介

C# StreamReader类:读取文件

C# StreamWriter类:写入文件

C# FileStream类:文件读写

C# BinaryReader类:读取二进制文件

C# BinaryWriter类:写入二进制数据

异常与调试

本章内容:

  1. C# Exception:异常类
  2. C# try catch finally:异常处理
  3. C#自定义异常(throw抛出异常)
  4. C# Debug和Trace:输出调试信息
  5. C#程序调试:VS2015调试程序详解

常用的异常类如下图所示。

异常类继承关系图

常用的系统异常类如下表所示。

异常类 说明
System.OutOfMemoryException 用 new 分配内存失败
System.StackOverflowException 递归过多、过深
System.NullReferenceException 对象为空
Syetem.IndexOutOfRangeException 数组越界
System.ArithmaticException 算术操作异常的基类
System.DivideByZeroException 除零错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Program
{
static void Main(string[] args)
{
//定义存放5个整数的数组
int[] a = new int[5];
try
{
for(int i = 0; i < a.Length; i++)
{
a[i] = int.Parse(Console.ReadLine());
}
for(int i = 0; i < a.Length; i++)
{
Console.Write(a[i] + " ");
}
}
catch(FormatException f)
{
Console.WriteLine("输入的数字格式不正确!");
}
catch(OverflowException o)
{
Console.WriteLine("输入的值已经超出 int 类型的最大值!");
}
catch(IndexOutOfRangeException r)
{
Console.WriteLine("数组越界异常!");
}
}
}

进程与线程

Process 类主要提供对本地和远程进程的访问,并提供对本地进程的启动、停止等操作。

线程及与线程有关的类

与线程有关的类同样也都在 System.Threading 命名空间中,主要的类如下表所示。

类名 说明
Thread 在初始的应用程序中创建其他的线程
ThreadState 指定 Thread 的执行状态,包括开始、运行、挂起等
ThreadPriority 线程在调度时的优先级枚举值,包括 Highest、AboveNormal、Normal、BelowNormal、Lowest
ThreadPool 提供一个线程池,用于执行任务、发送工作项、处理异步I/O等操作
Monitor 提供同步访问对象的机制
Mutex 用于线程间同步的操作
ThreadAbortException 调用Thread类中的Abort方法时出现的异常
ThreadStateException Thead处于对方法调用无效的ThreadState时出现的异常

Thread 类主要用于实现线程的创建以及执行,其常用的属性和方法如下表所示。

属性或方法 说明
Name 属性,获取或设置线程的名称
Priority 属性,获取或设置线程的优先级
ThreadState 属性,获取线程当前的状态
IsAlive 属性,获取当前线程是否处于启动状态
IsBackground 属性,获取或设置值,表示该线程是否为后台线程
CurrentThread 属性,获取当前正在运行的线程
Start() 方法,启动线程
Sleep(int millisecondsTimout) 方法,将当前线程暂停指定的毫秒数
Suspend() 方法,挂起当前线程(已经被弃用)
Join() 方法,阻塞调用线程,直到某个线程终止为止
Interrupt() 方法,中断当前线程
Resume() 方法,继续已经挂起的线程(已经被弃用)
Abort() 方法,终止线程

ThreadStart:创建线程

lock 关键字能保证加锁的线程只有在执行完成后才能执行其他线程。使用 TryEnter() 方法可以给它传送一个超时值,决定等待获得对象锁的最长时间。

Mutex 类也是用于线程同步操作的类,例如,当多个线程同时访问一个资源时保证一次只能有一个线程访问资源。 if(mutex.WaitOne()){} //mutex.ReleaseMutex();

多线程与异步程序设计

1.Thread类及其应用
2.线程优先级和线程调度
3.线程互斥
4.线程同步
5.volatile关键词
6.线程池
7.TAP异步编程模式

C#中@的用法

1.加在字符串前面,字符串中的 \ 失去转义符的作用,直接写字符串而不需要考虑转义字符
2.加在字符串前面,字符串中的 “ 要用 “” 表示
3.加在字符串前面,换行空格都保存着,方便阅读代码
4.用关键字做变量时在关键字前面加@
5.作为sql语句里的一个“标签”,声明此处需要插入一个参数

布局

Anchor:设置一个控件的Anchor为ToplRight当窗口大小改变时,该控件锚定于窗口的右上角即,与父窗口的上边距Top和右边距Right保持不变

Dock:停靠,将控件停靠在一侧或中央

FlowLayoutPanel:

TableLayoutPanel:

AfDockLayout:

当设置Dock属性时,Anchor属性无效

对话框的使用

弹出对话框窗口:
MyDialog dlg=new MyDialog();

dlg.ShowDialog(this);

dlg.Dispose();

其中,
-dlg.Show()作为普通窗口显示
-dlg.ShowDialog()作为对话框窗口显示

Form窗口对象含有非托管资源,需要手工销毁

注:Dispose非托管资源,

FormBorderStyle属性的不同效果

属性 意义
FormBorderStyle.None 0 无边框
FormBorderStyle.FixedSingle 1 固定的单行边框
FormBorderStyle.Fixed3D 2 固定的三维样式边框
FormBorderStyle.FixedDialog 3 固定的对话框样式的粗边框
FormBorderStyle.Sizable 4 可调整大小的边框
FormBorderStyle.FixedToolWindow 5 不可调整大小的工具窗口边框
FormBorderStyle.SizableToolWindow 6 可调整大小的工具窗口边框

窗口顶置

registerForm.TopMost = true;

根据鼠标点击的位置,判断点中了哪一项
int index=listBox1.IndexFromPoint(e.Location);

DataGridView

1
2
3
4
5
6
// 取得当前单元格内容 
Console.WriteLine(DataGridView1.CurrentCell.Value);
// 取得当前单元格的列 Index
Console.WriteLine(DataGridView1.CurrentCell.ColumnIndex);
// 取得当前单元格的行 Index
Console.WriteLine(DataGridView1.CurrentCell.RowIndex);

Tag 绑定对象

Listbox

加入对象调用tostring对象

标准类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    class plist
{
public plist() { }

string path;
string name;
public string Path
{
get { return this.path; }
set { this.path = value; }
}

public string Name
{
get { return this.name; }
set { this.name = value; }
}

public plist(string a, string b)
{
this.name = a;
this.path = b;
}
public override string ToString()
{
return this.name;
}
}

案例:图片查看器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog F = new FolderBrowserDialog();
if (F.ShowDialog() == DialogResult.OK)
{
string dir = F.SelectedPath;
textBox1.Text = dir;
ShowPictureList(dir);
}
}
private void ShowPictureList(string dir)
{
listBox1.Items.Clear();
string[] files = Directory.GetFiles(dir);
foreach (string s in files)
{
if (s.EndsWith(".jpg") || s.EndsWith(".png"))
{
plist p = new plist(Path.GetFileName(s), s);

listBox1.Items.Add(p);
}
}
if (files.Length > 0)
{
listBox1.SetSelected(0,true);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
plist p = (plist)listBox1.SelectedItem;
if (p == null) return;
pictureBox1.Load(p.Path);
}

多个窗口之间的数据传递

通过静态字段

通过窗体构造函数

多文档窗体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
父窗体
IsMdiContainer设置为True


SForm child = new SForm();
child.MdiParent=this; //建立父子窗体 关系
child.Show();

//窗体显示方式
this.LayoutMdi(System.Windows.Forms.MdiLayout.xxx);

排列:ArrangeLcons
层叠:Cascade
水平:TileVertical
垂直:TileHorizontal

异步TAP模式

winform自定义控件

创建控件

继承于Control类,就可以从头到尾定制一个控件包含以下几个方面:
1控件的显示(绘制)2控件的行为(事件)3控件的数据(属性)

image-20200418152433287

生成解决方案,工具箱自动添加为true

控件的绘制

重写OnPaint()方法,实现控件的绘制

image-20200418153254612

颜色
指定颜色有两种方式:
Color color=Color.White;或者
Color color=Color.FromArgb([可选],255,255,255)

形状的绘制
本章介绍形状的绘制:
DrawArc圆弧 .
DrawBezier贝塞尔曲线
DrawCurve曲线/多个线段
DrawEllipse 椭圆/圆.
DrawLine 直线.
DrawPie扇形
DrawPolygon多边形
DrawRectangle 矩形.

描边与填充
以Draw打头的方法,称为描边/勾线以Fill打头的文件,称为填充/涂色例如,在描边时,需指定一个笔Pen g.DrawRectangle(pen,rect);在填充时,需指定一个刷子Brush g.FillRectangle(brush,rect);

资源释放

Pen与Brush都包含非托管资源,需要Dispose可以使用using写法

1
2
3
using(Brush brush=new SolidBrush(Color.Red)){
g.FillRectangle(brush,rect);
}

常见形状

DrawLine直线
DrawEllipse 椭/圆
DrawPolygon 多边形
DrawRectangle矩形

1直线Line需指定起点和终点
2矩形Rectangle指定矩形的位置和大小,可以使用Inflate()来缩放矩形
3椭圆/圆Ellipse指定该椭圆所在的矩形

平滑模式SmoothingMode 也称为反锯齿效果,可以将线条显示得更平滑l

g.SmoothingMode=SmoothingMode.HighQuality;

线型与填充色

线型:指定Pen的参数,设置线条参数
比如,点画线的绘制

1
2
pen.DashCap=DashCap.Round;
pen.DashPattern=new float[]{10,2,5,1};

填充:
SolidBrush纯色填充
LinearGradientBrush 线性渐变填充
TextureBrush 纹理填充等

背景与前景

背景:填充整个区域的、一般不变化的OnPaintBackground()
按照官方的建议,背景的绘制应该和前景分开

实例:正弦曲线

WinFormAPI支持的三种线条:
-直线IDrawLine
-圆弧、椭圆弧DrawArc
-贝塞尔曲线DrawBezier

像正弦这种特殊的曲线,API并不支持

多段拟和法

1一个回调方法可以同时注册给多个控件

2为了减轻重绘时的闪烁问题,可以使用“双缓冲”
在自定义控件中,启用DoubleBuffer双缓冲特性

image-20200418163850121

文本的绘制

image-20200418161856008

image-20200418162058416

文本的对齐

image-20200418162819073

1此种方法也适用于多行文本的绘制支持自动换行
2将来如果需要更精细的测算,还可以使用Graphics.MeasureString()
可以测算出一段文本所需的显示空间的大小

添加属性0

给控件添加属性:
-添加一个字段,表示要绘制的内容
-添加属性控制
如果属性名称已经存在,则需要override

this.Invalidate();

[ Browsable(truel)]
[ DesignerSerializationVisibility(DesignerSerialization Visibility.Visible)]

练习:请给它再添加一个属性:BorderColor,用于设置边框的颜色。

image-20200418163637307

实例:自定义日历

图片绘制

使用d.DrawImage()可以绘制图片

g.DrawImage(image,rect)

图片缩放:算法实现

图片截取

在绘制图片时,可以截取图片的一部分显示

image-20200418165806501

高级形状绘制

本章介绍一些高级形状的绘制圆弧Arc、扇形Pie路径Path、不规则形状、圆角矩形
-剪辑区域Clip、蒙版
-半透明叠加效果。。

注意:高级形状,并不代表是常用形状

image-20200418170359659
image-20200418170454602

不规则图形:

image-20200418170619963

剪辑区域:

image-20200418171015938

Region类还支持交并补运算

事件

image-20200419151118288

鼠标事件:

重写方法

鼠标事件:public ovefride OnMouse***()
比如:
OnMouseEnter 鼠标进入OnMouseLeave 鼠标移出
OnMouseDown 鼠标按下OnMouseUp鼠标抬起
OnMouseMove 鼠标移动OnMouseWheel鼠标滚轮
OnMouseClick/MouseDoubleClick单击/双击

image-20200419151723401

状态控制

事件参数:

事件的参数,用于携带事件相关的数据
比如,MouseDown事件的参数:
void button1_MouseDown(object sender,MouseEventArgs e)
在EventArgs里包含了鼠标点击的位置、按键等信息。。

定义事件的参数,按以下三步进行
1添加MyClickEventArgs,继承于EventArgs
2在MyButton中:触发事件时,传递事件参数
3在Form1中:在事件处理方法,取出事件参数

案例:拨号面板

键盘事件

OnKeyPress:

char ch=e.KeyChar;

1区分大小写,比如,’a’和’A’是不同的
2如果一直按着,则KeyPress事件会多次触发

输入焦点

有的控件支持焦点,如TextBox有的控件不支持焦点,如Label设置一个控件是否接受焦点:

this.Setftyle(ControlStyles.Selectable,true);

如果自定义控件不接收焦点,则可以设置为false

image-20200419155319329

Winform

跨线程调用invoke

InvokeRequired 判断当前是否在工作线程

image-20200421160053936

定时任务

定时任务的实现方式:
1.创建工作线程,sleep控制时间间隔

2.创建定时器

System.Timers.Timer(基于线程池)

3.System.Threading.Timer(基于线程池)

4.System.Windows.Forms.Timer(基于消息循环)

System.Threading.Timer一个基于线程池的定时器演示:使用定时器实现倒计时效果。。
1创建定时器
2启动定时器/停止定时器
3在定时器回调中,执行定时任务
(回调在工作线程中执行的)
4窗口关闭时,销毁定时器

image-20200421160751699

image-20200421160820681

image-20200421160833933

image-20200421160854893

System.Windows.Forms.Timer:

界面定时器的回调,直接运行在消息循环中
好处:可以直接更新界面
坏处:必须尽快完成,否则界面卡顿

image-20200421161226183

image-20200421161247814

image-20200421161257133

1.界面定时器的好处:可以直接更新UI控件

2.界面定时器的局限:只适合执行轻量级任务,必须尽快完成,不然界面会卡顿。
对于重量级的定时任务,须使用线程定时器。

短消息提示

特点:
1.弹出式窗口
2.短文本,可以折行显示3根据文本长度,自动调整大小
4.约1.5后后,自动消息I

在WinForm中,所有的窗口都用Form实现I比如,
常规窗口Window
对话框窗口Dialog
悬浮窗口FloatWindow
工具提示Tooltip
弹出式窗口Popup(如菜单窗口、下拉列表窗口)

image-20200421164503937

使用Graphics.MeastureString()可以测算文本的尺寸

Graphics g=this.CreateGraphics();

SizeF size=g.MeasureString(str,this.Font,300);

g.Dispose();

注意,临时创建的Graphics用完之后需要手工销毁

窗口背景

实现方法:
1自己绘制一个圆角矩形背景
2将外围区域透明化
this.BackColor=Color.White;
this.TransparencyKey=Color.White;
//指定透明区域的颜色

托盘通知

NotifyIcon 托盘通知程序可以在通知区创建一个通知图标一般地,可以提示一个气泡通知、右键菜单支持。。

卡片式导航