ADO.NET實例教學一
今天我們先把上次文章《ADO.NET(內涵效率問題)》 中給大家講到的問題簡單的回顧一下.
在ADO.NET中除了可以連接SQL數據庫的類,還有哪些類呢?我們用反編譯器看一下吧。
一、ADO中的DbConnection類
二、DbConection的三個子類
三、DbCommand類
四、給我們寫代碼時帶來的思路
好,ado,net就是訪問數據庫的一種技術。
在訪問數據庫的時候至少要用到哪些類呢?
1是SqlConnection,指定它連接哪個數據庫的叫:“連接字符串”。連接哪個數據庫,哪個服務器,具體的登錄方式,還有一些像操作時間的屬性。
2.我們該執行SQl命令了。
這一步里我們要:確定SQL語句。
3.接下來我們該執行了,執行的時候需要
創建SqlCommand
4.SqlCommand有好幾個方法呢?
建議執行不同SQL語句的時候,使用不同的方法。那么我們有幾個方法分別是什么時候用來着?
ExecuteNonQuery() 執行對數據庫的增刪改,返回受影響的行數,適合:insert、delete、update(對於其他語句返回-1)----------這個方法有返回值,返回值是個整型。返回所影響的行數。返回的如果是0,不能證明執行失敗了。
理由:現在我要把班級表中所有的男同學的年齡改成20,但是表中都是女生,返回所影響的行數是0。這個時候我們不能說SQL語句執行失敗了。
除了這個還有
ExecuteScalar()執行查詢,返回首行首列
有返回值,return:object
一般用來執行什么樣的SQL語句的呢?
用來執行返回單個值的sql語句.
ExecuteReader(); 當執行sql語句返回多行多列時使用。
返回SqlDataReader 通過reader拿到數據
其實這三個方法執行任意一條sql語句都能成功,只是我們用對的時候能得到那個返回結果,用錯的就沒法得到這個返回結果了。
接下來我們重點說下reader的使用。reader取數據時是個什么過程呢?
執行完sql語句以后,查詢出來數據在服務器那個內存里面。判斷下如果沒數據告知用戶,要是有數據就一行一行的讀出來。通過索引,獲取當前行的某一列的值。
需要注意:在reader的使用的時候必須保證Connection是打開着的。reader當然更得是打開着的。
當reader使用完以后也需要close關閉。
遇到空值的時候用IsDBNull
我們還學習了ado.net連接池
連接池默認是啟用的,dot.net程序的連接池。程序一關閉就自動關閉了。
連接池的作用是什么呢?
可以提升程序的性能。
為什么能提升程序的性能呢?原因就是始終不關閉。
1>當上一個連接對象調用Close()方法后,才會將連接放入池中。
2>當再次創建連接對象時,只有當本次創建連接對象所使用的連接字符串與池中現有連接對象的連接字符串完全一致時,才會使用池中的連接對象。
還學了帶參數的sql語句:
它的作用是,防止注入攻擊。
等咱們后面學了存儲過程之后,你會發現,帶參數的sql語句編譯之后,調的就是存儲過程。是完全一樣的。
所以以后不要遇到這個問題,帶參數的sql不能防止注入攻擊,只有存儲過程可以。
實際上,兩個問題是一樣的,都能防止注入攻擊。
我以前有個同學去面試,面試官說只有存儲過程能防止注入攻擊。我同學說:“帶參數的sql語句也可以防止啊”。面試官對此,相當不屑。我同學不知道,他倆說的是一回事兒啊。
帶參數的sql語句寫的時候跟之前幾乎是一模一樣的,只是
string sql=”select*from where id=@uid” 出現了一些@變量。
將來集合里面add幾個對象,如:cmd.Parameters.Add(new SqlParameter(“@uid”,”zxh));
為了方便可以直接:cmd.Parameters.AddWithValue(“”,””);
建議大家以后就是用帶參數的sql語句。
像select count(*) from Biao where id=;沒有涉及到動態的拼接,就沒必要使用帶參數的sql語句了。
我們在寫帶參數的sql語句的時候sql server僅支持已命名參數@arg1,而oledb、odbc僅支持通用參數標記(?),不同數據提供程序對參數的寫法可能不同。
下面我們做一些個練習:
V1.0:用戶界面中進行登錄判斷。
V1.1:輸錯三次禁止登陸,1分鍾后才能繼續。用數據庫記錄ErrorTimes,最后出錯時間lastErrorDateTime。。
數據導入:從文本文件導入用戶信息。
數據導出:將用戶信息導出到文本文件。
V1.1:輸錯三次禁止登陸,1分鍾后才能繼續。用數據庫記錄ErrorTimes,最后出錯時間lastErrorDateTime。
五、畫好登錄界面
首先想下sql語句,或者在寫程序之前先分析一下。
六、需求分析
所以,需要給這張表增加兩列。
七、按照需求建好表
好,現在看下這個案例的基本思路:
出錯之后就記錄,記錄一次時間,記錄一次次數。
下次登錄之前判斷是否為鎖定,如果鎖定了,提示一下用戶。
如果沒鎖定再判斷下,是時間不夠呢?還是次數不夠?
八、校驗當前用戶是否被鎖定的sql語句
九、登錄及判斷登錄錯誤次數及延遲時間的代碼
十、登錄時間代碼
介紹個小知識:
十一、獲取時間問題
登錄限制時間的代碼:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Data.SqlClient; 10 11 namespace _9._5案例 12 { 13 public partial class Form1 : Form 14 { 15 public Form1() 16 { 17 InitializeComponent(); 18 } 19 /// <summary> 20 /// 點擊登錄按鈕 21 /// </summary> 22 /// <param name="sender"></param> 23 /// <param name="e"></param> 24 private void btnLogin_Click(object sender, EventArgs e) 25 { 26 //1.獲取用戶名和密碼 27 string loginId = txtUid.Text.Trim(); 28 string loginPwd = txtPwd.Text; 29 30 #region 每次登錄之前執行校驗 31 //4.每次登錄之前執行校驗,也需要連接數據庫,封裝成一個方法,寫在里面。 32 bool b = IsLocked(loginId); 33 #endregion 34 //5.b返回true就是以鎖定了。 35 if (b) 36 { 37 MessageBox.Show("您的賬戶已經鎖定,請1分鍾以后再嘗試!"); 38 } 39 else 40 { 41 //6.如果用戶沒有鎖定,有兩種情況1>次數不夠3次,2>時間已經超過1分鍾 42 //"Update UserLogin set ErrorTimes=0 where LoginId=@uid and ErrorTimes>=3" 43 //大於三次清零 44 ClearErrorTime(loginId); 45 //回答一個問題就是這只在sql語句中清3次的情況? 46 //原因是我在之前登陸之前的校驗(4)中已經判斷了用戶登錄小於1分鍾的情況。這樣返回false的時候,說明登錄時間已經超過1分鍾了。 47 48 #region 執行登錄校驗 49 //2.進行登錄操作 50 //寫個連接字符串 51 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 52 //連接對象 53 using (SqlConnection con = new SqlConnection(constr)) 54 { 55 //執行sql語句 56 string sql = "select count(*) from UserLogin where LoginId=@uid and LoginPwd=@pwd"; 57 //執行之前創建sqlcommand 58 using (SqlCommand cmd = new SqlCommand(sql, con)) 59 { 60 //增加參數 61 cmd.Parameters.AddWithValue("@uid", loginId); 62 cmd.Parameters.AddWithValue("@pwd", loginPwd); 63 //開始執行,執行之前先open,再close 64 con.Open(); 65 int r = Convert.ToInt32(cmd.ExecuteScalar()); 66 con.Close(); 67 //這如果不用帶參數的sql語句,用r=1也可以避免注入攻擊。 68 if (r > 0) 69 { 70 MessageBox.Show("登錄成功!"); 71 } 72 else 73 { 74 //3.每次出錯的時候都要記錄一下錯誤次數與最后一次登錄時間 75 WriteLoginLog(loginId); 76 MessageBox.Show("登錄失敗!"); 77 } 78 } 79 } 80 #endregion 81 } 82 } 83 private void ClearErrorTime(string loginId) 84 { 85 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 86 using (SqlConnection con=new SqlConnection(constr)) 87 { 88 string sql = "Update UserLogin set ErrorTimes=0 where LoginId=@uid and ErrorTimes>=3"; 89 using (SqlCommand cmd=new SqlCommand(sql,con)) 90 { 91 cmd.Parameters.AddWithValue("@uid",loginId); 92 con.Open(); 93 cmd.ExecuteNonQuery(); 94 } 95 } 96 } 97 /// <summary> 98 /// 校驗當前用戶是否被鎖定 99 /// </summary> 100 /// <param name="loginId">把剛才的用戶傳進來</param> 101 /// <returns></returns> 102 private bool IsLocked(string loginId) 103 { 104 //什么時候被鎖定呢?登錄錯誤三次並且被禁止登錄時間在1分鍾內。同時想下sql語句怎么去寫。 105 string constr = "Data Source=HY-PC;Initial CataLog=itcastcn;Integrated Security=True"; 106 using (SqlConnection con=new SqlConnection(constr)) 107 { 108 string sql = "select count(*) from UserLogin where ErrorTimes>=3 and datediff(minute,LastLogintime,getdate())<1 and LoginId=@uid"; 109 //另外,復習下using。 110 //釋放之后再return。 111 using (SqlCommand cmd=new SqlCommand(sql,con)) 112 { 113 cmd.Parameters.AddWithValue("@uid",loginId); 114 con.Open(); 115 //小細節:這需不需要提前判斷下是不是空值?答:不用count(*)是個聚合函數。聚合函數查不到返回的也是0. 116 int r = Convert.ToInt32(cmd.ExecuteScalar()); 117 return r>0 ?true:false; 118 } 119 } 120 } 121 /// <summary> 122 /// 統計當前用戶的錯誤信息 123 /// </summary> 124 /// <param name="loginId"></param> 125 private void WriteLoginLog(string loginId) 126 { 127 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 128 using (SqlConnection con = new SqlConnection(constr)) 129 { 130 //確定sql語句 131 string sql = "update UserLogin set ErrorTimes=ErrorTimes+1,LastLoginTime=getdate() where loginId=@uid"; 132 //創建sqlcommand對象 133 using (SqlCommand cmd = new SqlCommand(sql, con)) 134 { 135 cmd.Parameters.AddWithValue("@uid", loginId); 136 con.Open(); 137 cmd.ExecuteNonQuery(); 138 } 139 } 140 } 141 } 142 }
接下來我們完成這兩個需求:
數據導入:從文本文件導入用戶信息。
數據導出:將用戶信息導出到文本文件。
先看下通過設計器導出數據庫中的一張表
十二、將數據庫中的表導出一
十三、將數據庫中的表導出二
十四、將數據庫中的表導出三
十五、將數據庫中的表導出四
十六、將數據庫中的表導出五
十七、將數據庫中的表導出六
十八、將數據庫中的表導出七
十九、將數據庫中的表導出八
二十、將數據庫中的表導出九
二十一、導出的txt文件
接下來我們完成這兩個需求:
數據導出:將用戶信息導出到文本文件。
二十二、畫好需要的界面
二十三、在輸出窗口進行調試
二十四、數據導出的代碼
數據導出的代碼插入位置:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Data.SqlClient; 10 using System.IO; 11 12 namespace _02數據導入導出到文本文件 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 21 private void button1_Click(object sender, EventArgs e) 22 { 23 //1.讀取文件 24 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 25 using (SqlConnection con=new SqlConnection(constr)) 26 { 27 //導出所有數據 28 string sql = "select*from TblClass"; 29 using (SqlCommand cmd=new SqlCommand(sql,con)) 30 { 31 //執行 32 con.Open(); 33 using (SqlDataReader reader=cmd.ExecuteReader()) 34 { 35 //判斷是否查詢出數據 36 if (reader.HasRows) 37 { 38 //2.將數據導出 39 using (StreamWriter sw=new StreamWriter(@"tblClass.txt")) 40 { 41 #region 第一行是列名 42 //4.讀取出來列名 43 //獲取列的個數 44 //reader.FieldCount 45 //根據索引獲取列的名稱 46 //reader.GetName(); 47 //有了上面這兩個提示,我們循環就行了。 48 StringBuilder sbColumns = new StringBuilder(); 49 for (int i = 0; i < reader.FieldCount; i++) 50 { 51 sbColumns.Append(reader.GetName(i)+","); 52 } 53 //把最后多的逗號去掉 54 sbColumns.Remove(sbColumns.Length-1,1); 55 //再寫到文件里面 56 sw.WriteLine(sbColumns.ToString()); 57 #endregion 58 while (reader.Read()) 59 { 60 //取每列 61 int id = reader.GetInt32(0); 62 string clsName = reader.GetString(1); 63 string clsDesc = reader.GetString(2); 64 //調試下,看能不能輸出 65 //Console.WriteLine("{0},{1},{2}",id,clsName,clsDesc); 66 //3.每循環一次,寫入一行 67 sw.WriteLine(string.Format("{0},{1},{2}", id, clsName, clsDesc)); 68 } 69 } 70 //最后提示一下用戶 71 MessageBox.Show("導出成功!"); 72 } 73 else 74 { 75 MessageBox.Show("沒有導出任何數據!"); 76 } 77 } 78 } 79 } 80 } 81 } 82 }
我們發現剛才我們導出的文件沒有空值,那么遇到空值的時候怎么辦呢?大家想下怎么處理?
好,現在思考下怎么導入呢?先讀取文本文件,然后導入就行了。
讀取的細節:不用讀取列名和自動編號. 用split按照逗號,之后進行插入.
數據導入:從文本文件導入用戶信息。
二十五、讀取文本文件測試
二十六、為什么會在插入完一條數據之后報錯
二十七、從文本文件導入用戶信息的代碼
從文本文件導入用戶信息的代碼插入位置:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Data.SqlClient; 10 using System.IO; 11 12 namespace _02數據導入導出到文本文件 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 /// <summary> 21 /// 將數據導出 22 /// </summary> 23 /// <param name="sender"></param> 24 /// <param name="e"></param> 25 private void button1_Click(object sender, EventArgs e) 26 { 27 //1.讀取文件 28 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 29 using (SqlConnection con=new SqlConnection(constr)) 30 { 31 //導出所有數據 32 string sql = "select*from TblClass"; 33 using (SqlCommand cmd=new SqlCommand(sql,con)) 34 { 35 //執行 36 con.Open(); 37 using (SqlDataReader reader=cmd.ExecuteReader()) 38 { 39 //判斷是否查詢出數據 40 if (reader.HasRows) 41 { 42 //2.將數據導出 43 using (StreamWriter sw=new StreamWriter(@"tblClass.txt")) 44 { 45 #region 第一行是列名 46 //4.讀取出來列名 47 //獲取列的個數 48 //reader.FieldCount 49 //根據索引獲取列的名稱 50 //reader.GetName(); 51 //有了上面這兩個提示,我們循環就行了。 52 StringBuilder sbColumns = new StringBuilder(); 53 for (int i = 0; i < reader.FieldCount; i++) 54 { 55 sbColumns.Append(reader.GetName(i)+","); 56 } 57 //把最后多的逗號去掉 58 sbColumns.Remove(sbColumns.Length-1,1); 59 //再寫到文件里面 60 sw.WriteLine(sbColumns.ToString()); 61 #endregion 62 while (reader.Read()) 63 { 64 //取每列 65 int id = reader.GetInt32(0); 66 string clsName = reader.GetString(1); 67 string clsDesc = reader.GetString(2); 68 //調試下,看能不能輸出 69 //Console.WriteLine("{0},{1},{2}",id,clsName,clsDesc); 70 //3.每循環一次,寫入一行 71 sw.WriteLine(string.Format("{0},{1},{2}", id, clsName, clsDesc)); 72 } 73 } 74 //最后提示一下用戶 75 MessageBox.Show("導出成功!"); 76 } 77 else 78 { 79 MessageBox.Show("沒有導出任何數據!"); 80 } 81 } 82 } 83 } 84 } 85 /// <summary> 86 /// 將數據導入 87 /// </summary> 88 /// <param name="sender"></param> 89 /// <param name="e"></param> 90 private void button2_Click(object sender, EventArgs e) 91 { 92 //1.讀取文本文件中的數據 93 using (StreamReader sr=new StreamReader("TblClass.txt")) 94 { 95 //跳過第一行 96 sr.ReadLine(); 97 //2.插入數據庫 98 string constr = "Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"; 99 //連接對象 100 using (SqlConnection con=new SqlConnection(constr)) 101 { 102 string sql = "insert into TblClass(tClassName,tClassDesc) values(@clsName,@clsDesc)"; 103 using (SqlCommand cmd=new SqlCommand(sql,con)) 104 { 105 //3.先加好參數 106 cmd.Parameters.Add(new SqlParameter("@clsName",SqlDbType.VarChar)); 107 cmd.Parameters.Add(new SqlParameter("@clsDesc", SqlDbType.VarChar)); 108 //打開,放到最外面 109 con.Open(); 110 //考慮編碼問題,剛才我們導出的時候是utf-8現在也是utf-8,不會亂碼。 111 //讀取每一行 112 while (!sr.EndOfStream) 113 { 114 string line = sr.ReadLine(); 115 //判斷分割一下 116 if (!string.IsNullOrEmpty(line)) 117 { 118 string[] columnData = line.Split(','); 119 //添加參數,每次添加的參數不一樣 120 //報錯的原因是,當第二次插入的時候,參數重名了。兩種解決辦法,一種是傳完個參數清空下參數。第二種是在循環外面加好參數。 121 //cmd.Parameters.AddWithValue("@clsName",columnData[1]); 122 //cmd.Parameters.AddWithValue("@clsDesc",columnData[2]); 123 124 //在里面修改每個參數的值就行了。 125 cmd.Parameters["@clsName"].Value = columnData[1]; 126 cmd.Parameters["@clsDesc"].Value = columnData[2]; 127 //執行 128 cmd.ExecuteNonQuery(); 129 #region 讀取文本文件測試 130 //打印一下,看能不能輸出來 131 //Console.WriteLine("{0}-{1}-{2}",columnData[0],columnData[1],columnData[2]); 132 #endregion 133 //cmd.Parameters.Clear(); 134 } 135 } 136 MessageBox.Show("導入成功!"); 137 } 138 } 139 } 140 } 141 } 142 }
接下來我們做下省市聯動功能:
二十八、畫好省市界面
要加載省,我們發現有可能在A數據庫里面,也有也能在B數據庫里面。數據庫連接字符串總在變,以前我們是寫死在程序里面不好,我們能不能把連接字符串放在配置文件里面?接下來我們就用配置文件來做。
二十九、添加配置文件
三十、寫好配置文件
三十一、連接字符串添加引用
三十二、怎么把id也加進來
寫個類可以解決這個問題,把這兩個參數賦給這個屬性,然后把這個對象加進來。下面我們照着這個思路寫一下。
三十三、將兩個值封裝成一個類
三十四、解決類里面出現的問題
思考:在界面上單擊按鈕,把id打印出來。
三十五、查詢數據加載省數據代碼
省市聯動查詢數據加載數據代碼插入位置:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Configuration; 10 using System.Data.SqlClient; 11 12 namespace _03省市聯動 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 21 private void Form1_Load(object sender, EventArgs e) 22 { 23 //1.窗體加載的時候將省份信息加載到第一個combobox中。 24 //寫個方法 25 LoadProvinceData(); 26 } 27 28 private void LoadProvinceData() 29 { 30 //創建連接字符串 31 string constr=ConfigurationManager.ConnectionStrings["sql"].ConnectionString; 32 using (SqlConnection con=new SqlConnection(constr)) 33 { 34 //建議一般寫sql語句的時候,在select語句中,用到哪列寫哪列,不要動不動 就寫*。 35 string sql = "select AreaId,AreaName from TblArea where AreaPid=0"; 36 using (SqlCommand cmd=new SqlCommand(sql,con)) 37 { 38 con.Open(); 39 using (SqlDataReader reader = cmd.ExecuteReader()) 40 { 41 if (reader.HasRows) 42 { 43 while (reader.Read()) 44 { 45 //這的第0列,取決於我們查詢的順序。 46 int id = reader.GetInt32(0); 47 string name = reader.GetString(1); 48 //查詢出來之后往里面加 49 //把兩個值封裝成一個類,然后傳進去。 50 Area area = new Area(id, name); 51 cboProvince.Items.Add(area); 52 } 53 } 54 } 55 } 56 } 57 } 58 } 59 }
三十六、小細節
接下來寫代碼點按鈕獲取選中項
三十七、獲取當前選中項的id和省名稱
三十八、獲取當前選中項的id和省名稱的代碼
下面我們做當選中省份的時候,對應顯示出城市的列表。想下,在什么事件里面做這個東西呢?
三十九、屬性改變時發生的事件
四十、清空加載項
四十一、根據父id查詢城市並加載代碼
省市聯動演示
配置文件每次需要跟着拷走么?是的,沒有配置文件,會提示找不到配置文件。
四十二、修改配置文件
如果換成了web是web.config文件,咱們這是exe.config文件。
接下來我們看這么一個案例:
四十三、資料管理器升級案例
先看下數據庫中的兩個表:
四十四、兩張表
表一是主鍵表,表二是外鍵表。
四十五、資料管理器的界面
第一步:當窗體加載的時候,把文章列別加載到左邊的treeview中。
四十六、加載類別-1下的節點代碼
四十七、加載類別下的子節點的代碼
好,上面的代碼對於初學者來講可能比較的難理解,下面我把上面做的功能單拿出來再做一遍。
四十八、存儲數據的類
四十九、遞歸加載子節點
下面我們做下,選中某個類別把文章加載到右上方。下面顯示文章的內容。
首先給節點注冊一個鼠標雙擊事件:
先找到雙擊事件,再去判斷是軟件開發那個節點還是C#、Java、Php節點?
五十、節點的鼠標雙擊事件
五十一、存數文章信息的類
五十二、雙擊子節點將文章顯示到listbox的代碼
最后我們做下顯示標題對應的文章
五十三、找到相應的事件,一般默認的是最常用的
五十四、顯示標題對應的文章的代碼
五十五、更新數據內容的sql語句
五十六、資料管理器部分功能演示
作者近期文章列表:
C#基礎教程(完全免費,獻給代碼愛好者的最好禮物。注:本作者分享自己精心整理的C#基礎教程,無任何商業目的。 希望與更多的代碼愛好者交流心得,也請高手多多指點!!!) |
|
三層 | 三層(一) |
三層相關案例(及常見的錯誤) | |
三層實例(內涵Sql CRUD) | |
SQL數據庫 ADO.net | 數據庫的應用圖解一 |
數據庫的應用詳解二 | |
ADO.NET(內涵效率問題) | |
面向過程,面向對象中高級 | 面向過程,面向對象的深入理解一 |
面向過程,面向對象的深入理解二 | |
面向對象的深入理解三 | |
winform基礎 | Winform基礎 |
winform中常用的控件 | |
面向過程 | 三種循環的比較 |
C#中的方法(上) | |
我們常見的數組 | |
面向對象 | 思想的轉變 |
C#中超級好用的類 | |
C#中析構函數和命名空間的妙用 | |
C#中超級好用的字符串 | |
C#中如何快速處理字符串 | |
值類型和引用類型及其它 | |
ArrayList和HashTable妙用一 | |
ArrayList和HashTable妙用二 | |
文件管理File類 | |
多態 | |
C#中其它一些問題的小節 | |
GDI+ | 這些年我收集的GDI+代碼 |
這些年我收集的GDI+代碼2 | |
HTML概述以及CSS | 你不能忽視的HTML語言 |
你不能忽視的HTML語言2精編篇 | |
你不能忽視的HTML語言3 | |
CSS基本相關內容--中秋特別奉獻 | |
CSS基本相關內容2 | |
JavaScript基礎 | JavaScript基礎一 |
jQuery | jQuery(內涵: jquery選擇器) |