VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#教程之2016寒假自学笔记

寒假在家无聊,找了一本还不错的电子书来学习,

一是复习了以前最初学的一些基本类,

二是学一些那时候老师没有教的东西,

看的书是pdf的所以下面全部都是手打出来的,有什么错误在所难免。

其实一个寒假只看了这么一点还是很懒惰的。

放上来以后自己好查。以后空闲了还可以看看。
===================================================================================================

快捷键

Ctrl + Enter (在光标指定位置的上面添加一行,并将光标移至新添加行的行首位置)
Ctrl + Shift + Enter (在光标指定位置的下面添加一行,并将光标移至新添加行的行首位置)
Ctrl + Shift + L (删除当前行)

Ctrl + M + O (折叠所有的函数)
Ctrl + M + P (展开所有的函数)

Ctrl + E + C (注释)  <=>   Ctrl + K + C (注释)
Ctrl + E + U (取消注释)  <=>  Ctrl + K + U (取消注释)

Ctrl + R + E  自动生成属性

6: Ctrl + .  (调出using菜单;对于没有实现的类可以自动生成)

7: Ctrl + E + S   (查看空白 -- 将空格转换为绿色的点,在查找多余的空格时尤为方便)

F12  (转到定义)
Ctrl + _  (转到定义后返回)
Ctrl + Shift + _  (再次转到定义)

Ctrl + Atl + P  (Attach to Process 跟踪调试某个进程)

Ctrl + Shift + 左右方向键  (以单词为单位向左或向右选中代码) 

Ctrl + Tab (切换VS中的不同文件窗口)      
Alt + Tab (切换Windows的不同窗口)

prop + Tab + Tab (创建C#中的属性,之后用Tab进行位置的切换)

Ctrl + K + X (Insert Snippet 插入VS定义好的代码模板, 例如 选择其中的Visual C# 之后可以选择好多种不同的模块,例如选择prop name和12的效果是一样的, 还可以选择 try,tryf,using,while 等等,这些可以到VS中实际去看看 )

Ctrl + B + T (标记当前行)
Ctrl + B + P (将光标移动到前一个标记行)
Ctrl + B + N(将光标移动到后一个标记行)
Ctrl + B + C (移除所有的标记行)
Ctrl + W + B (列出所有的标记行,即:打开一个新的窗口,若想打开更多的小窗口请点击VIEW)

【注:标记行可以标记我们所关注的代码段,从而实现不同代码段的切换,例如我想比较两端代码段的异同,或者参照某段代码实现新的功能。当然也肯定不会忘 Ctrl + A, Ctrl + C, Ctrl + V, Ctrl + X, Ctrl + Z, Ctrl + S】

Ctrl + E + D (对当前页VS中的代码块进行格式化) ,选中VS中的代码 然后 Ctrl + E + F (对选中的代码段进行格式化)
===================================================================================================
比较字符串方法:Compare,CompareTo,Equals
1.Compare    int Compare(str1,str2,bool)    比较两个字符串,bool为true就会忽略大小写,返回值0表示相等
2.CompareTo    str1.CompareTo(str2)        其实比较的是在字典中的位置
3.Equals    str1.Equals(str2)        相同返回true,反则false
        string1.Equals(str1,str2)

格式化字符串:    string.Format(str1)
截取字符串:    str1.Substring(int,int)        开始位置,截取字符数量
分割字符串:    str1.Split(char[])        返回一个数组
插入字符串:    str1.Insert(int,str)        插入位置,插入字符串
填充字符串:    str1.padRight(int,char)    padLeft 结果中的字符串数量,填充字符
删除字符串:    str1.Remove(int,int)        开始删除的位置,指定删除的数量
替换字符串:    str1.Replace(str,str)        或者两个char 待替换的字符串,替换的新字符串
===================================================================================================
int[] arr = new int[5]{1,2,3,4,5};
声明一个数组变量可以不对其初始化,但在对数组初始化时必须使用new运算符
string[] arrStr;
arrstr = new string[7]{"sun","mon","tue","wed","thu","fri","sat"}
声明一个两行两列二维数组
int[,] arr = new int[2,2];
int[,] arr = new int[2,2]{{1,2},{3,4}};
初始化时也可以不指定行数和列数
int[,] arr = new int[,]{{1,2},{3,4}};
获取数组的行数与列数
arr.GetLength(0);列数
arr.GetLength(1);行数
冒泡排序
int[]arr = nem int[]{1,9,27,6,12,21,15};
foreach(int m in arr)
{
    for(int i=0;i<arr.Length-1;i++);
    {
        int j=i+1;
        int temp;
        id:
        if(arr[i]>arr[j])
        {
            temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp
        }
        else if(j<arr.Length-1)
        {
            j++
            goto id;
        }
    }
    foreach(int n in arr)
        {
            Console.Write(n+" ");
            Console.ReadLine(n+" ");
        }
}
使用函数进行排序
Array.Sert(arr);从小到大
Array.Reverse(arr);反向排序(从大到小)
===================================================================================================
使用ArrayList集合
ArrayList list = new ArrayList();
ArrayList list = new ArrayList(10);指定大小
ArrayList list = new ArrayList(arr);
ArrayList方法
List.Add(7);将对象添加至集合结尾处
List.Insert(3,7);将元素添加到索引处,将7添加到索引3
List.Clear();从集合中移除所有元素
List.Remove(3);从集合中移除特定对象的第一个匹配对象
List.RemoveAt(3);移除集合中特定索引处的元素
List.RemoveRange(3,2);从索引3开时移除2个元素
List.Contalns(2);判断集合中是否包含指定的元素,返回布尔值
List.IndexOf(3);搜索指定的对象,返回第一个匹配项,否则返回-1
List.LastIndexOf(3);返回最后一个匹配项的索引,否则返回-1
===================================================================================================
使用Hashtable哈希表
Hashtable通常称为哈希表,用于表示键/值的集合,
其每一个元素都是一个存储于DictionaryEntry对象中的键/值对。
键不能为空,但值可以。
Hashtable table = new Hashtable();
table.Add("id","001");添加的元素
table.Clear();移除所有元素
table.Remove("id");移除指定键的元素
foreach(DictionaryEntry dieEntry in table)Hashtable中的元素是一个键/值对,DictionaryEntry类型表示一个键/值对的集合。
table.Contains("id");搜索Hashtable中是否包含特定键,返回布尔值
table.ContainsValue("001");判断是否含有特定值,返回布尔值
===================================================================================================
面向对象
继承:子类可以继承父类中的属性和方法,可以简化类的操作,很大程度上提高开发效率
子类从基类继承时,会获得基类所有的方法,字段,属性,事件。若要更改基类的数据和行为,可以使用新的派生类成员替换基类成员,或者重写虚拟的基类成员。使用新的派生成员替换基类的成员,就需要使用new关键字new关键字放在子类方法,字段,属性的返回类型之前。
属性:get,set
静态方法:静态方法不对特定实例操作,在静态方法中引用this会导致编译错误。
方法重载:调用同一方法名,但各方法中的参数类型,个数,或顺序不同。
结构:是一种值类型,结构中可以包含构造函数,常量,字段,方法,属性,运算符,事件和嵌套类型等,但如果要同时包括上述几种成员则应该考虑使用类。使用struct定义
构造函数:通常用来初始化新对象的数据成员
多重继承:c#的类只支持单继承,而接口支持单继承,实现时,继承的多个接口使用,隔开
多态:多态使子类的实例可以直接赋予基类的对象(不需强制转换)然后通过这个对象调用派生类的方法
封装可以隐藏实现细节,使得代码模块化。
继承可以扩展已经存在的代码块,它们的目的都是为了代码重用。
多态则是为了实现接口重用。
在C#中类的多态性是通过在子类中重写基类的虚方法或者函数成员来实现的。
C#中,继承,虚方法和重写方法组合在一起才能实现多态性。
===================================================================================================
接口
接口是一种用来定义程序的协议,描述可属于任何类或结构的一组相关行为。
接口可由方法,属性,事件,索引器这四种成员类型的任何组成构成,但不能包含字段。
类和结构可以继承多个接口。
继承接口时,将继承成员定义但不继承实现。
若要实现,类中的对应成员必须是公共的非静态的,并具有相同名称与签名。
接口不包含方法的实现,接口自身可从多个接口继承。
声明接口使用 interface 关键字。
接口成员必须是公共的。
显式接口成员实现:返回类型.接口名.方法名。
===================================================================================================
抽象类
抽象类主要用来提供多个派生类可共享的的基类的公共定义。
与非抽象类的区别是抽象类不能实例化,不能被密封,可以包含抽象成员。
声明时使用 abstract 关键字。
从抽象类派生一个非抽象类时,需要在非抽象类中重写抽象方法使用 override 关键字。
抽象类和接口的区别有
它们的派生类只能继承一个基类,只能直接继承一个抽象类,但可以继承多个接口。
抽象类可以定义成员实现,接口不可以。
抽象类可以包含字段,构造函数,析构函数,静态成员,常量等,接口不可以。
抽象类的成员可以是私有的(只要不是抽象的),受保护的,内部的,但接口成员必须是公共的。
抽象类主要用于做对象的系列的基类,共享某些主要特性,例如共同的目的和结构。
接口则主要用于类,这些类在基础水平上,但仍可以完成某些相同的任务。
===================================================================================================
密封类
密封类可以用来控制扩展性,如果密封了某个类,则其他成员不能从该类继承。
如果密封了某个成员,则派生类不能重写对该成员的实现。
声明密封类使用 sealed 关键字
密封类中不能声明受保护成员或者虚成员受保护成员只能在派生类访问,虚成员只能在派生类重写。
密封类不能声明为抽象的。
密封方法只能用于对基类的虚方法进行重写,并提供具体实现。
因此声明密封方法时sealed总和override同时使用
===================================================================================================
枚举类型
枚举是由用户定义的数据类型,其基础类型可以是除Char外的任何整形。
如果没有显式声明基础类型,则使用Int32。
枚举是值类型的一种特殊形式。
枚举类型由名称,基础类型和一组字段组成。
基础类型必须是一个内置的整数类型。
字段为静态文本字段,其中的每一个字段都表示常数。
同一个值可以分配给多个字段但必须将其中某个值标记为主要枚举值,以便进行反射和字符串转换。
enum 枚举名
{
标示名称=整形数据类型值
}
===================================================================================================
泛型
泛型的类型参数T可以看作是一个占位符,它不是一种类型,仅代表某种可能的类型。
泛型接口的声明
interface 接口名<T>
{接口体}
===================================================================================================
LinQ
在c#3.5中声明变量时,可以不明确指定数据类型,使用关键字var来声明。
var number = 2099;
声明var变量需要初始化,不能为null。

Lambda表达式是一个匿名函数,他可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。
所有Lambda表达式都使用Lambda运算符 => 读作goes to。
运算符左边是输入参数(如果有),右边是表达式或语句块。
Lambda表达式无法从封闭方法中捕获ref或out参数。
捕获的变量不会被作为垃圾回收,直到引用变量的委托超出范围为止。

LINQ查询表达式包含8个基本子句。
from            指定数据源和范围变量
select            指定当前查询时返回的序列中的元素将具有的类型和形式
group            按照指定的键值对查询结果进行分组
where            根据一个或多个由逻辑&&和||分隔的布尔表达式筛选元素
orderby            基于元素类型的默认比较器
join            基于两个指定匹配条件之间的相等比较来连接两个数据源
let            引入一个用于存储查询表达式中的子表达式结果的范围变量
into            提供一个标识符,它可以充当对join,group或select子句的引用
===================================================================================================
File类支持对文件的基本操作,它包括用于创建复制删除移动和打开文件的静态方法。
Copy            将现有文复制到新文件
Create            在指定路径创建文件
Delete            删除指定的文件,不存在不引发异常
Exist            确定文件是否存在
Move            将制定文件移动到新位置,并提供指定新文件名的选项
Open            打开指定路径上的FileStream
CreateText        创建或打开一个文件用于写入UTF-8编码的文本
GetCreationTime        返回指定文件或目录的创建日期和时间
GetLastAccessTime    返回上次访问指定文件或目录的日期和时间
GetLastWriteTime    返回上次写入指定文件或目录的日期和时间
OpenRead        打开现有文件以进行读取
OpenText        打开现有UTF-8编码文件以进行读取
OpenWrite        打开现有文件以进行写入
ReadAllBytes        打开一个文本文件,将文件的内容读入一个字节数组,然后关闭该文件
ReadAllLins        打开一个文本文件,将文件的所有行读入一个字符串数组,然后关闭该文件
ReadAllText        打开一个文本文件,将文件的所有内容读入一个字符串,然后关闭该文件
Replace            用其他文件的内容替换指定文件的内容,过程中删除原始文件,创建被替换文件背份
SetCreationTime        设置创建该文件的日期和时间
SetLastAccessTime    设置上次访问文件的日期和时间
SetLastWriteTime    设置上次写入文件的日期和时间
WriteAllBytes        创建一个新文件,将其中写入一个字节数组,然后关闭该文件,存在则改写文件
WriteAllLins        创建一个新文件,将其中写入一个字符串数组,然后关闭该文件,存在则改写文件
WriteAllText        创建一个新文件,将其中写入内容,然后关闭该文件,如果存在该文件,则改写文件

Fileinfo类仅可以用于实例化的对象。
CreationTime        获取当前FileSystemInfo的创建时间
Directiory        获取父目录实例
DirectioryName        获取表示目录完整路径的字符串
Exists            获取指示文件是否存在的值
Extension        获取表示文件扩展名部分的字符串
FullName        获取目录或文件的完整目录
IsReadOnly        获取或设置当前文件是否为只读的值
LastAccessTime        获取或设置上次访问文件的日期和时间
LastWriteTime        获取或设置上次写入文件的日期和时间
Length            获取当前文件大小
Name            获取文件名

Directory类公开了用于创建移动枚举,删除目录和子目录的静态方法
CreateDirectiory    创建指定路径中的所有目录
Delete            删除指定的目录
Exists            确定指定路径是否引用磁盘上的现有目录
GetCreationTime        获取目录的创建日期和时间
GetDirectiories        获取指定目录中子目录名称
GetDirectioryRoot    获取指定路径的根信息,卷信息
GetFiles        返回指定目录中的文件名称
GetFilesSystemEntries    返回指定目录中的文件和子目录的名称
GetLastAccessTime    返回上次访问指定文件或目录的日期和时间
GetLastWriteTime    返回上次写入指定文件或目录的日期和时间
GetParent        检索指定路径的父目录,包括绝对路径和相对路径
Move            将文件或目录及其内容移动到新位置
SetCreationTime        为指定的文件或目录设置创建日期和时间
SetDirectiories        将应用程序的当前工作目录设置为指定的目录
SetLastAccessTime    设置上次访问指定文件或目录的日期和时间
SetLastWriteTime    设置上次写入目录的日期和时间

DirectoryInfo类仅可以用于实例化对象
reationTime        获取或设置当前FileSystemInfo的创建时间
Exists            确定指定目录是否存在的值
Extension        获取表示文件扩展名部分的字符串
FullName        获取目录或文件的完整目录
LastAccessTime        获取或设置上次访问指定文件或目录的日期和时间
LastWriteTime        获取或设置上次写入目录的日期和时间
Name            获取DirectoryInfo文件名
Parent            检索指定子目录的父目录
Root            获取路径的根部分
===================================================================================================
I/O
.NET Framework使用流来支持读取和写入文件。
开发人员可以将流视为一组连续的一维数据,包含开头和结尾,并且其中的游标指示了流当前的位置。
在。NET Framework中,流由Stream类来表示,该类构成了所有其他流的抽象类。
不能创建Stream类的实例,但必须使用它实现某个I/O流类。

FileStrean类,该类公开以文件为主的的Stream,表示在磁盘上或网络路径上指向文件的流。
一个FileStrean类实例实际上代表一个磁盘文件。
CanRead            获取一个值,指示当前流是否支持读取
CanSeek            获取一个值,指示当前流是否支持查找
CanTimeout        获取一个值,确定当前流是否可以超时
CanWrite        获取一个值,指示当前流是否支持写入
IsAsync            获取一个值,指示FileStream是异步还是同步打开的
Length            获取用字节表示的流的长度
Name            获取传递给构造函数的FileStream的名称
Position        获取或设置此流的当前位置
ReadTimeout        获取一个值,确定当前流在超时前尝试读取多长时间
WriteTimeout        获取一个值,确定当前流在超时前尝试写入多长时间
BeginRead方法        开始异步读操作
BeginWrite        开始异步写操作
Close            关闭当前流并释放与之关联的所有资源
EndRead            等待挂起的异步读取完成
EndWrite        结束异步写入,在I/O操作完成前一直阻止
Lock            允许读取访问的同时防止其他进程更改FileStream
Read            从流中读取字节块并将该数据写入指定缓冲区
ReadByte        从文件中读取一个字节,并将读取位置提升一个字节
Seek            将该流的当前位置设置为指定值
SetLength        将该流的长度设定为指定值
Unlock            允许其他进程访问以前锁定的某个文件的全部或部分
Write            使用从缓冲区读取的数据或字节块写入该流
WriteByte        将一个字节写入文件流的当前位置

StreamWriter类是专门用来处理文本文件的类,可以方便的向文本文件中写入字符串。
同时也负责重要的转换和处理向Filestream对象写入的工作。
Encoding属性        获取将输入写入到其中的Encoding
Formatprovider        获取控制格式设置的对象
NewLine            获取或设置由当前TextWriter使用的行结束符字符串
Close方法        关闭当前的StringWriter和基础流
Write            写入到StringWriter的此实例中
WriteLine        写入重载参数指定的某些数据,后跟行结束符

StreamReader类
Close方法        关闭StringReader
Read            读取输入字符串的下一个字符或下一组字符
ReadBlock        从当前流中读取最大的count的字符并从index开始将数据写入Buffer
ReadLine        从基础字符串中读取一行
ReadToEnd        将整个流或从流的当前位置到流的的结尾作为字符串读取

BinaryWriter类以二进制的形式将基元类型写入流
Close方法        关闭当前的Binary和基础流
Seek            设置当前流中的位置
Write            将值写入当前流

BinaryReader类使用特定的编码将基元数据类型读作二进制。
Close方法        关闭当前阅读器和基础流
PeekChar        返回下一个可用的字符,并且不提升字节或字符的位置
Read            从基础流中读取字符,并提升流的当前位置
ReadBoolean        从当前流中读取Boolean值,并使该流的当前位置提升一个字节
ReadByte        从当前流中读取下一个字节,并使该流的当前位置提升一个字节
ReadBytes        从当前流中将Count个字节读入字节数组,并使该流的当前位置提升Count个字节
ReadChar        从流中读取下个字节,并根据Encoding和读取的特定字符提升该流的当前位置
ReadChars        从流中读取Count个字节,并根据Encoding和读取的特定字符提升该流的当前位置
ReadInt32        从当前流中读取4字节有符号整数,并使该流的当前位置提升4个字节
ReadString        从当前流中读取一个字符串,字符串有长度前缀,一次七位的被编码为整数
===================================================================================================
网络编程
DNS类
GetHostAddress        返回指定主机的IP地址
GetHostByAddress    获取ip地址的DNS信息主机
GetHostName        获取本地主机名
IPAddress类
IPEndPoint类
Address属性        获取或设置终结点的ip地址
Port属性        获取或设置终结点的端口号
WebClient类
BaseAddress        设置基URL
Encoding        指定下载字符串的编码方式
OpenRead        获取数据
DownloadFile        将内容保存到文件中
WebReque类
WebResponse类
Socket类
Available属性        获取已从网络接受可供读取的数据量
Accept方法        为新建连接创建新Socket
BeginAccept        开始一个异步操作来接受一个传入的连接尝试
BeginConnect        开始一个对远程主机连接的异步请求
BeginDisconnect        开始异步请求从远程终结点断开连接
BeginReceive        开始从连接的Socket中异步接收数据
BeginSend        将数据异步发送到连接的Socket
BeginSendFile        将文件异步发送到连接的Socket
BeginSendTo        向特定远程主机异步发送数据
Close            关闭Socket连接并释放所有资源
Connect            建立与远程主机的链接
Disconnect        关闭套接字并允许重用套接字
Receive            接受来自绑定的socket的数据
Send            将数据发送到连接的Socket
Sendfile        将文件和可选数据异步发送到连接的Socket
SendTo            将数据发送到特定终结点
Shoutdown        禁用某Socket上的发送和接受
TcpClient类
Client属性        获取或设置基础Socket
Connected        获取值指示是否已经连接到远程主机
ReceiveTimeout        等待接受时的时间量
SendTimeout        等待发射完成的时间量
Connect方法        使用指定的主机名和端口号链接到tcp主机
TCPListener类
UdpClient类
MailMessage类
Attachments属性        获取附件集合
Bcc            获取收件人地址集合
Body            获取或设置邮件正文
BodyEncoding        获取或设置邮件正文编码
CC            获取抄送人的地址集合
From            获取或设置发件人地址
Headers            获取邮件标头
Priority        获取或设置此邮件优先级
ReplyTo            获取或设置邮件的回复地址
Sender            获取或设置此邮件发件人
Subject            获取或设置主题行
SubjectEncoding        获取或设置主题内容编码
To            获取收件人地址集合
Attachment类
ConntentDisposition属性    获取附件MiMe内容标头信息
ConntentStream        获取附件内容流
ConntentType        获取附件内容类型
Name            获取Mine内容类型名称值
NameEncoding        获取用于Name的编码
TransferEncoding    获取或设置附件的编码
CrateAttachmentFromString用字符串创建附件
SmtpClient类
Credentials        获取或设置用于验证发件人身份的凭据
Host            获取或设置用于SMTP事物的主机名称或ip
Port            获取或设置用于SMTP事物的端口
SevicePoint        获取用于传输电子邮件的网络连接
Timeout            指示send方法的超时时间
Send            将电子邮件发送到SMTP服务器,该方法在传输中会阻止其他操作
SendAsync        发送,该方法不会阻止调用线程
SendAsyncCancel        取消异步操作以发送电子邮件
===================================================================================================
线程
每个正在操作系统上运行的应用程序都是一个进程。
一个进程可以包括一个或多个线程。
线程是操作性系统分配处理器时间的基本单元。
在用户使用该线程实例调用Start方法之前,线程都是出生状态。
调用Start方法之后,线程处于就绪状态,获得系统资源后进入运行状态。
线程进入就绪状态,他就会在就绪与运行状态碾转。
同时可能进入等待,休眠,阻塞,死亡状态
进入运行状态的线程调用Thread类Suspend方法时该线程进入等待状态。
进入等待状态的线程必须调用Thread类Resuam方法才能唤醒。
当线程调用hread类Sleep方法时该线程进入休眠状态。
如果一个线程在运行状态下发出输入输出请求,该线程将进入阻塞状态。其等待结束时线程进入就绪状态。
对于阻塞线程来说,即使系统资源空闲,线程依然不能回到运行状态。
当线程执行完毕,线程进入死亡状态。

声明线程Thread thread = new Thrend(new ThreadStart(不带参方法名,不带括号));
声明线程Thread thread = new Thread(delegate() { GetPort(host, port); });
启动线程thread.Start();
挂起线程thread.Suspend();
恢复线程thread.Resume();
休眠线程Thread.Sleep(1000);
终止线程thread.Abort();
阻止调用线程直至线程终止thread.Join();
线程优先级thread.Priority = ThreadPriority.Highest;

lock语句可以用来确保代码块运行完成,不会被其他线程终断。
Object thisLock = new Object();
lock (thislock)
{//代码块}
严格来说,提供给lock语句的参数只是用来唯一标识由多个线程共享的资源,所以可以是任意类实例。
然而,实际上此参数通常表示需要进行同步得资源。

Monitor类通过向单个线程授予对象锁来控制对对象的访问。
当一个线程拥有对象锁时,其他任何线程都不能获取该锁。
Monltor.Enter(this);//锁定当前线程
Monltor.Exit(this);//释放线程

Mutex类是同步基本单元,它只向一个线程授予对共享资源的独占访问权。
如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。
Mutex mutex = new Mutex(false);
mutex.WaltOne();//组织当前线程
mutex.Release.mutex();//释放对象
===================================================================================================
获得鼠标在窗体上的位置
this.labelx.Text = e.X.ToString();
this.labely.Text = e.Y.ToString();

窗体允许拖放文件
窗体load事件中写this.AllowDrop = true;设置窗体允许拖放
窗体DragEnter事件中写
if(e.data.GetDataPresent(Data.Fornats.FileDrop))
{
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
}
 



转载请标明出处

作者:AXuan

地址:http://www.cnblogs.com/Aaxuan



相关教程