Slide Bai Giang c# Va Ung Dung.jpg

Preview:

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); }