Upload
pikachu89
View
1.223
Download
1
Embed Size (px)
Citation preview
Nội dung học
• Tổng quan về .net FrameWork• Ngôn ngữ lập trình C#• Ngôn ngữ lập trình hướng đối tượng với
C#• Xử lý dữ liệu với ADO.NET• Xây dựng ứng dụng Web
CHƯƠNG I
Giới thiệu• .NET Framework là môi trường tích hợp để đơn giản
hóa việc phát triển và thực thi các ứng dụng trênInternet, desktop và các thiết bị di động .
• Các mục tiêu chính:• Cung cấp một môi trường hướng đối tượng nhất quán
cho nhiều loại ứng dụng• Cung cấp một môi trường giảm tối thiểu sự xung đột
phiên bản.• Cung cấp một môi trường linh động, dựa trên các
chuẩn đã được chứng nhận để có thể chứa trên bấtcứ hệ điều hành nào.
Kiến trúc của .NET Framework
Kiến trúc của .NET Framework•CLR (Common Language Runtime): Quản lý sựthực thi mã lệnh và tất cả các tác vụ liên quan đếnnó: biên dịch, quản lý bộ nhớ, bảo mật, quản lýtuyến đoạn.Mã lệnh thực thi trong CLR chia làm 2 loại:- mã được quản lý- mã không được quản lý là mã lệnh không cài đặtnhững yêu cầu để thực thi trong CLR – chẳng hạnnhư COM hoặc các thành phần dựa trên Windows API.
Kiến trúc của .NET Framework
•FCL(Framework Class Library ) là thư việnkiểu dữ liệu có thể tái sử dụng (gồm cácclass, structure, …) dành cho các ứng dụngthực thi trong .NET. •Tất cả các ngôn ngữ hỗ trợ .NET Framework đều sử dụng thư viện lớp dùngchung này.
Các bước thực hiện của Ct truyền thống
SourceCode
Compiler
ExecutableCode
Code Executed
RUNTI
ME
Các bước thực hiện của Ct truyền thống
• Các ngôn ngữ trước đây có chươngtrình dịch riêng và có môi trường chạyriêng của nó.
• Trong .NET, chương trình dịch dịch mãnguồn vào một "Intermediate Language (IL)“ và runtime được thay thế bởi CLR (Common Language Runtime).
Các bước thực hiện của các ct .NET
1st Compliation
2nd Compliation
.NETSourceCode
LanguageCompiler
MSIL+
MetadataCLR Machine
codeCode
executed
Các chương trình .NET được dịch 2 lần: lần đầu chậm, lần thứ 2 tươngđối nhanh hơn.
Các bước thực hiện của các ct .NET
• Chương trình nguồn trước hết sẽ được biêndịch và đóng gói thành một khối gọi là assembly (là tập hợp các thành phần được đóng gói trongfile exe hoặc dll). Khối này sẽ chứa các mã lệnhngôn ngữ trung gian (IL) và các metadata mô tảthông tin cần thiết cho sự hoạt động của khối.
• Mỗi khi có yêu cầu thực thi assembly nói trên, CLR sẽ dùng trình biên dịch JIT (Just-in-Time)của môi trường thực thi để chuyển đối IL chứatrong nó sang dạng mã lệnh cụ thể của máy khiứng dụng thực sự thực thi.
Các bước thực hiện của các ct .NET
Các kiểu dữ liệu cơ sở của CTS
Nội dung
• Giới thiệu• Môi trượng soạn thảo và chạy• Biến và các kiểu dữ liệu• Các cấu trúc điều khiển: if, switch• Các cấu trúc lặp; for, while, do while,
foreach• Mảng, ArrayList, File văn bản.• Bài thực hành
GIỚI THIỆU VỀ C#• Là NNLT đơn giản, hiện đại, an toàn và
hướng đối tượng• Là ngôn ngữ mạnh nhất trong .NET• Thay thế cho C++• Có cú pháp giống C++, Java• Sử dụng con trỏ dễ dàng hơn trong C++
GIỚI THIỆU VỀ C#
- “bài toán” cần giải quyết là một solution.- Một solution bao gồm một hoặc nhiều
project.- Một solution, nếu có nhiều project thì nênđược tạo ra trong một thư mục riêng để cóthể chứa các project trong nó.
Cú pháp đơn giản của 1 Project•Using các Namespace [Namespace Ten]{
- Tập hợp các lớp}Trong các lớp phải có lớp chứa hàm main, chương trình luôn bắt đầu từ hàm mainpublic static void Main(string[] args)
{}
Dịch và chạy 1 chương trình C# trên Console• Soạn mã: Người sử dụng có thể dùng bất kỳ
trình soạn thảo nào như:– Notepad– Microsoft Visual Studio– ….
• Lưu lại thành file có phần mở rộng .cs• Start|Programs|Microsoft .NET Framework SDK
v2.0|SDK Command Prompt– Gõ csc [ổ đĩa:]\[ đường dẫn]\<tên file .cs> cần dịch– Gõ tên file cần chạy
• Chú ý: file csc.exe định vị ở:– "C:\Program Files\Microsoft Visual Studio 8\ SDK\
v2.0\“ đối với 2005– C:\WINNT\Microsoft.NET\Framework\v1.1.4322 đối
với 2003
Ví dụ chương trình đơn giảnusing System;class Test{public static void Main(){
string varStr;varStr = “A simple program";Console.WriteLine(varStr);
}}
Sử dụng IDE Microsoft Visual Studio 2005• Khởi động Microsoft Visual Studio 2005. File
New Project để tạo mới một project
Biến
• Khai báo theo cú pháp:
Mức truy cập Kiểu Tên biến
public
protected
private
int
string
...
Các kiểu số nguyênTên Kiểu trong
CTSMô tả Vùng biểu diễn
(min:max)sbyte System.SByte Số nguyên có dấu 8-bit -27:27-1
short System.Int16 Số nguyên có dấu 16-bit -215:215-1
int System.Int32 Số nguyên có dấu 32-bit -231:231-1
long System.Int64 Số nguyên có dấu 64-bit -263:263-1
byte System.Byte Số nguyên không dấu 8-bit 0:28-1
ushort System.UInt16 Số nguyên không dấu 16-bit 0:216-1
uint System.UInt32 Số nguyên không dấu 32-bit 0:232-1
ulong System.UInt64 Số nguyên không dấu 64-bit 0:264-1
Kiểu số thực, Boolean, ký tự
• Kiểu số thực: float, double• Kiểu Boolean: bool: true|false• Kiểu ký tự: char
– Biểu diễn 1 ký tự 16-bit (Unicode) Các hằngkiểu ký tự được gán bằng cách đóng trongcặp dấu nháy đơn, ví dụ 'A'.
Kiễu dữ liệu tham chiếuđược định nghĩa sẵn
Tên Kiểu CTS Mô tả
object System.Object Kiểu dữ liệu gốc, mọi kiểu dữ liệu kháctrong CTS đều kế thừa từ đây (kể cảcác kiểu dữ liệu giá trị)
string System.String Chuỗi ký tự Unicode
Ví dụclass Program
{static void Main(string[] args){
object t;t = (object) 5;string[] st = new string[2] { "ab","cd" };object[] t1;t1 = st;Console.Write(t1[1].ToString());Console.ReadLine();
}}
Các phương thức trên chuỗiusing System;class ThaoTacTrenString
{static void Main(string[] args){ string st1=" Nguyen Anh Trung ";
string st2 = "le Tien Tang";st1 = st1.Trim();Console.Write("Chieu dai chuoi la {0}:\n", st1.Length);Console.WriteLine("Ky tu tai chi so thu 3 la {0}", st1[3]); string ten1=st1.Substring(st1.LastIndexOf(' ')+1);string ten2 = st2.Substring(st2.LastIndexOf(" ")+1,
st2.Length - st2.LastIndexOf(" ")-1); Console.WriteLine("Ten2=ten1:{0}",ten2.Equals(ten1));Console.WriteLine("so sanh ten1 voi ten 2: {0}",ten1.CompareTo(ten2));Console.ReadLine();
}}
Các phương thức trên chuỗiusing System;class ThaoTacTrenString
{static void Main(string[] args){ string st1="Nguyen Anh Trung ";
Console.WriteLine("Tim chuoi con {0}", st1.Contains("yen"));st1=st1.Replace("Nguyen", "Le"); Console.WriteLine(st1);st1=st1.Remove(0, 3);Console.WriteLine(st1);st1 = "Le nam|tink26-dhkh";char[] ts = new char[2] { '|', '-' };string[] ds = st1.Split(ts);
Console.WriteLine("ten:{0},lop:{1},truong{2}", ds[0], ds[1], ds[2]);}
} ….
Các toán tửLoại toán tử Ký hiệuSố học + - * / % Logic && || ! Cộng chuỗi + Tăng và giảm ++ --Dịch bit << >>So sánh == != < > <= >= Phép gán = += -= *= /= %= &= |= ^= <<= >>= Truy xuất thành phần . Indexing (cho array và các indexers) [] Ép kiểu () Điều kiện ?: Tạo đối tượng new Thông tin về kiểu Sizeof(Kiểu)Điều khiển Overflow exception checked unchecked
Luồng điều khiển của chương trình• Các câu lệnh rẻ nhánh
– if– switch
• Các câu lệnh lặp– for– while– do– foreach
Câu lệnh ifusing System;class Test{
public static void Main(){
int i = 10;if (i<10){
Console.WriteLine("less than 10");}else{
Console.WriteLine("greater or equal to 10");}
}}
Câu lệnh Switch ...int i = 2;switch (i){
case 1:Console.WriteLine("one");break;
case 2:Console.WriteLine("two");break;
default:Console.WriteLine("another value");
break;}...
Câu lệnh For [1]using System;class Test{public static void Main(){int s = 0;for (int i=1; i<=10; i++){
s+=i;}Console.WriteLine(s);
}}
Câu lệnh For [2]Phạm vi của biến đếm: chỉ có tác dụngtrong vòng lặp. using System;//Ví dụ lỗi
class Test{public static void Main(){int s = 0;for (int i=1; i<=10; i++){
s+=i;}Console.WriteLine(i); //Error statementConsole.WriteLine(s);
}}
Câu lệnh whileusing System;class Test{
public static void Main(){
int i = 1;int s = 0;while (i<=10){
s += i;i++;
}Console.WriteLine(s);
}}
Câu lệnh doclass Test{public static void Main(){int i = 1;int s = 0;do{
s += i;i++;
} while (i<=10);Console.WriteLine(s);
}}
Lệnh break có thể dùng trong các câu lệnh lặp
Câu lệnh Foreachusing System;class Test{public static void Main(){int[] a = new int[3];a[0] = 10; a[1] = 20; a[2] = 30; foreach (int b in a){
Console.WriteLine(b);}}
}
Kiểu mảng [1]• Khai báo:
- Mảng 1 chiềutype[] identifier
– Mảng nhiều chiềutype[,] identifier
– Mảng jagged:type[][] identifier
Mảng1 chiều [2]using System;public class Test{
public static void Main(){
string[] students = new string[3];students[0] = “Hung";students[1] = “Lan";students[2] = “Nga";for (int i=0; i<3; i++){
Console.WriteLine(students[i]);}
}}
Mảng jagged [3]using System;
public class Test{
public static void Main(){
int[][] a = new int[5][];for (int i=0; i<a.Length; i++){
a[i] = new int[i+1];for (int j=0; j<i+1; j++){
a[i][j] = j;}
}
Mảng jagged [4]for (int i=0;i<a.Length;i++){
for (int j=0;j<a[i].Length;j++){
Console.Write("{0}",a[i][j]);}Console.WriteLine();
}}
}
Kiểu mảng [5]• Có thể khởi tạo các giá trị cho mảng bằng
cách dùng {}. • Nếu không khởi tạo C# sẽ lấy giá trị ngầmđịnh, phụ thuộc váo kiểu dữ liệu của mảng– Số: 0– Bool: False– Ngày: 01/01/0001– Chuỗi: “”– …
Khởi tạo mảng 1 chiều [6]using System;
public class Test{public static void Main(){
int[] a = new int[5] {1,2,3,4,5};foreach (int i in a){
Console.WriteLine(i);}
Khởi tạo mảng 2 chiều [7]
int[,] b = new int[2,3] {{1,2,3},{4,5,6}};foreach (int i in b){
Console.WriteLine(i);}
Khởi tạo mảng jagged [8]
//jagged arrayint[][] c = new int[2][]
{new int[2] {0,1},new int[3] {2,3,4}};for (int i=0; i<c.Length; i++)
for (int j=0; j<c[i].Length; j++){
Console.WriteLine(c[i][j]);}
}}
ArrayList
• Là mảng động, mỗi phần tử là một object• Namespace: System.Collections• Khai báo:
ArrayList <tenmang> = new ArrayList();ArrayList <tenmang> = new ArrayList(Số phần
tử);
Các phương thức trên ArrayList• Add(object): Chèn thêm 1 phần tử vào cuối
mảng• Clear(): Xoá tất cả các phần tử• Contains(object): Tìm object trong mảng• IndexOf(object): Tìm chỉ số của object trong
mảng (-1)• RemoveAt(index): Xoá phần tử thứ index• Thuộc tính: count: cho biết số phần tử trong
mảng• …
Ví dụ ArrayListclass ThaoTacTrenArrayList
{class test{
public int t = 15; }static void Main(string[] args){
ArrayList a = new ArrayList();a.Add("main");a.Add('m');a.Add(5);a.Add(DateTime.Now);test t = new test(); a.Add(t); for(int i=0;i<a.Count;i++)
if (a[i] is test){ test tt =(test) a[i];
Console.WriteLine (tt.t); }else
Console.WriteLine(" {0} ", a[i].ToString());}
Thao tác trên File
• Namespace: System.IO;• Các đối tượng thao tác trên File: Stream,
StreamReader, StreamWriter, FileStream.• Thao tác trên file văn bản: StreamReader,
StreamWriter.• Mở file văn bản để đọc:StreamReader <tênbiến> = new StreamReader(“dd"[,Encoding]);
• Mở file văn bản để ghi:StreamWriter <tênbiến> = new StreamWriter (“dd“[, bool
append][,Encoding])
Các phương thức trên StreamReader
• Close(): đóng file• Peek(): Trả về ký tự tiếp theo, -1;:EOF• Read(): Đọc ký tự tiếp theo• ReadBlock(…): Đọc dãy các byte• ReadLine(): Đọc 1 dòng• ReadToEnd(): Đọc hết file• …
Các phương thức trên StreamWriter• Close(): đóng file• Write• WriteLine: ghi filestatic void Main(string[] args)
{StreamWriter f = new
StreamWriter("d:\\tt.txt",true,Encoding.Unicode);f.WriteLine("cộng");f.Write("abc");f.Close(); Console.ReadLine();
}
Ví dụ StreamReaderusing System;using System.IO;class Program
{ static void Main(string[] args){
StreamReader f = new StreamReader("d:\\data.txt");string ht;//while ((ht = f.ReadLine()) != null)while(f.Peek()>=0){
ht = f.ReadLine();Console.WriteLine(ht);
}// Console.WriteLine(f.ReadToEnd() );f.Close();
}}
Bài tập thực hành• Thực hành các bài 1,2,3,4,5 trong giáo trình. • Giải pt bằng Gaussian:
– Vào ma trận hệ số A, vector B– Giải thuật để chuyển ma trận về tam giác trên:for(i = 0; i < n-1; i++)/* Trừ hàng đầu tiên */for(j = i+1; j < n; j++){m = a[j][i]/a[i][i];for(k = i; k < n; k++)a[j][k] = a[j][k] – a[i][k]*m;b[j] = b[j] – b[i] * m;}- In ra nghiệm của hệ
Bài tập thực hành về ArrrayList• Nhập vào danh sách họ tên và đtb của 1 lớp, số lượng
sv không hạn chế, quá trình nhập dừng khi nhập họ tênrỗng:
0 1 2 3 4 5Ht1 đtb1 Ht2 dtb2 … …
• Hiển thị họ tên và Đtb của các sinh viên lên lớp
•Nhập vào 1 họ tên, tìm xem có sv nào có họ tên nàyhay không
•Tính Trung bình cộng của ĐTB
•Xoá các sinh viên có đtb ra khỏi mảng
Bài tập thực hành về File• Làm lại bài thực hành trên nhưng lấy dữ liệu từ
file vào mảng• Cú pháp của file chứa dữ liệu như sau:
Họ tên sv1 |đtb sv1Họ tên sv2|dtb sv2
….
Nội dung
• Lớp đối tượng– Hàm dựng– Hàm huỷ– Trường– Phương thức
Lớp đối tượngMứctruycập class <Tên lớp>: <lớp cha hoặc các giao diện>
{ - Hàm dựng (Constructors)– Hàm huỷ (Destructors)– Hằng (Constants)– Trường (Fields)– Phương thức (Methods)– Thuộc tính (Properties)– Chỉ mục (Indexers)– Sự kiện (Events)– Con trỏ hàm (Delegates)– Lớp con (Classes)– Giao diện (Interfaces)– Cấu trúc (Structs)
}
Mức truy cậpMức truy cập Mô tả
public Biến hoặc phương thức có thể được truy xuất từ bất cứnơi nào
internal Biến hoặc phương thức chỉ có thể truy xuất trong phạmvi cùng assembly
protected Biến hoặc phương thức chỉ có thể truy xuất từ bêntrong kiểu dữ liệu mà nó thuộc về, hoặc các kiểu dữliệu dẫn xuất
protected internal
Biến hoặc phương thức có thể được truy xuất trongphạm vi assembly hiện tại, hoặc từ các kiểu dữ liệudẫn xuất từ kiểu dữ liệu chứa nó
private Biến hoặc phương thức chỉ có thể được truy xuất từbên trong kiểu dữ liệu mà nó thuộc về
Ví dụpublic class Class_b{
private class Class_b1{ }public class Class_b2{ }
}
class Program{ static void Main(string[] args)
{ Class_b t2 = new Class_b();Class_b.Class_b1 t21 = new Class_b.Class_b1();Class_b.Class_b2 t22= new Class_b.Class_b2(); }
}
Hàm dựng (Constructors)
• Là một loại đặc biệt của phương thức trong một lớp• Được gọi khi một lớp được tạo.• Thường được sử dụng để khởi tạo các giá trị trong
một lớp.• Tên trùng với tên lớp• Không trả về giá trị• Nếu không tạo ra hàm dựng C# sẽ tạo ra hàm dựng
ngầm định• Một lớp có thể có nhiều hàm dựng nhưng khác
nhau về số lượng hoặc kiểu của tham số
Ví dụ về Constructors using System;public class Person{
string Ten,dc=“Khong co”;public Person(string Ten){
this.Ten = Ten;}public Person(string Ten,string dc)
{this.Ten = Ten;this.dc = dc;
}
public void SayName(){
Console.WriteLine(“Ht: {0} Dc {1}",Ten,dc);}
}
Ví dụ về Constructors class Program
{static void Main(string[] args){
Person p1 = new Person("Cu Do");p1.SayName();Person p2 = new Person("Nguyen Ha","Ngu Tay");
p2.SayName();}
}
Private Constructors• Được sử dụng khi một lớp chỉ có các thành viên tĩnh và lớp không cần phải tạo
ra.public class MathConstant{private MathConstant(){} public static double Pi=3.14;
}
public class Test{public static void Main(){
//MathConstant m = new MathConstant(); Console.WriteLine(MathConstant.Pi);
}}
Static Constructors
• Được gọi tự động (chỉ 1 lần) trước khi thựcthể đầu tiên của đối tượng được tạo hoặccác thành viên tĩnh được tham chiếu.
• Không có tham số
public class Bus
{
static Bus() // Static constructor:
{ System.Console.WriteLine("Ham tinh duoc goi"); }
public static void Drive()
{ System.Console.WriteLine("Phuong thuc Drive duoc goi"); }
}
class TestBus
{ static void Main()
{ Bus.Drive();
Bus b = new Bus();
Bus c= new Bus(); }
}
Destructor• Destructors trong C# gọi là bộ thu gom rác
Garbage Collectors.• Bộ thu gom rác sẽ giải phóng bộ nhớ khiđối tượng không còn yêu cầu hoặc thamchiếu.
• Destructors khai báo như sau:~<tên hàm huỷ>()//giống tên lớp{
//các cài đặt của người lập trình}
Các trường (Fields)
• Lưu trữ giá trị• Cú pháp: <Mứctruycập> <Kiểu> <tênfields>• Mức truy cập: public, private, protected,
internal, protected internal • Kiểu:
– Kiểu giá trị được định nghĩa sẳn (int,char …)– Kiểu tham chiếu: lớp, struct, mảng, chuỗi,….
Ví dụnamespace Vidu{class Class_Lop{ }class SinhVien{ public string hoten;
private bool GioiTinh;protected DateTime NgaySinh;internal float[] DsDiem = new float[100];Class_Lop Lop= new Class_Lop();
}
class Program{static void Main(string[] args){
SinhVien sv =new SinhVien();sv.hoten = "Nguyen Nam";//sv.GioiTinh = false; //sv.NgaySinh =
DateTime.Parse("12/10/79");sv.DsDiem[0] = 5;
}}}
Trường tĩnh [1]
• Được khai báo trong 1 lớp
• Khi sử dụng không cần phải tạo ra lớp chứatrường tĩnh
• Khi khai báo chỉ cần dùng static trước tênbiến
• Truy xuất: <tênlớp>.tên trường tĩnh
Ví dụ trường tĩnhusing System;public class List{
public static int Dem = 0;public List()//Hàm dựng: được gọi khi tạo lớp{
Dem ++;}
}class Test{
public static void Main(){
Console.WriteLine(List.Dem );List n1 = new List();Console.WriteLine(List.Dem);List n2 = new List();Console.WriteLine(List.Dem);
}}
Trường chỉ đọc• Sử dụng readonly khi khai báo• Chỉ có thể gán giá trị khi khai báo hoặc trong hàm dựngclass test
{public readonly int a = 10;public readonly int b; public test(){ b = 12; }
}class TestBus{ static void Main()
{test t = new test();//t.a++; Console.WriteLine("a= {0}b= {1}",t.a,t.b);
}}
Constants
• Khai báo hàm dùng bổ từ const.
• Không thể thay đổi giá trị của hằng.
• Hằng sử dụng như trường tĩnh.
Ví dụ về Constantsusing System;
public class Gender{
public const int male = 1;public const int female = 2;
}
class Test{
public static void Main(){
Console.WriteLine("male = {0}",Gender.male);Console.WriteLine("female = {1}",Gender.female);
}}
Phương thức(method)
• Là tập hợp các câu lệnh• Được khai báo trong lớp hoặc cấu trúc,
phải chỉ rõ mức truy cập, tên, kiểu trảvề,danh sách các tham số. Nếu không cótham số phải có cặp dấu ngoặc
• Phương thức không trả về giá trị có kiểutrả về là void
• Dùng return để trả về giá trị của phươngthức
Ví dụ về methodsusing System;public class Person{
string name;
public Person(string name){
this.name = name;}public void SayName(){
Console.WriteLine("My name is {0}",name);}}
Tham chiếu ref and out [1]using System;public class Point{
int x;int y;public Point(int x,int y){
this.x = x;this.y = y;
}public void GetPoint(int x,int y){
x = this.x;y = this.y;
}}
Tham chiếu ref and out [2]class Test{
public static void Main(){
int x = 0; //int x; --> Errorint y = 0; //int y; --> ErrorPoint p = new Point(100,200);p.GetPoint(x,y);Console.WriteLine("({0},{1})",x,y);
}}
Output:(0,0)
Tham chiếu ref and out [3]using System;public class Point{
int x;int y;public Point(int x,int y){
this.x = x;this.y = y;
}public void GetPoint(ref int x,ref int y){
x = this.x;y = this.y;
}}
Tham chiếu ref and out [4]class Test{
public static void Main(){
int x = 0; // int x; --> Errorint y = 0; // int y; --> ErrorPoint p = new Point(100,200);p.GetPoint(ref x,ref y);Console.WriteLine("({0},{1})",x,y);
}} Output:
(100,200)- phải khởi tạo giá trị cho các tham số-Khi xây dựng và gọi phương thức phải dùng ref
Tham chiếu ref and out [5]using System;public class Point{
int x;int y;public Point(int x,int y){
this.x = x;this.y = y;
}public void GetPoint(out int x,out int y){
x = this.x;y = this.y;
}}
Tham chiếu ref and out [6]class Test{
public static void Main(){
int x;int y;Point p = new Point(100,200);p.GetPoint(out x,out y);Console.WriteLine("({0},{1})",x,y);
}}
Output:(100,200)
•Không cần khởi tạo giá trị cho các tham số•Khi xây dựng và gọi phương thức phải dùng out
Danh sách các tham số có chiều dài thay đổi [1]
• C# cho phép khai báo 1 tham số nhưng khigọi phương thức thì số lượng tham số có thểthay đổi
• Ví dụ như WriteLine(…)
• Sử dụng từ khoá params để khai báo thamsố có chiều dài thay đổi.
Variable-Length Parameter Lists [2]using System; public class MyClass{
public int Sum(params int[] args){
int s = 0; foreach (int i in args){
s+=i;}return(s);
}public void Write(params object[] args){
for (int index=0;index<args.GetLength(0);index++){
Console.WriteLine(args[index].ToString());}
}}
Variable-Length Parameter Lists [3]class Test{public static void Main(){
MyClass a = new MyClass();Console.WriteLine(a.Sum(1,2));Console.WriteLine(a.Sum(1,2,3));a.Write("John Smith",100);
}}
Output: 36John Smith100
• Xây dựng lớp Sinhvien bao gồm: ht,dc, mảngchứa điểm thi và các hàm sau.– Xây dựng hàm dựng:
• public Sinhvien(string ht, string dc, int somon)– Xây dựng hàm:
• public void Nhapdiem() để nhập vào danh sách điểm của 1 sv• public double Dtb(): Tính ĐTB của 1 sv• public void XuatSv(): Xuất các thông tin của 1 sv
• Xây dựng lớp Lop để:– Nhập vào danh sách các SV (Dùng ArrayList)– Xuất ra thông tin các SV– In ra họ tên các sinh viên lên lớp– Xây dựng hàm để tìm ĐTB cao nhất và thấp nhất (Dùng
ref hoặc out)
Bài tập
Nội dung
• Giới thiệu• Hàm nạp chồng (Overloading)• Hàm ghi đè (Overriding)• Hàm ảo (Virtual Functions)• Lớp trừu tượng (Abstract Classes)• Lớp Sealed• Giao diện
Giới thiệu
- C# chỉ hỗ trợ đơn kếthừa, tức là một lớp chỉcó thể kế thừa nhiềunhất là từ một lớp cha- Lớp cơ sở nhất trongC# là lớp System.Objectclass LopCon : LopCha{ Cai dat lop con}
Ví dụ về kế thừa [1]using System;
public class Person{
protected string name; //protected Fieldpublic Person(string name) //Function as a Constructor{
this.name = name;}public void SayName() //Member function{
Console.WriteLine("Person name is {0}",name);}
}
Ví dụ về kế thừa [2]public class Employee:Person{
public Employee(string name):base(name){}}
class Test{
public static void Main(){
Person p1 = new Person("Harry Potter");p1.SayName();Employee p2 = new Employee("Bill Gate");p2.SayName();
}}
Ví dụ về kế thừa [3]• Person là lớp cơ sở (lớp cha).• Employee là lớp dẫn xuất (lớp con) từ lớp
Person, vì thế:– Nó kế thừa tất cả các dữ liệu và hàm thành
viên của lớp cha (trừ private)– Constructors không tự động kế thừa lên lớp
cha, do đó người sử dụng phải chỉ rõ:public Employee(string name):base(name){…}
Ví dụ về kế thừa [3]public class Employee:Person{double salary;
public Employee(string name,double salary):base(name){ this.salary = salary;
}}
...class Test{
public static void Main(){
Person p1 = new Person("Harry Potter");p1.SayName();Employee p2 = new Employee("Bill Gate“,3000);p2.SayName();
}}
Hàm nạp chồng (Overloading )
• Hàm nạp chồng là hàm trùng tên trong một lớpnhưng khác nhau về số lượng và kiểu của cáctham số
• Không nạp chồng dựa vào tên tham số và kiểu trảvề của các tham số.
Ví dụ [2]class TinhDt
{ public double Dt(double r)
{ return ((double)Math.PI*r*r);
}public double Dt(double a,double b){ return a*b; }
public double Dt(double a,double b,double c){ double p=(a+b+c)/2;
return Math.Sqrt(p*(p-a)*(p-b)*(p-c)); }
Ví dụ [3]public static void Main() {
TinhDt DienTich=new TinhDt(); Console.WriteLine("Dt HT {0}",DienTich.Dt(3));Console.WriteLine("Dt HCN {0}",DienTich.Dt(3,4)); Console.WriteLine("Dt HTG{0}",DienTich.Dt(3,4,5));
}}
Ví dụ lỗi[4]using System; class ErrorClass{
public int Increase(int x){
return(x+1);} public string Increase(int x){
return((x+1).ToString());}
}class Test{
public static void Main(){
ErrorClass err = new ErrorClass();Console.WriteLine(err.Increase(10));
}}
Hàm ghi đè (Overriding) [1]Hàm ghi đè là hàm giống nhau trên cả lớpcha và lớp con.Để ghi đè một hàm đã có trên lớp cha:
Khai báo một hàm mới trong lớp con với têngiống với lớp cha.Sử dụng từ new.
Example:public new void SayName(){
Console.WriteLine("Employee name is {0}",name);}
Hàm ghi đè [2]using System;public class Person{
protected string name;public Person(string name){
this.name = name;}public void SayName(){
Console.WriteLine("Person name is {0}",name);}
}
Hàm ghi đè [3]public class Employee:Person{
public Employee(string name):base(name){}public new void SayName(){
Console.WriteLine("Employee name is {0}",name);}
}class Test{
public static void Main(){//Person p = new Person(“ab");// p.SayName();--> Person name is abEmployee e = new Employee("Bill Gate");e.SayName();//Person e1 = new Employee("Bill Gate");//e1.SayName(); --> Person name is Bill Gate
}}
Hàm ghi đè [4]Output:
Employee name is Bill Gate
Hàm ghi đè [5]...class Test{
public static void Main(){
Person p1 = new Person("Harry Potter");Person p2 = new Employee("Bill Gate");p1.SayName();p2.SayName();
}}
Hàm ghi đè [6]
Output:
Person name is Harry PotterPerson name is Bill Gate
Hàm ảo (Virtual Functions) [1]
• Cách xây dựng hàm ảo giống như hàm ghiđè nhưng sử dụng từ khoá virtual tronghàm của lớp cha và override trong hàm củalớp con
• Khi gọi hàm, trình biên dịch sẽ nhìn vào lớpthực sự được tạo ra và gọi hàm tương ứngtrên lớp này
Hàm ảo [2]using System;public class Person{
protected string name;public Person(string name){
this.name = name;}public virtual void SayName(){
Console.WriteLine("Person name is {0}",name);}
}
Hàm ảo [3]public class Employee:Person{
public Employee(string name):base(name){}public override void SayName(){
Console.WriteLine("Employee name is {0}",name);}
}
public class Student:Person{
public Student(string name):base(name){}public override void SayName(){
Console.WriteLine("Student name is {0}",name);}
}
Hàm ảo [4]
class Test{
public static void Main(){
Person p1 = new Person("Harry Potter");Person p2 = new Employee("Bill Gate");Person p3 = new Student("John Smith");p1.SayName();p2.SayName();p3.SayName();
}}
Hàm ảo [5]
Output:
Person name is Harry PotterEmployee name is Bill GateStudent name is John Smith
Lớp trừu tượng (Abstract) [1]
• Lớp trừu tượng là lớp xây dựng ra để lớpkhác kế thừa, các thành phần trong lớpkhông cần cài đặt.
• Tạo lớp trừu tượng bằng cách thêm từkhoá abstract khi khai báo
Lớp trừu tượng [2]
using System;
public abstract class MusicPlayer{public abstract void Play(); public void EndPlay(){
Console.WriteLine("Finished");}
}
Lớp trừu tượng [3]
public class Winamp:MusicPlayer{public override void Play(){
Console.WriteLine("Winamp is playing");}
}
public class MediaPlayer:MusicPlayer{public override void Play(){
Console.WriteLine("Media Player is playing");}
}
Lớp trừu tượng [4]public class Test{public static void Main(){
MusicPlayer m1 = new Winamp();m1.Play(); MusicPlayer m2 = new MediaPlayer();m2.Play();
}}
Output:Winamp is playingMedia Player is playing
Lớp Sealed
• Không cho lớp con kế thừa• Lớp Sealed được tạo bằng cách dùng từ
khoá sealed khi khai báo
Sealed Classes//Error sampleusing System;public sealed class MyClass{
public MyClass(){}}
public class MyNewClass:MyClass //Error definition{}
class Test{
public static void Main(){}
}
Giao diện (Interfaces)
• Concepts• A Simple Example • Working with Interfaces• The as Operator• Interfaces and Inheritance• Multiple Implementation• Interfaces based on interfaces
Giao diện (Interfaces)
• Giao diện giống như lớp trừu tượng• Chứa các phương thức trừu tượng nhưng
không cài đặt.• Một lớp kế thừa lên 1 giao diện phải cài đặt tất
cả các phương thức trên giao diện đó.• Một lớp chỉ kế thừa lên 1 lớp khác nhưng có thể
kế thừa trên nhiều giao diện.
Ví dụ [1]
using System;
interface Music
{
void PlayMusic(string filename);
void EndPlay();
}
Ví dụ [2]public class Winamp:Music{public Winamp(){ }
public void PlayMusic(string filename){
Console.WriteLine("Winamp is Playing {0}",filename);}
public void EndPlay(){
Console.WriteLine("End of play");}
}
A Simple Example [3]
class Test{
public static void Main(){
Winamp w = new Winamp();w.PlayMusic("Hello.mp3");w.EndPlay();
}}
CHƯƠNG III. (tt)
THUỘC TÍNH VÀ CHỈ MỤC
THUỘC TÍNH • Giới thiệu
• Các loại của thuộc tính
• Thuộc tính và trường
• Thuộc tính và phương thúc
• Thuộc tính tĩnh
Giới thiệu [1]• Thuộc tính trong 1 lớp được sử dụng để lấy
và thay đổi giá trị trong lớp.• Một thuộc tính thường có 2 khối lệnh:
– Get: trả về một giá trị– Set: Gán một giá trị mới– Từ khoá value được sử dụng để xác định giá trịđược gán trong khối set.
• Giống như hàm thuộc tính có thể dùng bổ từvirtual, override, abstract, static
Ví dụ [2]using System;
public class Person{
string name; // Fieldpublic string Name // Property{
get{
return (name);}set{
name = value;}
}}
Ví dụ [3]class Test{
public static void Main(){
Person p = new Person();p.Name = "John Smith";Console.WriteLine("Person name is {0}",p.Name);
}}
Output:Person name is John Smith
Các loại thuộc tính
• Read/Write: Thuộc tính có cả get và set.
• Read-Only: Thuộc tính chỉ có get.
• Write-Only: Thuộc tính chỉ có set.
Thuộc tính và trường
• Thuộc tính là trường cục bộ• Thuộc tính là sự mở rộng của trường• Không như trường, thuộc tính không được
cấp phát vùng nhớ.
Thuộc tính và phương thức
• Thuộc tính không có dấu ngoặc ()• Kiểu của thuộc tính không được là void
Ví dụ[1]public class SinhVien
{private string HoTen;private ArrayList Dsdiem=new ArrayList() ;public SinhVien(){ HoTen = "Nguyen van Nam";
Dsdiem.Add(3.0); Dsdiem.Add(4.0);Dsdiem.Add(9.0);
}public String GetHoten{ get
{return HoTen;
}}
Ví dụ [2]public double GetDTB
{ get{ double s=0;
for (int i = 0; i < Dsdiem.Count; i++)s += (double)Dsdiem[i];
return s / Dsdiem.Count; }
}}//class SinhVienclass test{ static void Main(string[] args)
{ SinhVien sv=new SinhVien();Console.WriteLine("Ho ten: {0}",sv.GetHoten);Console.WriteLine("DTB: {0}",sv.GetDTB); Console.ReadLine();
}}
Chỉ mục(Indexers)
• Giới thiệu
• Ví dụ
• Khai báo
• Chỉ mục và thuộc tính.
• Chỉ mục và mảng.
• Chỉ mục nhiều tham số
Giới thiệu• Chỉ mục có thể xây dựng trong 1 lớp
hoặc một cấu trúc giống như mảng• Xây dựng chỉ mục giống như thuộc tính
nhưng chỉ mục có tham số.
Ví dụ [1]using System;
public class TestIndexer{
string[] list;int count;
public TestIndexer(int count){
this.list = new string[count];this.count = count;
}
Ví dụ [2]public int Count //property{
get { return(count); }}
public string this[int index] //Indexer{
get{
return list[index];}set{
list[index] = value;}
}} //End of Class
Ví dụ [3]class Test{
public static void Main(){
TestIndexer indexer = new TestIndexer(4);indexer[0] = "Good Morning";indexer[1] = "Good Afternoon";indexer[2] = "Good Evening";indexer[3] = "Bye! See you again";for (int i=0;i<indexer.Count;i++){
Console.WriteLine(indexer[i]);}
}}
Ví dụ [4]
Output:
Good MorningGood AfternoonGood EveningBye! See you again
Khai báo chỉ mục
• Cú pháp:Mức truy cập <Kiểu trả về> this[tham số]{ Get {...}
Set {...}}
• Chú ý:– Chỉ mục phải có ít nhất một tham số– Các tham số nên được gán giá trị.
Chỉ mục và thuộc tính• Chỉ mục giống như thuộc tính nhưng:
Chỉ mục Thuộc tínhĐược xác định bởi từkhóa: this
Được xác định bởi tên
Có thể có nhiều tham số Không có tham số
Chỉ mục và mảng
• Chỉ mục không được cấp phát vùng nhớgiống như mảng
• Chỉ số của mảng phải là 1 số nguyên còn chỉmục thì bất kỳ.
• Chỉ mục có thể nạp chồng còn mảng thìkhông
Chỉ mục nhiều tham số[1]using System;
public class MultiParaIndexer{
private int[,] matrix = new int[2,3];
public MultiParaIndexer(){
for (int i=0; i<2; i++){
for (int j=0; j<3; matrix[i,j]=i+j,j++);}
}
Chỉ mục nhiều tham số[2]
public int this [int row,int col]{
get{
return (matrix[row,col]);}set{
matrix[row,col] = value;}
}} //End of class
Chỉ mục nhiều tham số [3]public class Test{
public static void Main(){
MultiParaIndexer m = new MultiParaIndexer();for (int i=0; i<2; i++){
for (int j=0; j<3; j++){
Console.Write("\t{0}",m[i,j]);}Console.WriteLine();
}}
}
Con trỏ hàm(Delegates)
• Con trỏ hàm là gì?
• Khai báo con trỏ hàm
• Thao tác trên con trỏ hàm
• Ví dụ
Con trỏ hàm là gì?
• Là 1 con trỏ trỏ đến 1 phương thức• Kết nối 1 tên với một phương thức đã xây
dựng• Sử dụng con trỏ hàm có thể gọi đến hàm
Khái báo con trỏ hàmCú pháp:
<Mức truy cập> <delegate> <Kiểu> <Têncontrỏhàm(cáctham số)>
– Kiểu: Giống với kiểu của hàm mà con trỏ trỏđến
– Các tham số: bằng nhau về số lượng và kiểu so với hàm mà con trỏ trỏ đến.
– Không xây dựng con trỏ hàm
Thao tác trên con trỏ hàm• Có thể khai báo bên ngoài hoặc bên trong 1 lớp• Một con trỏ hàm có thể trỏ đến nhiều hàm cùng kiểu
trả về, cùng số lượng và kiểu của tham số.• Giống như lớp, ta dùng new để tạo ra con trỏ hàm và
truyền tên hàm cần trỏ đến cho con trỏ hàm (khôngtruyền tên tham số cho hàm)
<têncontrỏhàm> <biến>=<têncontrỏhàm>(tênhàm);
• Gọi hàm bằng con trỏ hàm:biến(các tham số thực)
Ví dụ [1]using System;
public delegate int MathOperate(int a,int b);public class Math{
public int Add(int a,int b){
return (a+b);}
public int Sub(int a,int b){
return (a-b);}
} //End of class Math
Ví dụ[2]class Test{
public static void Main(){
MathOperate mathOp;Math m = new Math();mathOp = new MathOperate(m.Add);Console.WriteLine(mathOp(3,2));mathOp = new MathOperate(m.Sub);Console.WriteLine(mathOp(3,2));
}} //End of class Test
Sự kiện (Event)• Sự kiện là gì?
• Sự kiện và con trỏ hàm .
• Khai báo sự kiện.
• Ví dụ
Sự kiện là gì?
• Sự kiện trong C# cho phép một đối tượngthông báo đến đối tượng khác về sự kiệnhoặc 1 sự thay đổi đã xảy ra.
• Đối tượng thông báo đến đối tượng khác vềsự kiện đã xảy ra gọi là đối tượng phát sinhsự kiện (Publisher).
• Đối tượng nhận được sự kiện gọi là “đốitượng đáp trả“ (Subscriber).
• Khi Publisher phát ra 1 sự kiện tất cả cácSubscriber đều được thông báo
Sự kiện và con trỏ hàm (deleagte )• Sự kiện trong C# được cài đặt bằng delegate. • Lớp publish khai báo một deleagte mà các lớp
subscribe phải cài đặt. • Khi một sự kiện phát sinh, phương thức của lớp
subscribe sẽ được gọi thông qua delegate.• Cách quản lý các sự kiện được gọi là event handler
(trình giải quyết sự kiện). Ta có thể khai báo mộtevent handler như là ta đã làm với delegate.
• Để thuận tiện, event handler trong .NET Framework trả về kiểu void và nhận vào 2 tham số. Tham số thứnhất cho biết nguồn của sự kiện; có nghĩa là đốitượng publish. Tham số thứ hai là một đối tượngthừa kế từ lớp EventArgs.
Khai báo sự kiện[Mức truy cập] event <Kiểu> <tên sự kiện>
Kiểu: là 1 con trỏ hàmKhai báo sự kiện ở PublisherVí dụ://Khai báo con trỏ hàm cho sự kiện
public delegate void DeleEvent(object sender,EventArgs e);
// Khai báo sự kiện Clickpublic event DeleEvent Click;
//Click giống như 1 biến của con trỏ hàm
Ví dụ [1]using System;
public class TestEvents
{
//delegate mà subscribers phải cài đặtpublic delegate void DeleEvent(object sender,
EventArgs e);
Ví dụ [2]public class CommandButton //Publisher{
// Khai báo sự kiệnpublic event DeleEvent Click;
public void ButtonClick(){
if (Click !=null)//nếu có subscribe {
EventArgs e = new EventArgs();Click(this,e);//Thông báo đến subscribe
}}
} // kết thúc lớp CommandButton
Ví dụ [3]public class Form{CommandButton cmdOK = new CommandButton();
public Form(){
cmdOK.Click += new DeleEvent(cmdOK_Click);cmdOK.Click += new DeleEvent(cmdOK_Click1);cmdOK.ButtonClick();
}
private void cmdOK_Click(object sender,EventArgs e){
Console.WriteLine("Button is clicked");}private void cmdOK_Click1(object sender,EventArgs e){
Console.WriteLine("Button is clicked");}
Toán tử: +=: Cho phép thêm vào 1 sự kiện nhưng không ảnhhưởng đến các sự kiện trước đó
Ví dụ [4]public void DetachEvent(){
cmdOK.Click -= new DeleEvent(cmdOK_Click);}
} // Kết thúc lớp Form
public class Test{
public static void Main(){
Form f = new Form();f.DetachEvent();
}} //Kết thúc lớp Test
} // Kế hú lớ T E
Bài thực hành• Yêu cầu:
- Tạo lớp DongHo, cứ mỗi giây hãy thôngbáo cho lớp HienThiDongHo biết để hiểnthị và lưu vào file giờ, phút, giây hiện tại va
- Khai báo các Namespace• using System;• using System.Threading;• using System.IO;
Tạo lớp ThongTinThoiGianLớp này kế thừa lớp EventArgs, chứa các thông tin để thông báo cho lớp HienThiThoiGianpublic class ThongTinThoiGian : EventArgs{
public readonly int hour;public readonly int minute;public readonly int second;public ThongTinThoiGian(int hour, int minute, int
second){
this.hour = hour;this.minute = minute;this.second = second;
}}
Tạo lớp DongHo (Publisher)public class DongHo{
public delegate void DeleHienThiThoiGian(object DongHo,ThongTinThoiGian Tg);//Con trỏ hàm
public event DeleHienThiThoiGian EvenThaydoiThoiGian;public void Run( )//Hàm phát snh sự kiện sau mỗi giây{
for (; ; ) //Lặp vô hạn{
Thread.Sleep(1000);//Chương trình dừng lại 1 giâySystem.DateTime dt = System.DateTime.Now;
// tạo đối tượng ThongTinThoiGian để truyền cho subscriberThongTinThoiGian Tg = new ThongTinThoiGian(
dt.Hour,dt.Minute,dt.Second);if ( EvenThaydoiThoiGian != null){
EvenThaydoiThoiGian(this, Tg);}
}}}
Tạo lớp HienThiThoiGian(public class HienThiThoiGian
{
public void Subscribe(DongHo dh)
{dh.EvenThaydoiThoiGian += new DongHo.DeleHienThiThoiGian(HienThi);
dh.EvenThaydoiThoiGian += new DongHo.DeleHienThiThoiGian(Luufile);
}
// phương thức cài đặt hàm delegatedpublic void HienThi( object dh,ThongTinThoiGian tg)
{
Console.Clear();
Console.Write("Bay gio la: {0}:{1}:{2}",
tg.hour.ToString( ),tg.minute.ToString( ),
tg.second.ToString( ));
}
Tạo lớp DongHo (Publisher)public void Luufile(object dh, ThongTinThoiGian tg)
{StreamWriter f = new StreamWriter(@"d:\tg.txt",true); string st = tg.hour.ToString() + ":" +tg.minute.ToString() + ":" + tg.second.ToString();
f.WriteLine(st); f.Close(); }
}public class Test{
public static void Main( ){DongHo dh = new DongHo();HienThiThoiGian tg = new HienThiThoiGian();tg.Subscribe(dh);dh.Run( );}
}
Xử lý ngoại lệ (Exception Handling)
• Dùng Trying và Catching• Kiến trúc của ngoại lệ• Truyền ngoại lệ• Sử dụng Finally
Ngoại lệ [1]
• Ngoại lệ được phát sinh khi chạy chươngtrình bị lỗi.
• Ngoại lệ cung cấp đầy đủ thông tin về lỗi xẩyra.
Kiến trúc phân tầng của ngoại lệ[2]
Exception
IOException
System Exception
OutOfMemoryException
OverflowException
CoreException
NullReferencException
Trying và Catching [1]
• Khối try chứa đoạn chương trình• Khối catch xử lý lỗi, khi có lỗi xảy ra.• Dùng 1 khối try nhưng có thể nhiều khối
catch• Không có try và catch chương trình dừng lại
(treo) và đưa ra lỗi.
Trying và Catching [2]using System;class Test{
public static void Main(){
int Zero = 0;try{
int j = 22 / Zero;}catch (Exception e){
Console.WriteLine(e.Message);}Console.WriteLine(“Các lệnh sau catch");
}}
Trying và Catching [3]int Zero = 0;try{
int j = 22 / Zero;}catch (DivideByZeroException e){
Console.WriteLine(“Loi 1:"+e.Message);}catch (Exception e){
Console.WriteLine(“Loi 2:"+e.Message);}Console.WriteLine(“Sau catch");
Trying và Catching [4]
Kết quả hiển thị:
Loi 1:Attempted to divide by zero.Sau catch
Truyền ngoại lệ [1]• Trong 1 số trường hợp chúng ta không xử lý
khi lỗi xảy ra, chúng ta cần truyền các lỗi nàyđến hàm gọi nó
• Có 3 cách để làm điều này:– Không xử lý lỗi– Truyền lỗi đến hàm được gọi– Truyền lỗi cụ thể đến hàm được gọi.
Truyền ngoại lệ[2]• Không xử lý lỗiusing System;public class SumClass{
int sum = 0;int count = 0;int average = 0;public void CalculateAverage(){ try
{average = sum/count;
}catch{}
}}
Truyền ngoại lệ[3]
class Test{public static void Main(){
SumClass s = new SumClass();s.CalculateAverage();
}}
Truyền ngoại lệ [4]• Bắt lỗi, sau đó truyền lỗi này đến hàm được gọiusing System;public class SumClass{ int sum = 0;
int count = 0;int average = 0;public void CalculateAverage(){ try
{average = sum/count;
}catch (DivideByZeroException e){
throw e;}
}}
Truyền ngoại lệ[5]class Test{
public static void Main(){
SumClass s = new SumClass();try{
s.CalculateAverage();}catch (Exception e){
Console.WriteLine(e.Message);}
}}
Truyền ngoại lệ[6]• Xử lý lỗi, sau đó truyền các lỗi đã xử lý đến hàm được
gọi.using System;public class SumClass{ int sum = 0;
int count = 0;int average = 0;public void CalculateAverage(){ try
{average = sum/count;
}catch (DivideByZeroException e){
throw (new DivideByZeroException(“Loi roi:"));}
}}
Truyền ngoại lệ[7]class Test{
public static void Main(){
SumClass s = new SumClass();try{
s.CalculateAverage();}catch (Exception e){
Console.WriteLine(e.Message);//Loi roi}
}}
Sử dụng Finally• Khối Finally chứa đoạn chương trình luôn luôn
thực hiện cho dù có phát sinh lỗi hay không?try{
//đoạn chương trình}catch{
//Xử lý lỗi}finally{
//đoạn chương trình luôn thực hiện}
Chương 1
GiGiớớii thithiệệuu Visual Studio.NETVisual Studio.NET
Chia sẻ IDE [1]
• VS.NET cung cấp IDE cho tất cả các ngônngữ của nó.
• Giúp cho người lập trình xây dựng 1 chương trình nhanh chóng và hiệu quả
• Khi VS.NET khởi động, thì trang Start Page được hiển thị.
Chia sẻ IDE [2]
Chia sẻ IDE [3]
Solution Explorer
•Solution Explorer liệtkê các projects và cácfile đang hoạt động•Để hiển thị Solution Explorer, nhấn Ctrl+Alt+L(View|Solution Explorer )
ToolBox
• Bao gồm các điềukhiển trên Web form vàWin form, ActiveX controls, XML Web services, các thànhphần HTML và các đốitượng.
• Để hiển thị Toolbox, nhấn Ctrl+Alt+X(View|Toolbox).
Server Explorer
• Server Explorer Lậptrình trên CSDL màkhông cần sử dụngVS.NET IDE.
• Để hiển thị Server Explorer, nhấnCtrl+Alt+S(View|Server Explorer)
Class View
• Class view hiển thị cáclớp, phương thức vàthuộc tính đã xâydựng.
• Để hiển thị Class View, nhấn Ctrl+Alt+C(View|Class View).
Properties Window
• Properties window để thiết lập cácthuộc tính các điềukhiển, lớp vàprojects.
• Để hiển thịProperties Window, nhấn F4.
Kỹ thuật IntelliSense• Thông báo cho người lập trình cú phápđúng và cho phép hoàn thành tự động 1 câu lệnh
WinForms [1]• WinForms là một lớp thư viện giúp cho
người lập trình có thể tạo ra các ứng dụngdesktop, ứng dụng client/server,…
• File|New|Project
WinForms [2]
WebForms[1]• WebForms là lớp thư viện để tạo form choứng dụng Web.
• File|New|Web site
WebForms[2]
Chương 2
NNộộii dungdung
Các lớp thư viện
Các thuộc tính và phương thức
Xử lý sự kiện
Các thành phần giao diện cơ bản
Application
User Interface
Program
Các lớp thư viện
.Net Framework dựa trên cách tiếp cận hướngđối tượng
Các lớp thư viện được chia vào các namspace
Ví dụSystem.Windows.forms
Các thuộc tính và phương thức
Frog
Height :12 cmWeight :100gmName : Jumpie
Jump
HeightWeightName
Thể hiện của lớp
Sự kiện và đáp ứng sự kiện[1]
Ta có thể tương tác giữa các đối tượng khác nhaubên trong 1ứng dụng, giữa 1 đối tượng và đối tượngbên ngoài thông qua sự kiện và đáp ứng sự kiện.
Sự kiện và đáp ứng sự kiện[2]
• Để hiển thị tất các các sự kiện của điều khiển kíchvào button Event trên Properties window.
Ví dụ xử lý sự kiện
private void button1_Click(object sender, System.EventArgs e){
}
Người dùngchọn nút
Sự kiện
Đáp ứng sự kiện
MessageBox.Show("Goodluck to you!");
Ứng dụng Windows
Thành phần cơ bản là Form
Hiển thị thông tin của người dùng
Nhận thông tin từ người dùng
Một ứng dụng có thể có nhiều Form
WinForms
Form được trình bày như 1 lớp trong
WinForms.
Bất kỳ khi nào ứng dụng đuợc tạo thì 1 form
sẽ được thêm vào
WinForms sẽ tạo ra 1 thể hiện của lớp Form
Các điều khiển (Controls)
Trên Form có thể có nhiều điều khiển để hiển thị và
nhập dữ liệu của người dùng.
Có thể thiết kế các điều khiển ở Toolbox
Các thuộc tính chung cho các Controls
Thuộc tínhBackColorCanFocusEnabled
ForeColorNameText
Visible
Controls
Label
TextBox
Button
ListBox
ComboBox
CheckedListBox
PROPERTIESImage
TabStop ShowUpdate
Paint
Hide
Events
Methods
Label
PROPERTIES
Events
MethodsAcceptReturn
MaxLengthMultiline
PasswordcharReadOnly
ScrollBars
AppendTextClear
CopyCutPaste
MultilineChanged
TextChanged
TextBox
PROPERTIES
Events
Methods
DialogResult
TextAlign
PerformClick
ClickClick
Button
PROPERTIES
ItemsMultiColumn
SelectedIndexSelectedItem
SelectedItems
SelectedValue
Sorted
Text
ListBox [1]
EventsMethods
ClearSelected
FindStringGetSelected
SetSelected
SelectedIndexChanged
SelectedValueChanged
ListBox [2]
PROPERTIES
Events
Methods
CheckedIndices
CheckedItemsThreeDCheckBoxes GetItemChecked
GetItemCheckState
SetItemChecked
SetItemCheckState
ItemCheck
CheckedListBox
PROPERTIES
Events
Methods
DropDownStyleFocusedMaxDropDownItems
Select
SelectAll
DropDown
ComboBox
Từ khoá thisĐại diện cho Form hiện thờiĐể truy xuất đến tất cả các thuộc tính, phương
thức, trường và sự kiện của Form hiện thời.
Ví dụ
this.[controlname].[propertyname]
Tạo WinForm Applications
• File -> New -> Project
Thêm 1 Item vào project
• Project -> Add New Item
Label: Properties: Image
Nạp ảnh vào Label:Properties: Image= Image.FromFile(“fileName”);
Properties: Image= Image.FromFile(“fileName”);Event: Click, DoubleClick: Thay đổi ảnh
Giả sử trong Bin có 7 ảnhcó tên 1.jpg, 2.jpg, …
int i =1 ;private void label1_Click(object sender, EventArgs e)
{label1.Image = Image.FromFile(i.ToString()+".jpg");i++;if (i == 7) i = 1;
}
checkedListBox: Properties: Items,...Method: GetItemChecked, ...
checkedListBox1 list1
comboBox1
Khi nhấn enter trên textBox1
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{ if(e.KeyChar==13)
checkedListBox1.Items.Add(textBox1.Text);
}
Khi chọn trên 1 mục trên checkedListBox1
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{ listBox1.Items.Add(checkedListBox1.Items[e.Index]);
}
Khi chọn chọn trên butsend
private void butSend_Click(object sender, EventArgs e)
{
for (int i = 0; i < checkedListBox1.Items.Count; i++)
if (checkedListBox1.GetItemChecked(i) )
comboBox1.Items.Add(checkedListBox1.Items[i]);
comboBox1.Text = comboBox1.Items[0].ToString() ;
}
imageList, listView
• imageList:– Properties: Images,...
• listView– Properties:
• Columns• Items (Items.Add(...), Items[i].SubItems[i]• SmallItemList• View, GridLine, …
• DialogResult MessageBox (text, caption, MessageBoxButtons)
Hàm kiểm tra xem có Họ tên trùng nhau hay không?
bool Kiemtra(string ht){
for (int i = 0; i < listView1.Items.Count; i++)if (listView1.Items[i].Text.Equals(ht))
return false;return true;
}
Kích vào nút Nhậpprivate void butNhap_Click(object sender, EventArgs e)
{DialogResult kq=DialogResult.Yes;bool kt = Kiemtra(textHoten.Text);if(!kt)kq = MessageBox.Show("Đã có nv này, nhập thêm hay
không ?","Thông báo",MessageBoxButtons.YesNo) ;if(kq==DialogResult.Yes ||kt==true) {
string[] st = new string[3];st[0] = textHoten.Text;st[1] = textDiachi.Text;st[2] = textGioiTinh.Text;ListViewItem lv = new ListViewItem(st);listView1.Items.Add(lv);
}}
timer, progressBar
• timerProperties:
• Enable• Interval
Methods:• Tick
• progressBar– Properties:
• Maximum• Minimum• Value
statusStrip
DongHo TienTrinh DieuKhien
statusStrip
Lập trình trên timer1_Tick()
private void timer1_Tick(object sender, EventArgs e){ DateTime dh=DateTime.Now;
DongHo.Text = dh.ToLongTimeString() ;TienTrinh.Maximum = 60;TienTrinh.Minimum = 0; TienTrinh.Value = dh.Second;
}
colorDialog
Properties: Color; method: ShowDialogprivate void button1_Click(object sender, EventArgs e)
{colorDialog1.ShowDialog();textBox1.ForeColor = colorDialog1.Color;
}
colorDialog
Properties: Color; method: ShowDialogprivate void button1_Click(object sender, EventArgs e)
{colorDialog1.ShowDialog();textBox1.ForeColor = colorDialog1.Color;
}
fontDialog,saveFileDialog, openFileDialog
• Method:– ShowDialog();
• Properties:– Font– FileName
OpenFileprivate void butOpen_Click(object sender, EventArgs
e){try{
openFileDialog1.ShowDialog();StreamReader f=new
StreamReader(openFileDialog1.FileName);textBox1.Text = f.ReadToEnd();}catch(Exception
e1){MessageBox.Show(e1.Message); } }
SaveFileprivate void butSave_Click(object sender, EventArgs e){
try {saveFileDialog1.ShowDialog();StreamWriter f = new
StreamWriter(saveFileDialog1.FileName);f.WriteLine(textBox1.Text);f.Close();
}catch (Exception e1) { MessageBox.Show(e1.Message); }
}
Font
private void butFont_Click(object sender, EventArgs e){
fontDialog1.ShowDialog();textBox1.Font = fontDialog1.Font;
}
menuStrip
Mở Form1: Form1 f = new Form1();f.Show();
toolStrip
Chương I
Nội dung
• Giới thiệu• Kiến trúc của ADO.NET• Connection• Command• DataReader
Giới thiệu
Lưu vào
Database
Client
ADO.netCông nghệ truy xuất dữ liệu
Ứng dụng Client-Server
Client Server
Cung cấp dữ liệu đếnclient
Clie
nt S
oftw
are
Dat
abas
e
Các thành phần truy xuất dữ liệu
Database
User
Database
Yêu cầu dữ liệu
Gởi dữ liệu
Các thành phần truy xuất dữ liệu(ODBC, OLE DB, ADO, ADO.net)
ADO (ActiveX Data Object)(1)
• Sử dụng ADO để:• Kết nối đến CSDL• Dùng câu lệnh để truy cập đến CSDL
và cho thực hiện• Lưu trữ dữ liệu được lấy về.• Cập nhật lại dữ liệu khi dữ liệu bị thay đổi
ADO là tập hợp các đối tượng được sử dụng để truyxuất đến CSDL
KIẾN TRÚC ADO.NET
ADO.NET gồm 2 thành phần cơ bản:- DataSet:
- Được xem như là CSDL thu nhỏ tại client- Chứa các đối tượng table, view, constaint,
ralationship giữa các table, …- Ngắt kết nối với cơ sở dữ liệu
- .NET data provider: Cho phép kết nối đếnCSDL và thực hiện câu lệnh SQL
ADO.NET
Các thành phần cơ bản của ADO.net
Data Providers
Database
CONECTION
DataReader
Command
DataAdapter Winform
Webform
Other
DataSet
.Net Data Providers
.NET DATA PROVIDERS
Thiết lập kết nối đến CSDL
Xử lý dữ liệu trong CSDL
Connection (1)
• Kết nối đến CSDL, xác định chuỗi kết nối:1. Tên hệ QTCSDL2. Tên máy chủ3. Tên CSDL4. ID, Password
• Đối với Access: (2), (4) không cần• Connection có 2 đối tượng
– SqlConnection: Sử dụng cho SQL Server• OleDbConnection: Sử dụng cho HQTCSDL bất kỳ
Connection (2)SQL .NET Data Provider OLE DB .NET Data ProviderSystem.Data System.DataSystem.Data. SqlClient System.Data.OleDb"
SqlConnection cn = new SqlConnection("server=SQLDB; uid=sa; pwd=password; database=pubs");
OleDbConnection cn=new OleDbConnection (“ Provider = SQLOLEDB; Data Source=SQLDB; Initial Catalog=pubs; User Id=sa; pwd=password");
OleDbConnection cn = new OleDbConnection("provider=microsoft.jet.oledb.4.0; data source=d:\\qlsv.mdb");
Connection (3)
Close
OpenBeginTransaction
ConnectionString
State
DataSource
Ví dụ [1]Tạo lớp KetNoi để kết nối đến Access và SQL Server
class KetNoi{
public static OleDbConnection cn=new OleDbConnection();
public static void MoKetNoi(string FileName)//Access{
if (cn.State ==ConnectionState.Open) cn.Close(); String ChuoiKetNoi =@"provider=microsoft.jet.oledb.4.0;data source="+ FileName;cn.ConnectionString =ChuoiKetNoi;cn.Open();
}
Ví dụ [2]Tạo lớp KetNoi để kết nối đến Access và SQL Server
public static void MoKetNoi(string ServerName,stringCSDL,string ID, string pwd)//SQL Server
{
if (cn.State ==ConnectionState.Open) cn.Close();
String ChuoiKetNoi = string.Format("Provider = SQLOLEDB;Data
Source={0}; Initial Catalog={1}; User Id={2}; pwd={3}",
ServerName,CSDL,ID,pwd);
cn.ConnectionString = ChuoiKetNoi;
cn.Open();
}
} //lớp KetNoi
Ví dụ [3] Tạo form để kết nối
Ví dụ [4] Tạo form để kết nối
private void butKetNoiDenAccess_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "Microsoft Access|*.mdb"; //lọc file
openFileDialog1.ShowDialog();//Hiển thị hộp chọn file
KetNoi.MoKetNoi(openFileDialog1.FileName);
textBox1.Text = openFileDialog1.FileName;
HQTCSDL.Text = KetNoi.cn.ConnectionString;
TenCSDL.Text = KetNoi.cn.DataSource;
TrangThai.Text = KetNoi.cn.State.ToString() ;
}
Ví dụ [5] Tạo form để kết nối
private void butKetNoiSQLServer_Click(object sender, EventArgs e)
{
KetNoi.MoKetNoi(textServer.Text, textCSDL.Text, textID.Text,
textPwd.Text);
HQTCSDL.Text = KetNoi.cn.ConnectionString;
TenCSDL.Text = KetNoi.cn.DataSource;
TrangThai.Text = KetNoi.cn.State.ToString();
}
Command (1)
• Được sử dụng sau khi đã kết nối đến CSDL• Dùng để truy xuất dữ liệu: câu lệnh SQL,
tên bảng, truy vấn hoặc thủ tục lưu trữ• Có 2 loại Command:
• SqlCommand• OleDbCommand
Command [2]
•Sau khi kết nối xong, sử dụng đối tượng Command để lấy dữ liệu về client.
•Tạo đối tượng Command và lấy dữ liệu về:
SqlCommand cmd = new SqlCommand([câu lệnh Sql]|[bảng]|[Thủ tục lưu trữ],Đường kết nối)
OleDbCommand cmd = new OleDbCommand([câulệnh Sql ]|[bảng]|[Thủ tục lưu trữ],Đường kết nối)
Command [3]
•Xác định loại câu lệnh cần lấy dữ liệu về, dùng thuộctính:CommandType:
•Text: Câu lệnh SQL (Ngầm định)
•storedProcedures: Truy vấn hoặc thủ tục lưu trữ
•TableDirect: Tên bảng.•Ví dụ:OleDbCommand cmd = new OleDbCommand(“donvi”,cn);cmd.CommandType = CommandType.TableDirect;•CommandText: chứa câu lệnh
Command [4]: Thực thi câu lệnhPhương thức Mô tả
ExecuteNonQuery
Thực thi truy vấn hành động (Insert,delete, update) vàtrả về số lượng dòng dữ liệu bị ảnh hưởng bởi truy vấncmd.CommandText = "DELETE SinhVien WHERE MSV=12";int soLuong = cmd.ExecuteNonQuery();
ExecuteReader
Thực thi một query và trả về đối tượng DataReader đểcó thể truy cập tập kết quả của query đó.
cmd.CommandText = "SELECT * FROM SV” ;SqlDataReader rdr= cmd.ExecuteReader();
ExecuteScalar
Thực thi một query và trả về giá trị của cột đầu tiêntrong dòng đầu tiên của tập kết quả.
cmd.CommandText="SELECT COUNT(*) FROM SV";int soSinhVien = (int)cmd.ExecuteScalar();
SQL: Câu lệnh Select
SELECT [ALL | DISTINCT][TOP n] <Biểuthức>
FROM Bảng|Khung nhìn[WHERE Điều kiện] [GROUP BY Các cột] [HAVING Điều kiện]
…
SQL: Câu lệnh Delete, Insert
• DELETE FROM Table [WHERE Điều kiện] • INSERT INTO Table[(Các cột)]
VALUES(Danh sách các giá trị)
SQL: Câu lệnh Update
UPDATE Tên BảngSET Cột1 = BT1
[, ..., Cộtk = BTk] [FROM Tên bảng] [WHERE Điều kiện]
SQL: Quản lý giao tác
• Giao tác SQL được định nghĩa dựa trên các câulệnh xử lý giao tác sau đây: • BEGIN TRANSACTION: Bắt đầu một giao tác• ROLLBACK TRANSACTION: Quay lui trở lại đầu giao
tác• COMMIT TRANSACTION: Đánh dấu điểm kết thúc một
giao tác. Khi câu lệnh này thực thi cũng có nghĩa là giaotác đã thực hiện thành công.
Ví dụ:begin transaction abcselect * from phanloaidelete from phanloai where maloai='hoa'rollback transaction abc ‘ phục hồi lạiselect * from phanloai
Command [5]
• Thuộc tính: Transaction: xác định giao táckhi thao tác dữ liệu.
• Ví dụ:OleDbTransaction gt = KetNoi.cn.BeginTransaction();;
string sql = "delete from PhanLoai “OleDbCommand cmdDelete = new OleDbCommand(sql, KetNoi.cn);
cmdDelete.Transaction = ts; cmdDelete.ExecuteNonQuery(); ts.Rollback();//ts.Commit();
DataReader (1)
Lấy về từng dòng dữ liệu từ một tập dữ liệu trả về
mỗi khi phương thức Read của nó được thực thi.
Command.ExecuteReader: trả về 1 DateReader
DataReader (2)
Thuộc tínhFieldCount
IsClosed
RecordsAffected
Phương thứcCloseNextResult
Read
DataReader (3)
string st= "select * from donvi" ;OleDbCommand cmd = new OleDbCommand(st,cn);OleDbDataReader r= cmd.ExecuteReader(); while (r.Read())
{ String[] st1= new String[2] ;st1[0]= r[0].ToString();st1[1]= r[1].ToString();
ListViewItem t= new ListViewItem(st1); listView1.Items.Add(t); }
Ví dụ[1] Tạo CSDl qlthuven.mdb như sau:
Ví dụ:[2] Dùng câu lệnh sql: Select, Insert, Delete, Transaction
PhanLoaiClass
Fields
ts
Methods
DemHienThiLuuNhapPhanLoaiPhucHoiSuaTenPhanLoaiXoa
Tạo lớp PhanLoai để thao tác trên bảngPhanLoai:
•Trường Ts: Quản lý giao tác•PhanLoai(): Dùng lại lớp KetNoi để kếtnối đến CSDL.• Nhap(Ma,ten): Nhập thêm 1 loại• Xoa(Ma): Xoá 1 loại•SuaTenPhanLoai: cập nhật lại 1 Loại
•HienThi(): Lấy tất cả dữ liệu của bảngPhanLoai
• Dem(): Đếm số bản ghi
•Phuchoi(): Rollback lại 1 giao tác
•Luu(): Kết thúc 1 giao tác
Ví dụ [3]: Hàm dựng PhanLoai: Kết nối đến CSDL và mở
ra 1 giao tác
class PhanLoai{
OleDbTransaction ts = null;public PhanLoai(){ //Dùng lại lớp kết nối
KetNoi.MoKetNoi("qlthuvien.mdb");ts = KetNoi.cn.BeginTransaction();
}
Ví dụ [4]: Dùng câu lệnh SQL: Insert để nhập thêm 1 loại
public void Nhap(string MaPhanLoai, string TenPhanLoai){ try {
string sql = string.Format("insert into phanloaivalues('{0}','{1}')", MaPhanLoai, TenPhanLoai);
OleDbCommand cmdInsert = new OleDbCommand(sql, KetNoi.cn);
cmdInsert.Transaction = ts;//Gán giao tác cho Command
cmdInsert.ExecuteNonQuery();}catch (Exception e) { throw e; };
}
Ví dụ [5]: Dùng câu lệnh SQL: Delete để xoá 1 loại
public int Xoa(string MaPhanLoai)
{
string sql = "delete from PhanLoai where maloai='"+MaPhanLoai +"'";
OleDbCommand cmdDelete = new OleDbCommand(sql, KetNoi.cn);
cmdDelete.Transaction = ts;
return (int)cmdDelete.ExecuteNonQuery(); //1|0
}
Ví dụ [6]: Dùng câu lệnh SQL: Update để sửa 1 loại
public void SuaTenPhanLoai(string MaPhanLoai,string TenLoaiMoi)
{ string sql = string.Format("update PhanLoai set TenLoai='{0}'
where maloai='{1}'",TenLoaiMoi,MaPhanLoai);
OleDbCommand cmdUpdate = new OleDbCommand(sql, KetNoi.cn);
cmdUpdate.Transaction = ts;
cmdUpdate.ExecuteNonQuery();
}
Ví dụ [7]: Dùng câu lệnh SQL: Select để lấy dữ liệu
public OleDbDataReader HienThi()
{
OleDbCommand cmdSelect = new OleDbCommand("PhanLoai", KetNoi.cn);
cmdSelect.CommandType = CommandType.TableDirect;
cmdSelect.Transaction = ts;
return cmdSelect.ExecuteReader();
}
Ví dụ [8]: Dùng câu lệnh SQL: Select để thống kê
public int Dem()
{
string sql = "select count(*) from PhanLoai";
OleDbCommand cmdDem = new OleDbCommand(sql,
KetNoi.cn);
cmdDem.Transaction = ts;
return (int)cmdDem.ExecuteScalar() ;
}
Ví dụ [9]: Dùng câu lệnh SQL: Transaction để quản lý giao tác
public void PhucHoi()
{ ts.Rollback();
ts = null;
ts = KetNoi.cn.BeginTransaction();
}
public void Luu()
{
ts.Commit();
ts = null;
ts = KetNoi.cn.BeginTransaction();
}
Ví dụ[10]Tạo form: FrmPhanLoaiđể thao tác trên bảng PhanLoai
listview1
Ví dụ[11]
public partial class FrmPhanLoai : Form{
PhanLoai pl = new PhanLoai();public FrmPhanLoai(){
InitializeComponent();}
Ví dụ[12]: Hàm HienThi() để hiển thị toàn bộ dữliệu của bảng PhanLoai
void HienThi(){
listView1.Items.Clear(); OleDbDataReader dr= pl.HienThi();while (dr.Read()){
string[] st = new string[2];st[0] = dr[0].ToString();st[1] = dr[1].ToString();ListViewItem lv = new ListViewItem(st); listView1.Items.Add(lv);
}}
Ví dụ[13]: Khi nạp Form sẽ hiển thị toàn bộ dữliệu và số mẫu tin trong bảng PhanLoai
private void FrmPhanLoai_Load(object sender, EventArgs e)
{ HienThi();textSoluong.Text = pl.Dem().ToString() ;
}
Ví dụ[14]: Lập trình đáp ứng sự kiện Click() trênnút Nhập để nhập vào 1 loại sách
private void butNhap_Click(object sender, EventArgs e){
try{
pl.Nhap(textMaPhanLoai.Text, textTenPhanLoai.Text);HienThi();textSoluong.Text = pl.Dem().ToString();
}catch (Exception e1) { MessageBox.Show(e1.Message ); }
}
Ví dụ [15]: Lập trình đáp ứng sự kiệnItemSelectionChanged() trên listView1 để hiển thị dữliệu lên các textbox
private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{textMaPhanLoai.Text = e.Item.Text;textTenPhanLoai.Text = e.Item.SubItems[1].Text;
}
Ví dụ [16]: Lập trình đáp ứng sự kiện Click() trênnút xoá để xoá 1 mẫu tin
private void butXoa_Click(object sender, EventArgs e){if (pl.Xoa(textMaPhanLoai.Text) == 1){
HienThi(); textSoluong.Text = pl.Dem().ToString();
}else
MessageBox.Show("Không xoá được"); }
Ví dụ [17]: Lập trình đáp ứng sự kiện Click() trênnút cập nhật, lưu và phục hồiprivate void butCapNhat_Click(object sender, EventArgs e){ //Sửa tên phân loạipl.SuaTenPhanLoai(textMaPhanLoai.Text, textTenPhanLoai.Text);HienThi(); }private void butLuu_Click(object sender, EventArgs e)
{ pl.Luu(); //Hoàn thành giao tác }private void butPhuchoi_Click(object sender, EventArgs e)
{pl.PhucHoi();// phục hồi lại giao tác
}}// kết thúc lớp Form
Sử dụng thủ tục lưu trữ, truy vấntrong command [1]
• Trong Access: sử dụng Truy vấn
• Truy vấn thường chứa các tham số
• Tham số trong truy vấn nằm giữa […]
Ví dụ: Tạo truy vấn chọn để tìm kiếmtheo tên loại sách.
• Mở CSDL qlthuvien.mdb
• Tạo ra Truy vấn chọn: đưa 2 bảng PhanLoai và Sachtham gia vào truy vấn
• Query|Parameters để gõ tên và kiểu của tham số
Sử dụng thủ tục lưu trữ, truy vấntrong command[2]
Trong SQl Server: sử dụng Thủ tục lưu trữVí dụ: tạo thủ tục: Sp_TimKiem để tìm kiếm
theo tên loại sach:
CREATE PROCEDURE Sp_TimKiem(@Tenloai as nvarchar(30))
ASselect masach,nhande,sotrang,soluong from sach
,phanloaiwhere sach.maloai=phanloai.maloai and
tenloai=@Tenloai
Sử dụng thủ tục lưu trữ, truy vấntrong command[2]
• Truyền tham số cho command sử dụngthuộc tính Parameters:– command.Parameters.Add(Thamso);– Thamso là 1 OleDbParameter – OleDbParameter Thamso = new OleDbParameter(“Tên
tham số", giá trị của tham số);– Nếu có nhiều tham số ta sử dụng mảng
OleDbParameter
Ví dụ[2]: Tạo Frmtimkiem để hiển thịsách them loại
Ví dụ [3]: Nạp dữ liệu vào comboBox1
PhanLoai Pl = new PhanLoai(); private void FrmTimKiem_Load(object sender,
EventArgs e){
OleDbDataReader Dr = Pl.HienThi();while (Dr.Read())
comboBox1.Items.Add(Dr[1].ToString() ); }
Ví dụ [2]: sử dụng Q_TimKiemtrong Access
private void comboBox1_SelectedIndexChanged(object sender,EventArgs e
{KetNoi.MoKetNoi("qlthuvien.mdb"); //kết nối đến AccessOleDbCommand cmdTk = new
OleDbCommand("Q_TimKiem", KetNoi.cn);cmdTk.CommandType = CommandType.StoredProcedure;OleDbParameter Thamso = new
OleDbParameter("@tenloai", comboBox1.Text);cmdTk.Parameters.Add(Thamso);//truyền tham số
OleDbDataReader Dr = cmdTk.ExecuteReader();// Hiển thị dữ liệu ra listView1
…..}
Ví dụ [3]: sử dụng Sp_TimKiemtrong Sql Server
private void comboBox1_SelectedIndexChanged(object sender,EventArgs e
{ //kết nối đến Sql ServerKetNoi.MoKetNoi(“tenmay","qlthuvien",“Id",“pwd");
OleDbCommand cmdTk = new OleDbCommand(“Sp_TimKiem", KetNoi.cn);
cmdTk.CommandType = CommandType.StoredProcedure;OleDbParameter Thamso = new
OleDbParameter("@tenloai", comboBox1.Text);cmdTk.Parameters.Add(Thamso);//truyền tham số
OleDbDataReader Dr = cmdTk.ExecuteReader();// Hiển thị dữ liệu ra listView1
…..}
Sử dụng Wizard: oleDbConnection1.Open(); OleDbDataReader r = oleDbCommand1.ExecuteReader();
Chương 2.
Nội dung
• Giải thích Data Binding
Data AdapterDataSet
ADO.net Data ProvidersADO.NET
Data Providers
CONECTION
DataReader
Command
DataAdapter Winform
Webform
Other
DataSet
Database
DataAdapter [1]DataAdapter được sử dụng như là cầu nối giữa CSDL(nguồndữ liệu) và DataSet.Lấy dữ liệu về và cập nhật lại dữ liệuDùng phương thức fill để nạp dữ liệu vào DataSet, và Update để lưu dữ liệu từ DataSet vào CSDL.Để cập nhật lại dữ liệu ta sử dụng các câu lệnh SQL thông qua các thuộc tính: InsertCommand, UpdateCommand, vàDeleteCommand .Để lấy dữ liệu về dùng câu lệnh SQL thông qua thuộc tínhInsertCommand.Có 2 loại DataAdapter: OleDbDataAdapter Và SqlDataAdapter
DataAdapter [2]
Lấy dữ liệu vềSelectCommand
Ý nghĩaThuộc tính
DeleteCommandTableMappings
UpdateCommand Cập nhật lại CSDL phụ thuộc vào sựthay đổi trên DataSet
InsertCommand
Nạp dữ liệu vào DataSet phụ thuộcvào SelectCommand
Fill
Ý nghĩaPhương thức
Tạo DataAdapterKết nối đến CSDLTạo đối tượng Command Tạo DataAdapterXác định thuộc tính command cho DataAdapter
KetNoi.MoKetNoi("qlthuvien.mdb");
OleDbCommand cmd = new OleDbCommand("PhanLoai", KetNoi.cn);
cmd.CommandType = CommandType.TableDirect;
OleDbDataAdapter daPhanLoai = new OleDbDataAdapter();
daPhanLoai.SelectCommand = cmd;
DataSet: Mô hình ngắt kết nối•DataSet đóng vai trò của một CSDL ảo• Thuộc tính Tables là một tập hợp cácDataTable chứa dữ liệu và lược đồ dữ liệu môtả dữ liệu trong DataTable. •Thuộc tính Relations chứa tập hợp các đốitượng DataRelation xác định mối quan hệcủa các DataTable của DataSet. •Lớp DataSet cũng hỗ trợ việc sao chép, trộn, và xóa DataSet thông qua các phương thứctương ứng là Copy, Merge, và Clear.
Kiến trúc DataSet
Mô hình hoạt động DataSet
Client Server
Client yêu cầu dữ liệu từ Server
DataSet
Gởi dữ liệ
u đến
DataSet
DataSet truyền dữ liệu đến client
Client sửa đổi dữ liệu trong DataSet Dữliệu
trong Data
Set đượ
c truyền
đếnServ
er
Tạo và nạp dữ liệu vào DataSet
KetNoi.MoKetNoi("qlthuvien.mdb");OleDbCommand CmdPl = new OleDbCommand("PhanLoai", KetNoi.cnCmdPl.CommandType = CommandType.TableDirect;OleDbDataAdapter daPhanLoai = new OleDbDataAdapter();daPhanLoai.SelectCommand = CmdPl;DataSet ds = new DataSet();daPhanLoai.Fill(ds, "PhanLoai");OleDbCommand CmdSach = new OleDbCommand("sach", KetNoi.cn);CmdSach.CommandType = CommandType.TableDirect;OleDbDataAdapter daSach = new OleDbDataAdapter();daSach.SelectCommand = CmdSach;daSach.Fill(ds,"sach");
Kết nối đến CSDLTạo đối tượng Command Tạo DataAdapterXác định thuộc tính command cho DataAdapterTạo và nạp dữ liệu vào DataSet
Hiển thị dữ liệu: Điều khiển dataGridView
Hiển thị và sửa đổi dữ liệu từ bất kỳ nguồn nàoCác thuộc tính:
DataSource = nguồn dữ liệu;DataMember = tên bảng trong nguồn dữ liêu; RowCount: Số dòng dữ liệuColumnCount: Số cột.
Ví dụ: Hiển thị dữ liệu của 2 bảng: Phân loại,Sách
dataGridView1 dataGridView2
Ví dụ [1]:Nạp 2 bảng PhanLoai và Sách vào DataSet
private void FrmDataSet_Load(object sender, EventArgs e){KetNoi.MoKetNoi("qlthuvien.mdb");OleDbCommand CmdPl = new OleDbCommand("PhanLoai", KetNoi.cn);CmdPl.CommandType = CommandType.TableDirect;OleDbDataAdapter daPhanLoai = new OleDbDataAdapter();daPhanLoai.SelectCommand = CmdPl;DataSet ds = new DataSet();daPhanLoai.Fill(ds, "PhanLoai");OleDbCommand CmdSach = new OleDbCommand("sach", KetNoi.cn);CmdSach.CommandType = CommandType.TableDirect;OleDbDataAdapter daSach = new OleDbDataAdapter();daSach.SelectCommand = CmdSach;daSach.Fill(ds,"sach");
Ví dụ [2]:Nạp dữ liệu từ DataSet vào dataGridView:
Nạp bảng PhanLoai của dataSet vào dataGridView1Nạp bảng Sach của dataSet vào dataGridView2
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "PhanLoai";
dataGridView2.DataSource = ds;
dataGridView2.DataMember = "sach";
lSoLoai.Text = "Số loại: "+ dataGridView1.RowCount.ToString() ;
lSoLuongSach.Text = "Số đầu sách: "+dataGridView2.RowCount.ToString();
} //FrmDataSet_Load()
DataSet: DataTable• Thuộc tính DataSet.Tables chứa các đối tượng DataTable.
Mỗi đối tượng trong tập hợp này có thể được truy xuất bằngchỉ số hoặc bằng tên bảng.
• Ví dụ: Nạp dữ liệu của bảng PhanLoai vào dataGridView1:dataGridView1.DataSource = ds.Tables["PhanLoai"] ;
• Các DataTable trong tập hợp DataSet.DataTables mô phỏngcác Table trong CSDL quan hệ (các row, column, …). Cácthuộc tính quan trọng nhất của lớp DataTable là Columns vàRows định nghĩa cấu trúc và nội dung bảng dữ liệu.
• Phương thức: RejectChanges();AcceptChanges(); • Truy cập đến 1 ô trong bảng: ds.Tables[“bang"].rows[i][j];
Ví dụ: DataSet: DataTable• Giả sử đã có bảng Sv(ma,Hoten,Dm1,dm2).• Viết chương trình hiển thị DTB của các SV.• Tạo thêm cột DTB trong bảng Sv của DataSet, truy cập đến từng
ô của bảng SV để tính DTB
//nạp bảng Sv vào DataSet: dsds.Tables["Sv"].Columns.Add("Dtb"); //tạo thêm cột DTBint dong = ds.Tables["Sv"].Rows.Count; //Số dòng trong bảng Svint cot = ds.Tables["Sv"].Columns.Count;//Số cột trong bảng Svfor(int i=0;i<dong;i++){ int dm1=(int)ds.Tables["Sv"].Rows[i][2];
int dm2=(int)ds.Tables["Sv"].Rows[i][3];ds.Tables["Sv"].Rows[i][cot-1] = (dm1 + dm2) / 2; //Tính DTB
}ds.Tables["Sv"].AcceptChanges(); //Cho thay đổi trong bảng SvdataGridView1.DataSource = ds.Tables["sv"];
DataSet: DataView• DataView đóng vai trò như tầng hiển thị dữ liệu
lưu trữ trong DataTable. Nó cho phép người sửdụng sắp xếp, lọc và tìm kiếm dữ liệu.
• Nạp dữ liệu vào DataView:DataView <tên> = new DataView(ds.Tables[tên bảng]);
Thuộc tính:– RowFilter=<Điều kiện giống điều kiện sau where
trong câu lệnh SQL>– Sort =“Tên cột DESC|ASC”– Count: số dòng trong DataView
Ví dụ DataSet: DataView
Ví dụ DataSet: DataViewOleDbCommand cmd;OleDbDataAdapter da;DataSet ds = new DataSet(); //Nạp 2 bảng PhanLoai và sách vào DataSet dsprivate void FrmDataView_Load(object sender, EventArgs e)
{KetNoi.MoKetNoi("qlthuvien.mdb");string sql = "select * from PhanLoai,sach where
Phanloai.maloai=sach.maloai";cmd = new OleDbCommand(sql, KetNoi.cn);da = new OleDbDataAdapter();da.SelectCommand = cmd;ds = new DataSet();da.Fill(ds, "PhanLoai_Sach");dataGridView1.DataSource = ds.Tables["PhanLoai_Sach"];
}
Ví dụ DataSet: DataViewprivate void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == 13){DataView Dv = new DataView(ds.Tables[0]);Dv.RowFilter = string.Format(
"nhande like '%{0}%' or tacgia like '%{1}%‘ or tenloai like '%{2}%'", textBox1.Text, textBox1.Text,textBox1.Text );
Dv.Sort="Soluong ASC, Sotrang DESC"; lketqua.Text = "Số sách tìm được:" + Dv.Count.ToString(); dataGridView1.DataSource = Dv;
}}
Cập nhật CSDL bằng DataAdapter• Khi DataAdapter nạp dữ liệu vào DataSet, connection sẽđược đóng, và chỉ thao tác trên DataSet không ảnhhưởng đến CSDL
• Để cập nhật lai dữ liệu thì DataAdapter phải khôi phụcconnection và gửi các dòng dữ liệu đã được thay đổi lênCSDL.
• Ngoài SelectCommand, DataAdapter có thêm 3 thuộctính Command nữa, gồm InsertCommand, DeleteCommand và UpdateCommand, làm nhiệm vụchèn, xóa, cập nhật. Các Command này được thực thikhi phương thức Update của DataAdapter được triệugọi.
• Để cập lại CSDL thì tap phải tạo ra bảng ánh xạ(TableMappings) và truyền tham số cho các câu lệnhSQL, các công việc này rất mất thời gian, ADO.NET đãcài đặt sẳn một lớp gọi là CommandBuilder dùng để cậpnhật lại 1 bảng trong CSDL một cách tự động.
Cập nhật CSDL bằng DataAdapter
• CommandBuilder sẽ sinh ra các Command vàTableMappings cần thiết để thực hiện việccập nhật nguồn dữ liệu tạo ra bởi DataSet.
• Cách tạo đối tượng CommandBuilder là truyềnđối tượng DataAdapter cho phương thức khởidựng của nó.
• Khi phương thức DataAdapter.Update đượcgọi, các lệnh SQL sẽ được tự động sinh ra vàthực thi.
Ví dụ [1]
Ví dụ [2]OleDbCommand CmdSelect;OleDbDataAdapter daPhanLoai;DataSet ds = new DataSet();//Nạp dữ liệu vào DataSet, tạo OleDbCommandBuilder private void FrmCapNhatDataSet_Load(object sender, EventArgs e){KetNoi.MoKetNoi("qlthuvien.mdb");CmdSelect = new OleDbCommand("select * from PhanLoai",
KetNoi.cn);daPhanLoai = new OleDbDataAdapter();daPhanLoai.SelectCommand = CmdSelect;OleDbCommandBuilder cmdB = new
OleDbCommandBuilder(daPhanLoai);daPhanLoai.Fill(ds, "Phanloai");}
Ví dụ [3]//tạo ra 1dòng mới trên bảng//Nhập dữ liệu vào cho dòng//Cập nhật lại CSDLprivate void butNhap_Click(object sender, EventArgs e)
{
DataTable dt = ds.Tables[0];DataRow dr= dt.NewRow();dr["Maloai"] = textMaPhanLoai.Text;dr["tenloai"] = textTenPhanLoai.Text;dt.Rows.Add(dr);daPhanLoai.Update(ds, "Phanloai");
}
Quan hệ giữa các bảng trong Dataset• Khi nạp các bảng vào DataSet thì các bảng này
chưa có quan hệ với nhau.• Để đặt quan hệ giữa các bảng sử dụng đối tượng
DataRelation với hàm dựng sau:public DataRelation( string relationName,
DataColumn parentColumn, DataColumnchildColumn)
• Thuộc tính Relations của DataSet: quản lý tậphợp các DataRelation đã được định nghĩa trongDataSet.
• Dùng phương thức Relations.Add để thêm cácDataRelation vào tập hợp Relations.
Ví dụ[1]• Hiển thị tất cả các sách thuộc mỗi loại.• Nạp 2 bảng PhanLoai và Sach vào
DataSet ds• ds.Tables[“tênbảng”]: trả về toàn bộ dữ liệu
của bảng• ds.Tables[“tênbảng”].Columns[“têncột"]: trả về
tập hợp DataColumn của cột• ds.Tables[“tênbảng”].Rows: trả về tập hợp
DataRow của bảng• ds.Tables[“tênbảngcha”].Rows[i].GetChildRo
ws(“tên quan hệ") : trả về tập hợp các dòngtương ứng trên bảng con
Ví dụ[2]Đặt quan hệ giữa 2 bảng PhanLoai và Sach trong dataSet
ds
DataTable BCha = ds.Tables["PhanLoai"];
DataTable BCon = ds.Tables["sach"];
DataColumn Kchinh= BCha.Columns["Maloai"];
DataColumn KPhu = BCon.Columns["Maloai"];
DataRelation dr = new DataRelation("Pl_Sach", Kchinh, KPhu);
ds.Relations.Add(dr);
Ví dụ[3]Hiển thị sách theo mỗi loại ra ListView1foreach (DataRow DCha in BCha.Rows)
{ listView1.Items.Add(DCha["tenloai"].ToString() );
foreach (DataRow Dcon in DCha.GetChildRows("Pl_sach"))
{ string[] st = new string[5];
st[1] = Dcon["masach"].ToString();
st[2] = Dcon["nhande"].ToString();
st[3] = Dcon["sotrang"].ToString();
st[4] = Dcon["soluong"].ToString();
ListViewItem lv = new ListViewItem(st);
listView1.Items.Add(lv);
}
Data Binding
Các điều khiển giao diện Các điều khiển ADO.netVí dụ Ví dụ
ComboBox
DataBinding
Là sự kết hợp giữa các điều khiển để thiết kế giao diện nhưTextBox, ListBox, … với các điều khiển của ADO.NET nhưDataSet, DataTable, ….
Mọi sự thay đổi trên các điều khiển giao diện sẽ ảnh hưởngđến dữ liệu trong ADO.NET
Data Binding
Các loại Binding (1)
ADO.NET cung cấp 2 loại Binding:
- DataBinding đơn giản (Simple DataBinding): Tạimột thời điểm, một giá trị đơn trong DataSet cóthể bị buộc vào bất kỳ một điều khiển.
– Ví dụ: giả sử đã có 1 DataSet ds chứa dữ liệu củabảng PhanLoai, cần buộc tên tên loại vào TextBoxtxtloai:
• txtloai.DataBindings.Add("Text", ds,”PhanLoai.tenLoai");
• Khi đó mọi thay đổi trên DataSet ds sẽ ảnh hưởng đến
Các loại Binding (2)DataBinding phức tạp (Complex DataBinding): Các dữ liệu trongDataSet bị buộc vào một điều khiển thay vì chỉ một giá trị đơn. Chỉcó DataGidView, ComboBox và listBox hỗ trợ chức năngDataBinding phức tạp.
- Dùng các thuộc tính: DataSource,DataMember hoặcDisplayMember để buộc
Ví dụ: Giả sử đã có DataSet ds chứa dữ liệu bảng PhanLoai:– listBox1.DataSource = ds;– listBox1.DisplayMember = "PhanLoai.TenLoai";– dataGridView1.DataSource = ds;– dataGridView1.DataMember = "PhanLoai– comboBox1.DataSource = ds;– comboBox1.DisplayMember = "PhanLoai.TenLoai"; ";
Ví dụ (1)Tạo form để người dùng chọn 1 tênloai sách trên listBox1 sẽhiển thị tất cả các sách trên datagrid1
Ví dụ (2)Lập trình trên sự kiện Load của form:
–Nạp 2 bảng sách và phân loại vào DataSet ds
– Đặt quan hệ giữa 2 bảng sach và PhanLoai trong dataset ds: tên quan hệ là Pl_Sach
–Buộc listBox1 quản lý cột tên loại của bảng PhanLoai, vàdatagrid1 quản lý tập các sách của 1 loại:
• listBox1.DataSource = ds;• listBox1.DisplayMember = "PhanLoai.TenLoai";• dataGridView1.DataSource = ds;• dataGridView1.DataMember = "PhanLoai.Pl_Sach";
Các nguồn dữ liệu củaDataBinding
–DataTable: •DataTable t = ds.Tables[“Sach"]; •txtten.DataBindings.Add("Text", t, “nhande"); •cmbsach.DataSource = t; •cmbsach.DisplayMember = “masach"; •dgvsach.DataSource = t;
DataView:• DataView s =new DataView (ds.Tables[“sach"]); •cmbsach.DataSource sach;•Cmbsach.DisplayMember = “tacgia";
– DataSet:– Mảng: •int[] t = new int[4] { 12, 2, 3, 4 };•txt.DataBindings.Add("Text", t, "");•cmb.DataSource = t;
– Bất kỳ các thành phần được cài đặt từ giao diện Ilist có thể xem là như nguồn dữliệu của DataBinding
BindingContext• Cách tương tác giữa 1 nguồn dữ liệu với tất cả các điều
khiển bị buộc trên form
• Mỗi Form đều có một thuộc tính BindingContext. MộtBindingContext có một tập hợp các BindingManagerBase, các đối tượng này được tạo ra khi dữ liệu buộc vào mộtđiều khiển.
• Một CurrencyManager có thể duy trì một vị trí hiện thờibên trong nguồn dữ liệu và khi vị trí này thay đổi thì dữliệu trên các điều khiển bị buộc trên form sẽ tự động thayđổi theo .
• Một CurrencyManager chỉ được tạo ra một lần cho mộtnguồn dữ liệu. Nếu hai TextBox bị buộc vào 1 dòng củaDataTable khi đó chỉ có một CurrencyManager được tạo
BindingContext
Thuộctính
Mô tảBindings Tập hợp các đối tượng Binding được quản lý
bởi CurrencyManagerCount Số dòng được quản lý trong
CurrencyManagerCurrent Giá trị của các đối tượng hiện thời trongnguồn dữ liệu
Position Gets hoặc sets đối tượng hiện thời trongdanh sách các đối tượng được quản lýtrong CurrencyManager
Lựa chọn mô hình kết nối• DataSet là một lựa chọn tốt khi:
– Dữ liệu cần được tuần tự hóa và/hoặc gửi đi bằng HTTP.– Các điều khiển read-only trên Form Win Form được buộc với
data source. – Một điều khiển Win Form như GridView hay DataView được
kết buộc với một data source có khả năng cập nhật được.– Một ứng dụng desktop cần thêm, xóa, sửa các dòng dữ liệu.
• DataReader là lựa chọn cho những trường hợp:– Cần quản lý một số lượng lớn các record, lớn đến mức mà bộ
nhớ và thời gian để nạp dữ liệu cho DataSet là phi thực tế.– Dữ liệu là read-only và được kết buộc với một điều khiển loại
danh sách (list control) của Win Form hoặc Web Form.– CSDL là không ổn định và thay đổi thường xuyên.
LẬP TRÌNH ỨNG DỤNG WEB VỚI ASP.NET VÀ C#
Nội dung
• Kiến trúc của ứng dụng Web• Công nghệ phát triển ứng dụng Web
(động)• Kiến trúc• HTML
Web động
• Nội dung được Web Server sinh ra khi có yêu cầu từ Client.
• Nội dung hiển thị tại các lần duyệt khác nhau làkhác nhau.
• Rất phổ dụng: Hầu hết các trang web thương mại đều là web động.
• Sử dụng ngôn ngữ lập trình để sinh ra trang HTML.
• Sử dụng CSDL.
Web động
Web động
CSDL
WebServer
WebBrowser
Database Provider
http://www....
Yêu cầu dữ liệu
Thao tác CSDLDữ liệu
Dữ liệu
Nội dung (HTML)
Công nghệ phát triển Web (động)
• Đa dạng và không ngừng được phát triển.
• Microsoft: ASP, ASP.NET• Sun: Java Servelet, JSP.• Khác: PHP
ASP.NET - Kiến trúc
ASPX
.ASPX.ASPX
ASP.NET - Kiến trúc
Client (Browser)
ASP.DLLASP.DLL
IISIIS VBScriptVBScriptJavaScriptJavaScript
ActiveX Data Objects(ADO)
ActiveX Data Objects(ADO)
DatabaseDatabase ASP file
ASP.NET – Đặc điểm
• Hướng đối tượng: Mỗi trang bao gồm hai đối tượng kế thừa nhau.
• Tách mã giao diện (HTML) với mã xử lý bằng kỹ thuật Codebehind.
• => Dễ viết chương trình, tìm lỗi.• => Giấu được mã (mã được dịch thành DLL).
.aspx .aspx.cs
ASP.NET – Đặc điểm (2)
• Các điều khiển phía Server (server-side controls).
• => Có thể xử lý tất cả trên server.– <form id="Form1" method="post" runat="server">
</form>– <asp:Button id="Button1" runat="server"
Text="Tìm kiếm"></asp:Button>– <asp:TextBox id="txtUserName" runat="Server"/>– <input type = “text” id = “hoten” runat=“server”>
ASP.NET – Đặc điểm (3)
• Các điều khiển phía Server (server-side controls). – Auto PostBack cho từng điều khiển => Bắt
sự kiện trên điều khiển đơn giản.• <asp:CheckBox id="CheckBox1" runat="server"
AutoPostBack="True" ></asp:CheckBox>
ASP.NET – Đặc điểm (3)
• Các điều khiển phía Server (server-side controls). – Kiểm tra hợp thức (validation)
• Cần mã– Tùy biến (CustomValidator)
• Không cần mã– Yêu cầu nhập (RequiredFieldValidator)– Trong khoảng (RangeValidator)– So sánh (CompareValidator)– Biểu thức chung (RegularExpressionValidator)
Giới thiệu 1 số thẻ HTML
• <B>, <U>, <I>• <Table>, <tr>, <td>• <Img src=“file ảnh”>• <Marquee>• <A href
=“url?ts1=gtri1&ts2=gt2&…&tsn=gtn”>Tên liên kết </a>• <Form> ….• Dùng các trình soạn thảo Web để phát sinh
các thẻ
Chương 2
GIỚI THIỆU
• Active Server Pages (ASP): là kịch bản chạy ở phía Server, cung cấp 1 WebServer có thể xử lý các ứng dụng logic vàtrả về HTML cho browser.
• Web Forms: Cung cấp các công cụ để thiết kế và soạn thảo Form
• Design: hiển thị bố cục của trang• Source: Hiển thị mã tự động phát sinh khi tạo trang Web.• Web.config: là file XML chứa cấu hình trong project .• Global.asax là file tự chọn được sử dụng để thao tác trên
các sự kiện ở mức ứng dụng.• *.aspx, *.aspx.cs: Desgn, Codebehind
Thư mục ảo
<SCRIPT>
Page_Load
Đáp ứng sự kiện
Ví dụ trang ASP.NET [1]
HTML Control
Web Control
Ví dụ trang ASP.NET [2]
Click MeClick Me
LABEL
Click MeClick Me
Hello World
void click_btn(Object sender, EventArgs e){lbl.Text="Hello World";}
Đáp ứng sự kiện
Request and Response• Resquest:
– Nhận yêu cầu từ Client gởi đến Server khi nút Submit được nhấn.
– Khi nhấn nút Submit thì dữ liệu của các điều khiển bên trong Form sẽ được gởi đến Server (Post).
– Để nhận được dữ liệu gởi từ Form (client):• Request.Form[“tên điều khiển”];• Để nhận đựoc tham số gởi bằng Get (Dùng thể <A>)• Request.QueryString[“tên tham số]);
• Response:– Gởi dữ liệu từ Client đến Server– Phưong thức:
• Write(dữ liệu);• Rediirect(“URL”);
Request and Response
Nhap.htm<body>
<form method="POST" action="NHAPHTML.ASPX">
<p>Mã Loại:<input type="text" name="txtma" size="20"></p>
<p>Tên Loại<input type="text" name="txtten" size="20"></p>
<p> <input type="submit" value="Nhap" name="Nhap"> </p>
</form>
</body>
NhapHtml.aspxprotected void Page_Load(object sender, EventArgs e)
{
string ma = Request.Form["txtma"];
string ten = Request.Form["txtten"];
Response.Write("Mã Loai:" + ma);
Response.Write("<br>Tên Loại" + ten);
}
NhapHtml.aspx: Nhập 1 loại sáchprotected void Page_Load(object sender, EventArgs e)
{string ma = Request.Form["txtma"];
string ten = Request.Form["txtten"];
OleDbConnection cn = new OleDbConnection("provider=microsoft.jet.oledb.4.0;data source=“ +
Server.MapPath("qlthuvien.mdb") );
cn.Open();
string sql = string.Format("insert into Phanloai values('{0}','{1}')",ma,ten);
OleDbCommand cmd = new OleDbCommand(sql,cn);
cmd.ExecuteNonQuery();
Response.Redirect("~/Nhap.htm");
}
NhapHtml.aspx: Nhập 1 loại sáchSử dụng các điều khiển Web chạy trên Server:
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<asp:Label ID="Label1" runat="server" Text="Mã loại:"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
<asp:Label ID="Label2" runat="server" Text="Tên loại:"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server“ ></asp:TextBox><br />
<asp:Button ID="ButNhap" runat="server" Height="23px" Text="Nhập" Width="59px" OnClick="ButNhap_Click" /></div>
</form>
</body>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<asp:Label ID="Label1" runat="server" Text="Mã loại:"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
<asp:Label ID="Label2" runat="server" Text="Tên loại:"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server“ ></asp:TextBox><br />
<asp:Button ID="ButNhap" runat="server" Height="23px" Text="Nhập" Width="59px" OnClick="ButNhap_Click" /></div>
</form>
</body>
protected void ButNhap_Click(object sender, EventArgs e){string ma = TextBox1.Text;string ten = TextBox2.Text;OleDbConnection cn = new
OleDbConnection("provider=microsoft.jet.oledb.4.0;data source=“ + Server.MapPath("qlthuvien.mdb"));
cn.Open();string sql = string.Format("insert into Phanloai values('{0}','{1}')",
ma, ten);OleDbCommand cmd = new OleDbCommand(sql, cn);cmd.ExecuteNonQuery();cn.Close(); }
NhapHtml.aspx: Nhập 1 loại sáchSử dụng các điều khiển Web chạy trên Server:
Đối tượng Server
HTMLEncode
MapPath
Server.property | methodCú phápCú pháp
MethodsMethods
cn = new OleDbConnection("provider=microsoft.jet.oledb.4.0;data source=" + Server.MapPath("qlthuvien.mdb"));
Response.Write(“<b>alo</b>”);Response.Write(Server.HtmlEncode(“<b>alo</b>”));
Đối tượng Session
• Lưu trữ các thông tin của người dùng trong 1 phiên làm việc.
• Biến lưu trữ trong Session không bị xoá đi khi người dùng chuyển từ trang này sang trang khác.
• WebServer sẽ tự động tạo ra khi người dùng yêu cầu 1 trang web, bị giải phóng khi kết thúc phiên làm việc
• Session[“tên biến” ]= object
Ví dụ 1• Tạo một Website để sinh viên mượn sách trong
thư viện bao gồm các WebPage:– Qlthuvien.aspx: Chứa giao diện chính– Dangky.Aspx: Đăng nhập.– Hienthi. Aspx: Hiển thị tất cả các sách– Mượn. Asp: mượn sách.
• Yêu cầu: người sử dụng phải đăng nhập mới được xem hoặc mượn sách.
• Ta phải tạo ra 1 phiên làm việc (Session) đểkiểm tra xem người dùng đã đăng nhập chưa?
Qlthuvien.aspx
protected void LinkButton3Dn_Click(object sender, EventArgs e){
Response.Redirect("Dangky.aspx"); }
protected void LinkButton1HT_Click(object sender, EventArgs e){
Response.Redirect("Hienthi.aspx"); }
…..
DangKy.aspx
protected void ButDangNhap_Click(object sender, EventArgs e){
Session["ID"] = TextID.Text;....
}
HienThi.aspx
protected void Page_Load(object sender, EventArgs e){
if (Session["Id"] == null || Session["Id"] == "")Response.Redirect("~/Dangky.aspx");
//}
Bài thực hành (Session)Tạo ra trang Web đơn giản để mua hàng trên mạng:
GridView1GridView1
Tạo lớp GioHang.cs để nhập thêm 1 hàng vào giỏ
public class Giohang{ public DataTable dt = new DataTable("Hang");
public Giohang(){ dt.Columns.Add("TenHang");
dt.Columns.Add("Soluong"); }public void ThemGiohang(string th,string sl){ DataRow dr = dt.NewRow();
dr[0] = th;dr[1] = sl;dt.Rows.Add(dr);dt.AcceptChanges();
}}
Lập trình trên nút mua và giỏ hàngprotected void butMua_Click(object sender, EventArgs e)
{if (Session["gh"] == null)
gh = new Giohang();else
gh = (Giohang) Session["gh"]; gh.ThemGiohang(DropDownList1.Text, textSoluong.Text);Session["gh"] = gh;
}protected void ButGioHang_Click(object sender, EventArgs e){ Giohang gh = (Giohang)Session["gh"];
if (gh != null){
GridView1.DataSource = gh.dt;GridView1.DataBind();
}
Yêu cầu bổ sung• Tạo CSDL qlhang.mdb bao gồm bảng hang(mahang,tenhang,gia),
khachhang(hoten,diachi,tenhang,soluong,thanhtien).
• DropDownList1 Hiển thị tất cả các tên hàng của bảng hàng
• Trong giỏ hàng thêm trường ThanhTien=Sốlượng * giá.
• Kiểm trả xem trong giỏ hàng nếu đã có tên hàng thì tăng số lượng, tính lại thành tiền.
• Tạo thêm nút Thanh Toán: người dùng nhập họ tên và địa chỉ và chuyển tất cả hàng trong giỏ hàng vào bảng Khachhang
CachingCaching là kỹ thuật để tăng tốc độ thực hiện khi truy cập dữ liệu.Cache[“Tên"] = Source;Cache.EffectivePrivateBytesLimit: lấy số KB tối đa trong Catch.Cache.Remove(“tên”): Xoá CacheCache. Insert(“Tên”, nguồn dữ liệu); Thêm Cache
Data Caching
Data Caching (tt)DataView Source = null;protected void Page_Load(object sender, EventArgs e)
{Source = (DataView)Cache["MyCache1"];if (Source == null) { SqlConnection myConnection = new SqlConnection ("server=nhha;database=pubs;uid=sa; pwd="); SqlDataAdapter myCommand = new SqlDataAdapter("select * from employee", myConnection);DataSet ds = new DataSet();myCommand.Fill(ds, "employee");Source = new DataView(ds.Tables["employee"]); Cache["MyCache1"] = Source;Label1.Text = "Dữ liệu lấy từ Table";
}else
Label1.Text = “Dữ liệu lấy từ Cache";GridView1.DataSource = Source; GridView1.DataBind();}
Data Caching (tt)protected void Button1_Click(object sender, EventArgs e)
{
Cache.Remove("MyCache1"); }protected void Button2_Click(object sender, EventArgs e){
Cache.Insert("MyCache1", Source); }