文章目录
- .NET Framework概述
- 1、.NET 框架
- 什么是.NET框架?
- .NET框架核心
- 2、CLR
- 3、名称空间
- 面向对象
- 1、面向对象三大特性
- 2、类和对象
- 3、访问修饰符
- 4、静态方法与实例方法区别
- 5、重载
- 6、构造函数
- 7、枚举
- 8、结构体
- 9、类和结构的异同点
- 10、继承
- 11、base关键字
- 12、接口
- 13、抽象类
- 14、密封类
- 15、虚方法和抽象方法的异同点
- 16、接口与抽象类的异同点
- 17、out 和 ref关键字
- 18、值类型与引用类型细分
- 集合与泛型
- 1、常见集合类
- 2、ArrayList
- 2、HashTable
- 3、泛型
- 4、List< T >
- 5、Dictionary< K,V >
- 6、ArrayList与List对比
- 7、泛型的重要性
- XML— .NET框架核心
- 1、XML标记语法规则
- 2、XML文档语法
- 3、XML的属性
- 4、XML文档的注释
- 5、XML文档的数据结构
- 6、XML相关技术
- 7、XML的名称空间
- 文件读写与序列化
- 1、文件读写的步骤
- 2、序列化的含义
- 3、FileMode和FileAccess
- 4、XmlDocument的使用
- 绘图
- 1、绘图的基本步骤
- 2、Graphics、Pen、Brush对象
- 3、DrawLine与鼠标事件实例
- 4、窗体的Paint事件实例
- ADO.NET
- 1、ADO.NET特性
- 2、Connection对象
- 3、Command对象
- 4、DataSet对象
- 5、DataAdapter对象
.NET Framework概述
1、.NET 框架
什么是.NET框架?
.NET Framework(又称 .NET 框架)是由微软开发,一个致力于敏捷软件开发(Agile software development)、快速应用开发(Rapid application development)、 平台无关性和网络透明化的软件开发平台。
框架:类似于Java的虚拟机,但在内部实现上与Java相比有本质区别,不是字节码,速度比Java快。语言:支持C#、C++、VB、J#。
.NET框架核心
2、CLR
CLR:公共语言运行时
CTS和CLS是CLR的子集
CTS (通用类型系统)定义了在IL中的的数据类型
VB.NET的Integer和C#的int型都被编译成Int32
CLS (公共语言规范)CLR支持的语言功能的子集,包括几种面向对象的编程语言的通用功能
3、名称空间
命名空间用于组织相关类和其他类型与Java的package相似。分为系统命名空间和自定义命名空间。 系统命名空间使用using关键字导入。
(1)自定义命名空间
namespace MySchool
{
public class Student
{ }
}
(2)嵌套命名空间
namespace City
{
namespace MySchool
{
namespace Class
{
class Student
{
// 此处编写代码
}
}
}
}
引用命名空间为 using City.MySchool.Class
(3)类库中重要的命名空间
System.Data 用于访问ADO.NET
使用DataTable、DataSet对象
System.IO 用于操作文件
System.Windows.Forms 用于开发Windows应用程序
可以使用MessageBox、Form对象
System.Collections.Generic 可以使用泛型
System.Net 可以对网络协议进行编程
System.Security提供系统的安全控制功能
System.Data.SqlClient用于访问ADO.NET
使用SqlConnection、 SqlCommand等对象
面向对象
1、面向对象三大特性
- 封装
隐藏内部实现,稳定外部接口 - 继承
子类继承父类成员,实现代码复用 - 多态
不同子类对同一个消息作出不同的反映
2、类和对象
对象是人们要进行研究的任何事物
类描述一组相似对象的共性,类的实例化为对象
类的组成
1、字段
就是一些定义的变量,通过访问修饰符(private和public等)分为私有成员和公有成员。
2、属性
即使set访问器和get访问器,这样就不直接访问类的数据,而是通过访问器访问(set/get),从而保护内部数据安全。
3、方法
方法是类或对象的行为。
3、访问修饰符
访问修饰符 | 说明 |
---|---|
public | 访问不受限制,同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问 |
private | 同一类中的代码可以访问 |
protected | 同一类或此类的派生类中的代码可以访问 |
internal | 同一程序集中的任何代码都可以访问,其他程序集中的代码不可以访问 |
Protected internal | 同一程序集中的任何代码、或此类的派生类中的代码可以访问 |
4、静态方法与实例方法区别
使用static修饰的方法称为静态方法,使用实例对象调用的方法叫做实例方法。
静态方法 | 实例方法 |
---|---|
static 关键字 | 不需要static 关键字 |
使用类名调用 | 使用实例对象调用 |
可以访问静态成员 | 可以直接访问静态成员 |
不可以直接访问实例成员 | 可以直接访问实例成员 |
不能直接调用实例方法 | 可以直接访问实例方法、静态方法 |
调用前初始化 | 实例化对象时初始化 |
5、重载
c#语言允许在类中创建同名的方法,但是这些方法需要有不同的参数列表,这称为方法的重载。在调用方法时,编译器会根据不同的方法签名调用相应的方法。
方法签名由方法名和参数列表构成。
public string GetShow(string format)
{
.....
return format;
}
public string GetShow(string format,string name,int a)
{
.....
return name;
}
注:方法重载需要满足参数列表不同,不同可以是参数类型不同和参数个数不同,但是仅仅是参数名称不同是不可以实现重载的。
6、构造函数
- 是类中的一种特殊方法
- 构造函数名与类名相同,不返回任何值
- 可以初始化成员变量
- 构造函数也可以重载
class Student
{
public Student() { }
public Student(string name)
{
this.Name = name;
}
public Student(string name, int age, string hobby)
{
this.Name = name;
this.Age = age;
this.Hobby = hobby;
}
......
}
7、枚举
枚举可以用描述性的名称表示值,使用无须了解它的构成。提高代码维护性,确保变量合法。
- 枚举是一组描述性的名称
- 枚举定义一组有限的值,不能包含方法
- 对可能的值进行约束
- 枚举允许描述性名称表示整数值
public enum Accp
{
S1=1,S2=2,S3=3
}
8、结构体
结构体的定义
public struct StructStudent
{
public string name;
public int age;
public StructStudent(string name,int age)
{
this.name = name;
this.age = age;
}
public void SayHi()
{
Console.WriteLine("Hello");
}
}
结构体的使用
StructStudent stu;
stu.age = 20;
stu.name = "Casey";
StructStudent mstu = new StructStudent();
9、类和结构的异同点
不同点
类 | 结构 |
---|---|
引用类型 | 值类型 |
可以继承 | 不可以继承 |
可以有默认构造函数 | 不可以有默认的构造函数 |
可以添加无参的构造函数 | 可以添加构造函数,但必须带参数 |
创建对象必须使用new | 创建对象可以不使用new |
类中可以给字段赋值 | 结构中给字段赋值是错误的 |
相同点:都可以包含字段方法、都可以实现接口
10、继承
继承是面向对象程序设计中最重要的特性之一。一个类可以被另一个类继承,这个类就拥有它继承的类的所有成员。被继承的类被称为基类,也称为父类。继承基类的类被称为派生类,也称为子类。继承是可以传递的。在c#中,所有类的基类是System.Object。
下列代码中Employee继承了Person类。
class Employee : Person
{
public string id = "ABC567EFG23267";
public void GetEmployeeInfo()
{
// 调用基类的GetInfo方法:
base.GetInfo();
Console.WriteLine("成员ID: {0}", id);
}
}
11、base关键字
base关键字的作用
- 调用父类的属性和方法
- 调用父的构造函数
class Employee : Person
{
public string id = "ABC567EFG23267";
public void GetEmployeeInfo()
{
// 调用基类的GetInfo方法:
base.GetInfo();
Console.WriteLine("成员ID: {0}", id);
}
}
public Student(string name, Genders gender, int age, string hobby, int popularity)
: base(name, age, gender)
{
//继承自父类的属性
this.Name = name;
this.Age = age;
this.Gender = gender;
//base.Name = name;
//学生类扩展的属性
this.Hobby = hobby;
this.Popularity = popularity;
}
12、接口
接口是对一组可以实现的功能的定义,在其中定义了对象必须实现 的成员,通过其实现类来实现。接口不能直接实例化,不能包含成员的任何代码,只定义成员本身。通过interface关键字定义接口。
interface Drawable{
Void draw();
}
class Circle : Drawable{
Public void Draw(){
.....
}
}
13、抽象类
抽象类的特点
- 抽象类只能作为其派生类的一个基类,不能被实例化。
- 抽象类中可以包含抽象成员,但不是必需的。
- 从抽象类派生的非抽象类必需通过重载实现它所继承来的所有抽象成员。
- 抽象类不能是密封的和静态的
抽象类不能实例化,其用途是被其他类继承。在抽象类中,可以通过abstract关键字定义抽象方法。抽象方法实际上是虚方法,不提供方法的具体实现。包含了抽象方法的类必须声明为抽象类。
public override void sayHi(){
....
}
14、密封类
通过在类定义前放置关键字sealed,可以将类声明为密封类。密封类是不能被继承的类,因此密封类不能作为基类,也不能是抽象类。
在对基类的虚成员进行重写的派生类上,可以将方法、属性等成员声明为密封成员。使用密封成员的目的是使成员所在类的派生类无法重载该成员。方法是在类成员声明中将关键字sealed置于关键字override前。
Class Circle : Shape
{
....
public sealed override void Draw(){
....
}
}
15、虚方法和抽象方法的异同点
虚方法 | 抽象方法 |
---|---|
用virtual修饰 | 用abstract修饰 |
要有方法体,哪怕是一个分号 | 不允许 有方法体 |
可以被子类override | 必须被子类override |
除了密封类都可以写 | 只能在抽象类中 |
16、接口与抽象类的异同点
同:
接口和抽象类都可以包含需要实现的成员,两者不能直接实例化,但是其实现类可以被实例化,并可以赋值给接口和抽象类的类型定义的变量,访问其成员。
异:
- 派生类只能继承一个基类,即只能直接继承一个抽象类,但是类可以实
现多个接口。 - 抽象类可以拥有抽象成员,也可以拥有非抽象成员,但是接口的成员没
有代码实现。 - 抽象类的成员可以是私有的,受保护的,内部的和公共的,接口类成员是公共
的。 - 接口不包含常数、字段、运算符、实例构造函数、析构函数或类型,不包含任
何访问修饰符,成员不能是静态的。
17、out 和 ref关键字
引用参数(ref)
在参数前加上ref修饰符声明的参数为引用参数。值类型参数传递的是实参值的副本,而引用类型参数向方法传递的是实参的地址,使实参的存储位置和形参的存储位置相同。因此,在方法中对形参进行的任何改变都会影响实参的值。引用参数,在定义形参时需要ref修饰符,调用方法是的实参与一定要使用ref修饰符。
int Show(ref int a){
.....
}
输出参数(out)
使用out修饰符声明的参数被称为输出参数。输出参数与引用参数类似,在向方法传递参数时,将实参的地址传递给形参。引用参数传递时,变量必须是已赋值的变量,而输出参数传递时,可以是没有初始化的变量。
void Show(ref int x,out int y){
....
}
18、值类型与引用类型细分
集合与泛型
1、常见集合类
.NET Framework提供了常见的集合类。在System.Collections命名空间中包含集合类,在System.Collections.Generic命名空间中定义了泛型集合类。
System.Collections
访问修饰符 | 说明 |
---|---|
ArrayList | 根据大小动态增长的对象集合 |
HashTable | 根据键的哈希进行组织的键/对象集合 |
System.Collections.Generic
访问修饰符 | 说明 |
---|---|
List<Tkey,TValue> | 通过索引访问的集合 |
Dictionary | 根据键和值映射的集合 |
除此之外还有queue,stack ,sortedList
2、ArrayList
(1)ArrayList是一个可动态维护长度的集合
(2)初始化
引入System.Collections命名空间
实例化ArrayList对象
(3)访问ArrayList
//建立班级学员的集合
ArrayList Students = new ArrayList();
Student scofield = new Student("Scofield", Genders.Male, 28, "越狱");
Student zhang = new Student("张三", Genders.Female, 20, "唱歌");
Student li = new Student("李四", Genders.Male, 21, "打篮球");
#region 添加元素 演示
Students.Add(scofield);
Students.Add(zhang);
Students.Add(li);
打印集合数目
//MessageBox.Show(string.Format("共包括 {0} 个学员。",
// Students.Count.ToString()));
#endregion
#region 存取单个元素 演示
//Student stu1 = (Student)Students[0];
//stu1.SayHi();
#endregion
#region 元素遍历 演示
//for (int i = 0; i < Students.Count; i++)
//{
// Student stuFor = (Student)Students[i];
// MessageBox.Show(stuFor.Name);
//}
//foreach (Object stuo in Students)
//{
// Student stuForeach = (Student)stuo;
// MessageBox.Show(stuForeach.Name);
//}
#endregion
//Students.RemoveAt(0);
//Students.Remove(zhang);
2、HashTable
动态可维护长度,通过关键字检索,通过键(key)可以找到相应的值(value)。
Hashtable Students = new Hashtable();
Student scofield = new Student("Scofield", Genders.Male, 28, "越狱");
Student zhang = new Student("张三", Genders.Female, 20, "唱歌");
Student li = new Student("李四", Genders.Male, 21, "打篮球");
Students.Add(scofield.Name, scofield);
Students.Add(zhang.Name, zhang);
Students.Add(li.Name, li);
#region 添加元素 演示
Students.Count.ToString()));
#endregion
#region 存取单个元素 演示
//错误陷阱
Student stu1 = (Student)Students[2];
//stu1.SayHi(); //出错 智能用 key 检索
Student stu2 = (Student)Students["李四"];
stu2.SayHi();
#endregion
#region 元素遍历 演示
foreach (Object stuo in Students.Values)
{
Student stu = (Student)stuo;
MessageBox.Show(stu.Name);
}
#endregion
#region 删除元素 演示
Students.Remove("李四");
#endregion
3、泛型
泛型(generic)是指将类型参数化以达到代码复用,提高软件开发工作者工作效率的一种数据类型。
泛型编程是一种编程范式,它利用“参数化类型”来将类型抽象化,从而实现更为灵活地复用。使用泛型类型可以最大限度地重用代码、保护类型的安全性以提高性能。
4、List< T >
List<Student> students = new List<Student>();
Student scofield = new Student("Scofield", Genders.Male, 28, "越狱");
Student zhang = new Student("张三", Genders.Female, 20, "唱歌");
Student li = new Student("李四", Genders.Male, 21, "打篮球");
Teacher jacky = new Teacher("jacky", 4);
students.Add(scofield);
students.Add(zhang);
students.Add(li);
//students.Add(jacky); //编译时立即报错
students.Remove(scofield);
//students.RemoveAt(0);
//students.Clear();
5、Dictionary< K,V >
Dictionary<K,V>具有List相同的特性。
- <k,v>约束集合中元素类型
- 编译时检查类型约束
- 无需装箱拆箱
- 与哈希表类似存储Key和Value的集合
Dictionary<String, Student> students = new Dictionary<string, Student>();
Student scofield = new Student("Scofield", Genders.Male, 28, "越狱");
Student zhang = new Student("张三", Genders.Female, 20, "唱歌");
Student li = new Student("李四", Genders.Male, 21, "打篮球");
#region 添加元素 演示
students.Add(scofield.Name, scofield);
students.Add(zhang.Name, zhang);
students.Add(li.Name, li);
#endregion
#region 存取单个元素 演示
Student stu2 = students["李四"];
stu2.SayHi();
#endregion
#region 元素遍历 演示
foreach (Student student in students.Values)
{
Console.WriteLine(student.Name);
}
#endregion
#region 删除元素 演演示
students.Remove("李四");
#endregion
6、ArrayList与List对比
7、泛型的重要性
XML— .NET框架核心
1、XML标记语法规则
(1)标记的命名规则
- 名称的开头必须是字母或“_”
- 标记名称中不能有空格
- 名称的字符串只能包含“英文字母”、“数字”、“_”、“-”、“.”等字符
例如下面的标记就是合法标记:
<_name><lisongtao_name><li.name>
(2)标记的使用规则
- 必须具有根标记且根标记必须惟一
- 开始标记和结束标记需配对使用
- 标记不能交错使用
所谓标记的交错使用就是指如下情形的标记使用:
< publisher >< ISBN >7-04-0147688< /publisher >< /ISBN >
在XML中这种标记的交错使用是非法的。应改成:
< publisher>7-04-014768-8< /ISBN >< /publisher>
(3)空标记的使用
所谓空标记指的是标记只有开始没有结束,又叫孤立标记。空标记可写成“<标记名/>”的形式。
(4)标记对大小写敏感
2、XML文档语法
XML是一种语法要求十分严格的标记语言,因此语法有严格的限制。有关XML的基本语法一共有4条:
- 文件的第一条语句必须是有关版本的声明;
- 标记的使用必须遵循XML标记语法规则
- 属性的值必须用引号括起来;
- 特殊字符必须使用XML中特定的编码来表示。
3、XML的属性
XML允许为元素设置属性,用来为元素附加一些额外信息,这些信息与元素本身的信息内容有所不同。一个XML可以包含多个属性,从而存储一个或多个关于该元素的数据。
- 对于非空元素,属性的基本使用格式为:
<开始标记 属性名称1=”属性值” 属性名称2=”属性值”…></结束标记>
或
<开始标记 属性名称1=’属性值’ 属性名称2=’属性值’…></结束标记> - 对于空元素,属性的基本使用格式为:
<空标记 属性名称1=”属性值” 属性名称2=”属性值”…/>
或
<空标记 属性名称1=’属性值’ 属性名称2=’属性值’…/>
4、XML文档的注释
注释语句是其文档中其它形式语句进行提示或说明。XML文档中的注释和HTML文档中的注释是一样的,都是以下列开始符号和结束符号界定的一行或多行代码。
<!–
……
-->
5、XML文档的数据结构
XML的文档由文档头和文档体构成。文档体是指文档中内容信息所在的部分,例如根标记及其以内的所有元素、脚本等。其他的部分构成文档的头部,文档的头部通常是一些声明信息或控制信息,如:处理指令和文档类型定义,其中文档类型定义不是必须的,但合法的XML文档必须具有该部分。文档的“体”部是真正的数据信息,“头”部的信息都是为体部的信息服务的。
6、XML相关技术
CSS、XSL、DTD、XMLSchema 、XML的链接语言
7、XML的名称空间
XML是一种元标记语言,允许用户定义自己的标记,因此,很可能产生名字重复的情况。为了解决这个问题,W3C在1999年1月颁布了名称空间(NameSpace)标准。该标准对名称空间的定义是:XML名称空间提供了一套简单的方法,将XML文档和URI引用标识的名称相结合,来限定其中的元素和属性名。由此可知它通过使用URI,解决了XML文档中标记重名的问题,从而确保任何一篇XML文档中使用的名字都是全球范围内独一无二的。
名称空间的声明
在使用名称空间之前,必须首先进行声明,名称空间的声明类似于前面元素的声明,将一个唯一的标识符号指定到一个URI或其他合法字符串上,使用前面定义的标识符号作为标记的前缀,表示一类标记的出处。
名称空间具有继承性,也就是说,如果不明确声明子元素的名称空间,子元素将继承父元素的名称空间声明。但要注意的是,在默认声明的名称空间范围内,所有的元素及其子元素不加前缀,而在显示声明的名称空间范围内,所有的元素及其子元素必须加前缀。
文件读写与序列化
1、文件读写的步骤
static void Main()
{
byte[] data = new byte[10];//建立字节数组
for (int i = 0; i < 10; i++)//为数组赋值
data[i] = (byte)i;
FileStream fs = new FileStream(@"d:\g1.bin", FileMode.Create);//建立流对象
fs.Write(data,1,8);//写data字节数组中的所有数据到文件
fs.Close();//不再使用的流对象,必须关闭。垃圾收集器不能自动清除流对象
FileStream fs1 = new FileStream(@"d:\g1.bin", FileMode.Open);
byte[] data1 = new byte[fs1.Length];
int n = fs1.Read(data1, 0, (int)fs1.Length);//n为所读字节数
fs1.Close();
Console.WriteLine("文件的内容如下:");
foreach (byte m in data1)
{
Console.Write("{0},", m);
}
Console.WriteLine(".");
Console.WriteLine(n.ToString());
Console.Read();
}
2、序列化的含义
序列化直降一个对象转换成字节流已达到将其长期保存在内存,数据库或文件中的处理过程,它的主要目的是保存对象的状态以便以后需要的时候使用。
序列化(写对象)、发序列化(读对象)
3、FileMode和FileAccess
(1)FileMode: 是指确定如何打开或创建文件,枚举类型
1)FileMode.CreateNew:
用法:创建新的文件,如果文件已存在,则会抛出异常。
2)FileMode.Create:
用法:创建新的文件,如果文件已存在,则覆盖;如果文件不存在,则创建新的。
3)FileMode.Open:
用法:打开文件,如果文件不存在,则会抛出异常。
4)FileMode.OpenOrCreate:
用法:打开或者新建文件夹,如果文件存在,则打开文件,把指针指到文件的开始;如果文件不存在,则新建文件。
5)FileMode.Truncate:
用法:如果文件存在,则打开文件,清除这个文件中的内容,把指针指到文件的开始,保留最初文件的创建日期(重写);如果文件不存在,则抛出异常。
6)FileMode.Append:
用法:追加,如果文件存在,则打开文件,把指针指到文件的末尾;如果文件不存在,则新建文件。
(2)FileAccess 是指确定访问文件方式
1)FileAccess.Read:
用法:获得对文件的读取访问权限,进而可以从文件中读取数据(只读)。
2)FileAccess.Write:
用法:获得对文件的写入访问权限,进而可以将数据写入该文件(只写)。
3)FileAccess.ReadWrite:
用法:获得读取,写入文件的访问权限, 进而可以从文件中读取,写入数据(可读可写)
4、XmlDocument的使用
XmlDocument类代表XML文档在内存中表示,通过XmlDocument类访问XML数据,首先需要利用XmlDocument.Load()方法,从具有XML数据的文件或数据流中读取一个完整的XML数据内存。
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\xmlFile.xml");
利用XmlDocument类将XML文档加载到内存后,可以利用这个类提供的方法获取XML文件中的节点值,添加、修改和删除文档中的某些节点。
绘图
1、绘图的基本步骤
2、Graphics、Pen、Brush对象
(1) Graphics对象
Graphics是画布对象。Graphics类提供一些方法绘制各种图形。Graphics类是密封类,不能有派生类,因此也是抽象类,无法直接实例化而产生绘图对象。
创建Graphics对象的方法一般有下列三种。
- 使用窗体或控件的CreateGraphics方法。
- 利用窗体或控件的paint时间的参数PaintEventArgs.
- 使用Image派生类
//第一种
Graphics g;
g = pictureBox1.CreateGraphics();
//PictureBox1为绘图区域
//第二种
private void Form_Paint(object sender,PaintEventArgs e){
Graphics g = e.Graphics;
}
//第三种
Bitmap bp = nre Bitmap(@"c:\1.jpg");
Graphics g;
g = Graphics.FromImage(bp);
Graphics g=this.CreateGraphics();
Pen pen1=new Pen(Color.Red);
SolidBrush brush1=new SolidBrush(Color.Blue);
g.DrawEllipse(pen1,10,10,100,100);
g.FillEllipse(brush1,10,10,100,100);
(2)Pen类
Pen类对象又称画笔对象,它就像是一枝绘图是所使用的的画笔,可以用来在Graphics对象上绘图。
Pen类的构造函数有4种。
public Pen(Color color);
public Pen(Color color,float width);
public Pen(Brush brush);
public Pen(Brush,float width);
(3)Brush类
Brush类对象指定填充封闭图形内部的样式和颜色
GDI+系统提供了几个预定义画刷类,包括:
SolidBrush:单色画刷,在命名空间System.Drawing中定义。
HatchBrush:阴影画刷,后4个画刷在命名空间System.Drawing.Drawing2D中定义。
TextureBrush:纹理(图像)画刷。
LinearGradientBrush:两个颜色或多个颜色线性渐变画刷。
PathGradientBrush:使用路径定义刷子形状的复杂渐变画刷。
3、DrawLine与鼠标事件实例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace DrawLineDemo
{
public partial class Form1 : Form
{
bool flag = false;
Point point;
List<Point> List_Point = new List<Point>();
Graphics grap; //=this.CreateGraphics();
Pen pen1=new Pen(Color.Red,3);
public Form1()
{
InitializeComponent();
grap = this.CreateGraphics();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
point.X = e.X;
point.Y = e.Y;
flag = true;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
flag = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (flag)
{
grap.DrawLine(pen1,point.X,point.Y,e.X,e.Y);
List_Point.Add(point);
point.X=e.X;
point.Y=e.Y;
List_Point.Add(point);
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
// 一次触发
if (List_Point.Count != 0)
{
Point pt = List_Point[0];
foreach (Point p in List_Point)
{
grap.DrawLine(pen1, pt.X, pt.Y, p.X, p.Y);
pt = p;
}
}
//Graphics g = this.CreateGraphics();
//Pen pen1 = new Pen(Color.Red);
//SolidBrush brush1 = new SolidBrush(Color.Blue);
//g.DrawEllipse(pen1, 10, 10, 100, 100);
//g.FillEllipse(brush1, 10, 10, 100, 100);
}
private void Form1_Load(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
Pen pen1 = new Pen(Color.Red);
SolidBrush brush1 = new SolidBrush(Color.Blue);
g.DrawEllipse(pen1, 10, 10, 100, 100);
g.FillEllipse(brush1, 10, 10, 100, 100);
}
}
}
4、窗体的Paint事件实例
当发生窗体最小化后再最大化、菜单被打开再关闭或打开对话框再关闭等情况,用户区内容可能被破坏。操作系统不保存被破坏的用户区内容,而是由应用程序自己恢复被破坏的用户区内容。
当应用程序窗口用户区内容被破坏后需恢复时,Windows操作系统向应用程序发送Paint事件,应用程序应把在窗口用户区输出数据的语句放在Paint事件处理函数中,应用程序响应Paint事件,能在事件处理函数中调用这些在窗口用户区输出数据的语句恢复被破坏的内容。
Form类窗体不能自动响应Paint事件,程序员必须生成Paint事件处理函数
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace FormPaintDemo
{
public partial class Form1 : Form
{
private bool mark = false;//表示鼠标左键是否按下,如按下鼠标再移动将画曲线
private Point point;//记录画下一条很短线段的起始点。
private List<Point> Point_List; //用来记录1条曲线的所有点。
private List<List<Point>> Line_List;
Pen pen1 = new Pen(Color.Red, (float)3.0);
Graphics g;
public Form1()
{
InitializeComponent();
Line_List = new List<List<Point>>();
g = this.CreateGraphics();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point_List = new List<Point>(); //建立数组,记录1条曲线的所有点
point.X = e.X;
point.Y = e.Y;
mark = true;
Point_List.Add(point); //记录曲线起点的坐标
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mark)
{
g.DrawLine(pen1, point.X, point.Y, e.X, e.Y);
point.X = e.X;
point.Y = e.Y;
Point_List.Add(point); //记录曲线中其它点的坐标
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mark = false;
Line_List.Add(Point_List);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Point p1, p2;
foreach (List<Point> pl in Line_List)//取出每条线
{
for (int k = 0; k < pl.Count - 1; k++)//重画每条线的点
{
p1 = pl[k];
p2 = pl[k + 1];
g.DrawLine(pen1, p1, p2);
}
}
}
}
}
ADO.NET
1、ADO.NET特性
ADO.NET是微软在.NET平台上数据存取问题的解决方案,他不只是ADO的改变版本,实际上是一种全新的数据访问技术。
(1)数据在内存中的表示形式
在ADO中,数据在内存的表示形式为记录集(Recordset),在ADO.NET中,数据的表示形式为数据及(DataSet).
(2) ADO.NET采用了‘断开连接’模式
(3) ADO.NET提供了对XML的内存支持。
2、Connection对象
Connection对象有两种类型:SqlConnection和OleDbConnection.操作过程:创建Conneciton对象,打开数据库连接,访问或操作后台数据库中的数据,数据处理完毕后关闭数据库连接。
打开数据库连接,可以通过调用Connection对象的Open方法。当Connection对象不再使用时,必须释放连接,可以通过调用Connection对象的Close方法或Dispose方法实现。
static void Main(string[] args)
{
//建立连接
SqlConnection cn = new SqlConnection("server=jmucj;database=northwind;uid=sa;pwd=123");
cn.ConnectionString="server=jmucj;uid=sa;pwd=123;database=northwind";
//打开数据库连接
cn.Open();
Console.WriteLine(cn.State);
Console.ReadLine();
//关闭数据库连接
cn.Close();
Console.WriteLine(cn.State);
Console.ReadLine();
}
3、Command对象
连到数据库后,就可以使用Command对象对数据库进行从操作,如进行数据增加,删除,修改等操作,一个Command命令可以用典型的SQL语句来表达,包括执行选择查询来返回记录集,执行动作查询来更新数据库记录,或者创建并修改数据库的表结构。
一个 Command 对象是一个SQL语句或者存储过程的引用。
常用属性:
- CommandText:获取或设置要对数据源执行的T-SQL语句、表名或存储过程名。
- CommandType:获取或设置一个值,该值指示如何解释CommandText属性。Text、 StoredProcedure、DirectTable 的一种
- Connection:获取或设置Command实例使用的Connection
- CommandTimeout:获取或设置在终止执行命令的尝试并生成错误之前的等待时间
- Parameters :可以有零个或多个参数
常用方法:
- ExecuteScalar返回一个惟一的值
- ExecuteReader返回数据行的集合
- ExecuteNonQuery用于更新数据库或改变数据库结构,返回被影响的行数
- ExecuteXmlReader (仅限于SqlCommand)返回一个 XML 的结果集
static void Main(string[] args)
{
//建立连接
SqlConnection cn=new SqlConnection("server=jmucj;database=northwind;uid=sa;pwd=123");
//创建 SqlCommand对象,对数据库进行操作,执行sql语句
SqlCommand cmd = new SqlCommand("select count(*) from products", cn);
//设置Command实例使用的Connection
cmd.Connection = cn;
//打开数据库连接
cn.Open();
//执行ExecuteScalar方法,返回一个惟一的值
int result =(int)cmd.ExecuteScalar();
Console.WriteLine(result);
Console.ReadLine();
//关闭数据库连接
cn.Close();
}
static void Main(string[] args)
{
//建立连接
SqlConnection cn=new SqlConnection("server=jmucj;database=northwind;uid=sa;pwd=123");
//创建SqlCommand对象
SqlCommand cmd=new SqlCommand();
//设置Command实例使用的Connection
cmd.Connection=cn;
//打开数据库连接
cn.Open();
//设置值为StoredProcedure
cmd.CommandType=CommandType.StoredProcedure;
//设置存储过程的名称
cmd.CommandText="getproductlist";
//传入参数@id=4,数据类型为整型
cmd.Parameters.Add(new SqlParameter("@id",SqlDbType.Int,4));
//输入参数@id
cmd.Parameters["@id"].Direction = ParameterDirection.Input;
int id=int.Pachuangrse(Console.ReadLine());
cmd.Parameters["@id"].Value=id;
//调用Command的ExecuteReader方法创建SqlDataReader对象
SqlDataReader reader =cmd.ExecuteReader();
//读取数据库中的内容
while(reader.Read())
{
Console.WriteLine(reader.GetString(1)+" "+reader.GetInt32(3).ToString());
}
//关闭数据库连接
cn.Close();
Console.ReadLine();
}
4、DataSet对象
ADO.NET DadaSet是数据的一种内存驻留表示形式,无论它包含的数据来自什么数据源,都会提供一致的关系编程模型。与关系数据库相似的对象模型保存数据:表、行、列
可以在数据集中定义约束条件与关联
5、DataAdapter对象
DataAdapter对象是ADO.NET数据提供程序的组成部分,充当DataSet和数据源之间用于检索和保存数据的桥梁,,能够检索和保存数据。DataAdapter用来从数据库中读取数据的Command对象存储在DataAdapter对象的SelectCommand属性中。
static void Main(string[] args)
{
//建立与位于运行代码的同一台及其上的SQL server的连接
SqlConnection cn=new SqlConnection("server=localhost;database=northwind;integrated security=sspi");
//创建SqlDataAdapter对象
SqlDataAdapter da = new SqlDataAdapter();
//连接数据库后,创建SqlCommand对象对数据库进行操作
SqlCommand selectcmd=new SqlCommand("select ProductName,UnitPrice,UnitsInStock from products",cn);
da.SelectCommand=selectcmd;
//da.InsertCommand
//da.UpdateCommand
//da.DeleteCommand
//创建数据集对象
DataSet ds=new DataSet();
//调用 SqlDataAdapter对象的Fill方法,使用数据源中的数据生成和填充DataSet表中的每个DataTable
da.Fill(ds,"products");
//获取DataTabla中的每行数据
DataRow[] drs=ds.Tables[0].Select("UnitPrice>100.0");
foreach(DataRow dr in drs)
{
Console.WriteLine(dr[0]);
}
Console.ReadLine();
}
}