C#笔记
C#介绍
.Net平台 .Net FrameWork框架
.Net FrameWork框架提供了一个稳定的运行环境,来保障我们.Net平台正常的运转;
两种交互模式
C/S(Client-Server,分布式模式):要求客户的电脑上必须要安装一个客户端:qq、360、快播等.....
B/S(Browser/Server,浏览器/服务器模式):要求客户的电脑上只需要安装一个浏览器。
.sln:解决方案文件,里面包含着整个解决方案的信息,可以双击运行。
.csproj:项目文件,里面包含着这个项目的信息,可以双击运行。
Console.WriteLine("要打印的内容");
Console.ReadKey();暂停当前程序,等待用户按下任意键继续,按下的任意键将显示在我们的控制台当中
基础语法
注释
1)、单行注释 //
2)、多行注释 /*要注释的内容*/
3)、文档注释 /// 多用来解释类或者方法
数据类型
1)、整数类型:**int** 只能存储整数,不能存储小数。
2)、小数类型:**double** 既能存储整数,也能存储小数,小数点后面的位数 15~16位。
3)、金钱类型:**decimal**:用来村粗金钱,值后面需要加上一个m.
4)、字符串类型:**string**,用来存储多个文本,也可以存储空,字符串类型的值需要被 双引号引来,`这个双引号必须是英文半角状态下的双引号`
5)、字符类型:**char**,用来存储单个字符,最多、最少只能有一个字符,不能存储空。`字符类型的值需要用 单引号因起来。英文半角状态下的单引号。`
命名规则
1)、变量名要有意义
2)、以字母开头,后面跟任意的字母、数字或者下划线,不能有特殊符号
命名规范
1)、Camel 骆驼命名规范。要求变量名首单词的首字母要小写,其余每个单词的首字母要大写。
多用于给变量命名。
2)、Pascal 命名规范:要求每个单词的首字母都要大写,其余字母小写。多用于给类或者方法命名。
运算符
算术运算符:+、-、*、/、%、++、--
关系运算符:==、!=、>、<、>=、<=
逻辑运算符:&&、||、!
赋值运算符:=、+=、-=、/=、%=、<<=、>>=、&=、^=、|=
其他运算符.
sizeof()返回数据类型的大小。
typeof()返回 class 的类型。
类型转换
1)、自动类型转换(隐士类型转换):小的转大的(int--->double)
2)、显示类型转换(强制类型转换):大的转小的(double--->int)
> 语法:(待转换的类型)要转换的值
1)、类型转换(Convert): 可用于类型不兼容 `Convert.Toint32()`
2)、int.parse()
3)、int.Tryparse()尝试着将一个字符串转换成int类型。
转义符
\\ 、\"、\n、\r\n、\b、\t
@符号:
取消\在字符串中的转义作用
将文本按照编辑的原格式输出
判断语句
if 语句
if...else 语句
嵌套 if 语句
switch 语句
三元表达式
循环
while 循环
for/foreach 循环
do...while 循环
循环控制
break 语句
continue 语句
无限循环:for (; ; )
枚举
语法:
[public] enum 枚举名
{
值1,
值2,
值3,
........
}
`枚举名:要符合Pascal命名规范`
结构
可以帮助我们一次性声明多个不同类型的变量。
语法:
[public] struct 结构名
{
成员;//字段
}
变量在程序运行期间只能存储一个值,而字段可以存储多个值。
数组
语法:
数组类型[] 数组名=new 数组类型[数组长度];
数组类型[] 数组名={值1,值2,值3...}
冒泡排序
for(int i=0;i<number.Length-1;i++)
{
for(int j=0;j<nums.Length-1-i;j++)
{
if(nums[j]>nums[j+1])
{
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
}
}
}
方法
函数就是将一堆代码进行重用的一种机制。
🥕函数的语法:
[public] static 返回值类型 方法名([参数列表])
{
方法体;
}
🥕注意:
返回值类型:如果不需要写返回值,写void
方法名:Pascal 每个单词的首字母都大些。其余字母小写
参数列表:完成这个方法所必须要提供给这个方法的条件。如果没有参数,小括号也不能省略。
方法写好后,如果想要被执行,必须要在Main()函数中调用。
🥕方法的调用语法:
类名.方法名([参数]);
***在某些情况下,类名是可以省略的,如果你写的方法跟Main()函数同在一个类中,这个时候,类名可以省略。
GetMax(int n1,int n2)
方法参数
out参数:
如在一个方法中,返回多个相同类型的值的时候,可以考虑返回一个数组。但是,如果返回多个不同类型的值的时候,返回数组就不行了,那么这个时候,我们可以考虑使用out参数。
out参数就侧重于在一个方法中可以返回多个不同类型的值。
ref参数:
能够将一个变量带入一个方法中进行改变,改变完成后,再讲改变后的值带出方法。
ref参数要求在方法外必须为其赋值,而方法内可以不赋值。
params可变参数:
将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理。
params可变参数必须是形参列表中的最后一个元素。
方法的重载
概念:方法的重载指的就是方法的名称相同给,但是参数不同。
方法的递归
方法自己调用自己。
面向对象
面向过程:面向的是完成这件事儿的过程,强调的是完成这件事儿的动作。
面向对象:找个对象帮你做事儿。
类
语法:
[public] class 类名
{
字段;
属性;
方法;
}
写好了一个类之后,我们需要创建这个类的对象,那么,我们管创建这个类的对象过程称之为类的实例化。
使用关键字 new.
语法格式如下:
类名 对象名 = new 类名()
this:表示当前这个类的对象。[类是不占内存的,而对象是占内存的。]
属性
属性的作用就是保护字段、对字段的赋值和取值进行限定。
属性的本质就是两个方法,一个叫get()一个叫set()。
既有get()也有set()我们诚之为可读可写属性。
只有get()没有set()我们称之为只读属性
没有get()只有set()我们称之为只写属性
修饰符
访问修饰符
public:公开的公共的,在哪都能访问。
private:私有的,只能在当前类的内部进行访问,出了这个类就访问不到了。
protected:受保护的:可以在当前类的内部以及该类的子类中访问。
internal:只能在当前项目中访问。在同一个项目中,internal和public的权限是一样。
protected internal:protected+internal
1)、能够修饰类的访问修饰符只有两个:public、internal。
2)、可访问性不一致。
子类的访问权限不能高于父类的访问权限,会暴漏父类的成员。
静态和非静态的区别
1)、在非静态类中,既可以有实例成员,也可以有静态成员。
2)、在调用`实例成员`的时候,需要使用`对象名.实例成员`;
在调用`静态成员`的时候,需要使用`类名.静态成员名`;
总结:`静态成员`必须使用`类名`去调用,而`实例成员`使用`对象名`调用。
静态函数中,只能访问静态成员,不允许访问实例成员。
实例函数中,既可以使用静态成员,也可以使用实例成员。
静态类中只允许有静态成员,不允许出现实例成员。
使用:
1)、如果你想要你的类当做一个"工具类"去使用,这个时候可以考虑将类写成静态的。
2)、静态类在整个项目中资源共享。
只有在程序全部结束之后,静态类才会释放资源。
构造函数
作用:帮助我们初始化对象(给对象的每个属性依次的赋值)
构造函数是一个特殊的方法:
1)、构造函数没有返回值,连void也不能写。
2)、构造函数的名称必须跟类名一样。
注意:
1)、创建对象的时候会执行构造函数
2)、构造函数是可以有重载的。
new关键字
Person zsPerson=new Person();
new帮助我们做了3件事儿:
1)、在内存中开辟一块空间
2)、在开辟的空间中创建对象
3)、调用对象的构造函数进行初始化对象
this关键字
1)、代表当前类的对象
2)、在类当中显示的调用本类的构造函数 :this
析构函数
语法:
~ Class()
{
// Cleaning up code goes here
}
析构函数的名称 是在【类的名称 前加上一个波浪形(~)】作为前缀,它不返回值,也不带任何参数。
析构函数 用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载。
命名空间
可以认为类是属于命名空间的。
如果在当前项目中没有这个类的命名空间,需要我们手动的导入这个类所在的
命名空间。
1)、用鼠标去点
2)、alt+shift+F10
3)、记住命名空间,手动的去引用
值类型和引用类型
区别:
1、值类型和引用类型在内存上存储的地方不一样。
2、在传递值类型和传递引用类型的时候,传递的方式不一样。
值类型我们称之为值传递,引用类型我们称之为引用传递。
我们学的值类型和引用类型:
值类型:int、double、bool、char、decimal、struct、enum
引用类型:string、自定义类、数组
存储:
值类型的值是存储在内存的栈当中。
引用类型的值是存储在内存的堆中。
字符串
1)、字符串的不可变性
当你给一个字符串重新赋值之后,老值并没有销毁,而是重新开辟一块空间存储新值。
当程序结束后,GC扫描整个内存,如果发现有的空间没有被指向,则立即把它销毁。
2)、我们可以讲字符串看做是char类型的一个只读数组。
ToCharArray();将字符串转换为char数组
new string(char[] chs):能够将char数组转换为字符串
字符串提供的各种方法
1)、Length:获得当前字符串中字符的个数
2)、ToUpper():将字符转换成大写形式
3)、ToLower():将字符串转换成小写形式
4)、Equals(lessonTwo,StringComparison.OrdinalIgnoreCase):比较两个字符串,可以忽略大小写
5)、Split():分割字符串,返回字符串类型的数组。
6)、Substring():解决字符串。在截取的时候包含要截取的那个位置。
7)、IndexOf():判断某个字符串在字符串中第一次出现的位置,如果没有返回-1、值类型和引用类型在内存上存储的地方不一样。
8)、LastIndexOf():判断某个字符串在字符串中最后一次出现的位置,如果没有同样返回-1
9)、StartsWith():判断以....开始
10)、EndsWith():判断以...结束
11)、Replace():将字符串中某个字符串替换成一个新的字符串
12)、Contains():判断某个字符串是否包含指定的字符串
13)、Trim():去掉字符串中前后的空格
14)、TrimEnd():去掉字符串中结尾的空格
15)、TrimStart():去掉字符串中前面的空格
16)、string.IsNullOrEmpty():判断一个字符串是否为空或者为null
17)、string.Join():将数组按照指定的字符串连接,返回一个字符串。
继承
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,
单独的封装到一个类中,作为这些类的父类。
【语法】:
<访问修饰符符> class <基类>
{
...
}
class <派生类> : <基类>
{
...
}
【问题】:子类继承了父类,那么子类从父类那里继承过来了什么?
首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。
【问题】:子类有没有继承父类的构造函数?
答:子类并没有继承父类的构造函数,但是。子类会默认的调用父类无参数的构造函数,
创建父类对象,让子类可以使用父类中的成员。
所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,
子类就调用不到了,所以子类会报错。
解决办法:
1)、在父类中重新写一个无参数的构造函数。
2)、在子类中显示的调用父类的构造函数,使用关键字:base()
继承的特性
1、继承的单根性:一个子类只能有一个父类。
2、继承的传递性
new关键字
1)、创建对象
2)、隐藏从父类那里继承过来的同名成员。
隐藏的后果就是子类调用不到父类的成员。
里氏转换
1)、子类可以赋值给父类
2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象。
2、子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。
---------------------------------------------------------
// Student s = new Student();
Person p = new Student();//s;
Person p1 = new Teacher();
if (p is Student)
{
Student ss = (Student)p;
ss.StudentSayHello();
}
else {
Console.WriteLine("转换失败");
}
-----------------------------------------------------------
is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false
as:表示类型转换,如果能够转换则返回对应的对象,否则返回一个null
集合
【ArrayList】
Add:在 ArrayList 的末尾添加一个对象。
AddRange:在 ArrayList 的末尾添加 ICollection 的元素。
Remove:从 ArrayList 中移除第一次出现的指定对象。
RemoveAt:移除 ArrayList 的指定索引处的元素。
RemoveRange:从 ArrayList 中移除某个范围的元素。
Insert:在 ArrayList 的指定索引处,插入一个元素。
InsertRange:在 ArrayList 的指定索引处,插入某个集合的元素。
clear:从 ArrayList 中移除所有的元素。
Reverse:逆转 ArrayList 中元素的顺序。
Sort:对 ArrayList 中的元素进行排序。
【注意】ArrayList集合的长度问题
每次集合中实际包含的元素个数(count)超过了可以包含的元素的个数(capcity)的时候,
集合就会向内存中申请多开辟一倍的空间,来保证集合的长度一直够用。
-----------------------------------------------------------------
【Hashtable】
解释:创建一个键值对集合对象。
怎样根据键去找值 ht[键]=值;
ContainKey(key):x判断是否包含指定的键值
【注意】键值对集合当中,键必须是唯一的,而值是可以重复的
foreach循环
int[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定义一个2行2列2纵深的3维数组a
foreach(var i in a)
{
Console .WriteLine (i);
}
【注意】
Var:根据值能够推断出来类型。<不足点>:在生命var的同时必须赋值
泛型集合
List<T>
【解释】:泛型的List 类是一个不限长度的集合类型,它内部实际就是一个数组,初始长度是4,`每次数组到达限制,就会把现有容量翻倍`,它提供用于对集合进行搜索、排序和操作等方法
----------------------
//创建泛型集合对象
List<int> list = new List<int>();
list.AddRange(new int[]{1,2,3,4,5,6});
//List泛型集合转换为数组
int[] nums = list.ToArray();
List<String> listStr = new List<String>();
string[] str = listStr.ToArray();
//数组转结集合
char[] chs = new char[]{'a','b','c'};
List<char> listChar = chs.ToList();
----------------------
泛型集合:不会发生拆箱装箱。
字典
Dictionary<Tkey,Tvalue>
【说明】
必须包含名空间System.Collection.Generic
Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)
键必须是唯一的,而值不需要唯一的
键和值都可以是任何类型(比如:string, int, 自定义类型,等等)
通过一个键读取一个值的时间是接近O(1)
键值对之间的偏序可以不定义
//定义
Dictionary<string, string> openWith = new Dictionary<string, string>();
//添加元素
openWith.Add("txt", "notepad.exe");
openWith.Add("bmp", "paint.exe");
//遍历字典
foreach (KeyValuePair<string, string> kvp in openWith)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
【详细介绍】:https://www.cnblogs.com/txw1958/archive/2012/11/07/csharp-dictionary.html
Path
1)Path类是static类型
2)常用方法
Path.GetFullPath(file) 取全路径
Path.GetFileName(file) 取文件名,包含扩展名
Path.GetFileNameWithoutExtension(file) 取文件名,不包含扩展名
Path.GetExtension(file) 取扩展名
Path.GetDirectoryName(file) 取路径名
Path.GetPathRoot(file) 取盘符
Path.Combine(file1,file2) 合并2个路径
3)注意事项
a.使用前需要对参数进行判空,其次追加try catch来捕获Exception。
string fullpath7 = null;
if (!String.IsNullOrWhiteSpace(file))
{
try
{
fullpath7 = Path.GetFullPath(file);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
b.GetFullPath()可以将多个 / \ 合并为1个,使之格式化为合法的路径。末尾的\会保留。
c.GetDirectoryName()结果末尾没有\。
d.Combine() 不会合并多个 / \ ,第二个参数不能以/ \ 开头。
e.利用GetDirectoryName()和Combine()去掉末尾\.
string dir2 = Path.GetDirectoryName(Path.Combine(@"D:\1","Temp")); // D:\1
string dir3 = Path.GetDirectoryName(Path.Combine(@"D:\1\", "Temp")); // D:\1
【详细介绍】:https://www.cnblogs.com/wyvern0618/p/9454627.html
File
File.Create( string path):在指定路径中创建或覆盖一个文件(注意:如果指定路径下已经有此文件,那么原有的会被覆盖)
File.Delete( string path):根据指定路径删除一个文件(注意:此删除是彻底删除,回收站也没有)
File.Copy( string originPath, string newPath):根据指定路径复制一个文件;(参数一:要复制的文件路径参数二:复制出来的新的文件路径及文件名字)
File.Exists( string originPath ):判断一个文件是否存在,参数为文件路径,返回值为布尔类型;
File.Move():将指定的文件移到新位置(等于剪切一个文件到新的地方);(参数一:原始文件路径;参数二:新的文件路径及名字。)
File.ReadAllBytes():读取一个文件内容,返回的是这个文件内容的字节数组;
File.ReadAllLines(string path, Encoding.encoding):读取一个文件的所有行,返回包含文件所有行的字符串数组;
(参数一:文件的路径;参数二:编码格式,如果不指定编码格式,所输出的文件内容很有可能是乱码!!!)
File.ReadAllText(string path, Encoding.encoding)读取一个文件的所有行,返回包含文件所有行的字符串;
(与ReadAllLines区别在于:返回的结果不同;)
读写数据
ReadAllBytes() 字节数组---字符串 Encoding.Default.GetString(字节数组)
WriteAllBytes() 字符串--->字节数组 Encoding.Default.GetBytes(字符串)
【详细介绍】https://blog.csdn.net/qq_42778001/article/details/109081166
FileStream
FileStream文件流 只能处理原始字节(raw byte)。FileStream 类可以用于任何数据文件,而不仅仅是文本文件。FileStream 对象可以用于读取诸如图像和声音的文件,FileStream读取出来的是字节数组,然后通过编码转换将字节数组转换成字符串。
三步:
1.创建文件读写流对象
2.对文件进行读写
3.关闭文件流
【详细介绍】https://blog.csdn.net/qq_41209575/article/details/89178020
StreamReader和StreamWriter
【详细介绍】https://www.runoob.com/csharp/csharp-text-files.html
装箱、拆箱
装箱:就是将值类型转换为引用类型。
拆箱:将引用类型转换为值类型。
看两种类型是否发生了装箱或者拆箱,要看,这两种类型是否存在继承关系。
实现多态的手段
1)、虚方法
步骤:
1、将父类的方法标记为虚方法 ,使用关键字 virtual,这个函数可以被子类重新写一个遍。
2)、抽象类abstract
当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法。
抽象类
在C#中使用关键字 abstract 来定义抽象类和抽象方法
不能初始化的类被叫做抽象类
一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被实例化,进一步
一个抽象类只能通过接口和作为其它类的基类使用
一个抽象类可以包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现所有的
的基类抽象方法。
一个抽象方法是一个没有方法体的方法。
【详细介绍】:https://www.cnblogs.com/flyinthesky/archive/2008/06/18/1224774.html
虚方法
【定义】
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法,虚方法是使用关键字virtual声明的,虚方法可以在不同的继承类中有不同的实现,即为基类中定义的允许在派生类中重写的方法;
【格式】
访问修饰符 virtual 函数返回类型 函数名(参数表) {函数体};
【示例】
class Person
{
public virtual void XXX()
{
Console.WriteLine("我有一个梦想,那就是动身去往远方!!");
}
}
【调用】
class Person
{
public virtual void XXX()
{
Console.WriteLine("我有一个梦想,那就是动身去往远方!!");
}
}
class Boy : Person
{
public override void XXX()
{
Console.WriteLine("我不想继承父类的虚方法");
}
public void SSS()
{
Console.WriteLine("不学习就不会进步,不仅不就没有出人头地的机会");
}
}
class Program
{
static void Main(string[] args)
{
Person person = new Person();//实例化的虚方法类
Boy boy = new Boy();//实例化的子类
boy.XXX();//调用了子类的方法
boy.SSS();
Console.ReadLine();
}
}
【详细介绍】:https://blog.csdn.net/qq_45096273/article/details/106816397
序列化和反序列化
部分类
partial
密装类
sealed
重写
override
接口
interface
【格式】:
[public] interface I..able
{
成员;
}
【注意】:
1)接口中的成员不允许添加修饰符,默认就是public。
2)不允许写具有方法体的函数。
3)只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员。
4)接口中的成员不能有任何实现(“光说不做”,只是定义了一组未实现的成员)。
5)接口不能被实例化。也就是说,接口不能new(不能创建对象)。
6)接口中只能有方法、属性、索引器、事件,不能有“字段”和构造函数。
7)接口与接口之间可以继承,并且可以多继承。
8)接口并不能去继承一个类,而类可以继承接口 (接口只能继承于接口,而类既可以继承接口,也可以继承类)
9)实现接口的子类必须实现该接口的全部成员。
19)一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。即:
class MyClass:A,IA{},因为类是单继承的。
【问题】:
显示实现接口的目的:
解决方法的重名问题
什么时候显示的去实现接口:
当继承的借口中的方法和参数一摸一样的时候,要是用显示的实现接口
当一个抽象类实现接口的时候,需要子类去实现接口。
WinForm窗体
【介绍】
winform应用程序是一种智能客户端技术,我们可以使用winform应用程序
帮助我们获得信息或者传输信息等。
【属性】
Name:在后台要获得前台的控件对象,需要使用Name属性。
visible:指示一个控件是否可见。
Enabled:指示一个控件是否可用。
ContextMenuStrip 右键菜单
Cursor 鼠标光标
FlatStyle 框架外观
【事件】:发生一件事情。
注册事件:双击控件注册的都是控件默认被选中的那个事件。
触发事件:
Load 加载
Mouse Enter 当鼠标移进去,触发事件
TextBox控件
WordWrap:指示文本框是否换行。
PasswordChar:让文本框显示一个单一的字符
ScollBars:是否显示滚动条
【事件】:
TextChanged 当文本框中的内容发生改变的时候触发这个事件。
Timer
在指定的时间间隔内做一件指定的事情。
【事件】:
Tick 每当经过指定的时间间隔发生的事件。
ListBox控件
listBox1.SelectedIndex 当前索引
DoubleClick 双击事件
SoundPlayer音乐播放
SoundPlayer sp = new SoundPlayer();
sp.SoundLocation = @"D:\InstallationDirectory\TIM_3.3.8.22043_Green\TIM\Plugin\Com.Tencent.AudioVideo\Misc\SoundTest.wav";
sp.Play();
Directory类 -操作文件夹
CreateDirectory 创建文件夹
Delete删除文件夹
Move剪切文件夹
//获取文件下所有文件的全路径
string[] path = Directory.GetFiles(@"D:\GUO");
for(int i = 0; i < path.Lenght; i++)
{
Console.WriteLine(path[i]);
}
//Exists判断给的路径在电脑上是否存在。
if(Directory.Exists(@"c:\a\b"))
{
for(int i = 0; i < 100; i++)
{
Directory.CreateDirectory(@"c:\a\b" + i);
}
}
WebBrownser控件
url网页地址
Uri uri = new Uri("http://" + text);
ComboBox控件 -下拉框
comboBox.Items.Add();
comboBox.Items.clear()/remove()/removeAt();
|--------
DropDownStyle:控制下拉框的外观样式
[事件]:
SelectedIndexChanged:SelectedIndex属性值更改时发生的事件
单选和多选
checked:指这个控件是否处于选中状态
默认情况下,可以使用GroupBox进行分组。
打开对话框
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "请选择要打开的文本文件";
ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
ofd.Multiselect = true;
ofd.Filter = "文本文件|*.txt|所有文件|*.*";
ofd.ShowDialog();
保存对话框
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "请选择要保存的路径";
sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
sfd.Filter = "文本文件|*.txt|所有文件|*.*";
sfd.ShowDialog();
//获得保存文件的路径
string path = sfd.FileName;
if (path == "")
{
return;
}
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] buffer = Encoding.Default.GetBytes(textBox1.Text);
fsWrite.Write(buffer, 0, buffer.Length);
}
MessageBox.Show("保存成功");
}
字体和颜色对话框
//字体对话框
private void button1_Click(object sender, EventArgs e)
{
FontDialog fd = new FontDialog();
fd.ShowDialog();
textBox1.Font = fd.Font;
}
//颜色对话框
private void button2_Click(object sender, EventArgs e)
{
ColorDialog cd = new ColorDialog();
cd.ShowDialog();
textBox1.ForeColor = cd.Color;
}
自动换行
private void 自动换行ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (自动换行ToolStripMenuItem.Text == "☆自动换行")
{
textBox1.WordWrap = true;
自动换行ToolStripMenuItem.Text = "★取消自动换行";
}
else if (自动换行ToolStripMenuItem.Text == "★取消自动换行")
{
textBox1.WordWrap = false;
自动换行ToolStripMenuItem.Text = "☆自动换行";
}
}
MDI窗体的设计
``
1、首先确定一个父窗体。 将IsMdiContainer设置为true。
2、创建子窗体,并且设置他们的父窗体。
private void 显示子窗体ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.MdiParent = this;
frm2.Show();
Form3 frm3 = new Form3();
frm3.MdiParent = this;
frm3.Show();
Form4 frm4 = new Form4();
frm4.MdiParent = this;
frm4.Show();
}
private void 横向排列ToolStripMenuItem_Click(object sender, EventArgs e)
{
LayoutMdi(MdiLayout.TileHorizontal);
}
private void 纵向排列ToolStripMenuItem_Click(object sender, EventArgs e)
{
LayoutMdi(MdiLayout.TileVertical);
}
#### PictureBox控件
SizeMode 如何处理控件的位置和大小
-------------------------
🥕

浙公网安备 33010602011771号