2018/6/4~2018/6/8 周記
一轉眼一周時間已經過去,這一周的任務是做一個實時更新的窗體運用,項目的要求有如下三點:
1、界面上窗口號不能寫死,要可配置的。
2、設置一個定時器,每隔10秒更新數據。
3、由於有五個窗口,所以要使用五個DataGridView控鍵,但是更新數據時要求只能訪問一次數據庫,以此來提高性能。
這個項目邏輯很簡單,可以說沒有邏輯,就是去數據庫取到數據然後定時更新到界面上,本來想著給個Demo的話,馬上就能照著Demo寫出來,但是主管說這次不給Demo,要我自己寫出來,剛聽的時候還有點心裏沒底。畢竟這個項目是要拿出去用的,所以有點慌。後來主管又說他已經做好了,這個就相當於給我練手用的,所以必須用三層來寫。一聽已經做完,只是拿來練手的,心理壓力馬上就小了好多好多。而且不懂的還可以問主管。
首先第一個,界面上窗口號不能寫死,要可配置的。實現這個很簡單,對比將數據庫信息存放在配置文件裏面,我也直接將窗口號信息直接寫在配置文件裏面,將數據讀出來並賦值給lable就行了。實現代碼如下所示:
lblRoomName1.Text = ConfigurationManager.AppSettings["0001"]; lblRoomName2.Text = ConfigurationManager.AppSettings["0002"]; lblRoomName3.Text = ConfigurationManager.AppSettings["View Code0003"]; lblRoomName4.Text = ConfigurationManager.AppSettings["0004"]; lblRoomName5.Text = ConfigurationManager.AppSettings["0005"];
後面主管說要我通過數據庫表裏的數據將值賦值給lable,雖然取到需要的表,表裏面的數據也有,但是不知道如何將表數據準確賦值給lable,主管實際操作一波,使用DataView來實現,因為DataView裏面有可以篩選表數據的方法RowFilter(),DataView就是視圖的意思,可以虛擬出一張表並獲取真實表的數據,和SQL裏面視圖一樣的道理,對DataView操作就是對表進行操作。代碼如下:
//通過讀取數據庫數據更新科室名稱 DataTable dt = bllXtRoom.GetList(); //創建一個視圖,虛擬表數據 DataView dv = dt.DefaultView; //通過視圖篩選符合條件的數據 dv.RowFilter = "RoomCode =‘001‘ "; //賦值 lblRoomName1.Text = dv[0][1].ToString(); dv.RowFilter = "RoomCode =‘002‘ "; lblRoomName2.Text = dv[0][1].ToString(); dv.RowFilter = "RoomCode =‘003‘ "; lblRoomName3.Text = dv[0][1].ToString(); dv.RowFilter = "RoomCode =‘004‘ "; lblRoomName4.Text = dv[0][1].ToString(); dv.RowFilter = "RoomCode =‘005‘ "; lblRoomName5.Text = dv[0][1].ToString();View Code
將表數據根據條件分別填入五個DataGridView裏面。我的做法就是寫五條數據庫語言,分別查出所需要的數據,然後分別填入DataGridView裏面(後面要一次性跟新整個界面數據時,這樣取數據是不行的!每跟新一次數據就要訪問五次數據庫!)數據填入DataGriView裏面並不美觀,其中最重要的是數據在DataGridView裏面自適應列寬。這樣數據看著才會比較整齊!因為背景圖片已經給出來了,所以每個DataGridView的大小已經定下來了。DataGridView裏面每一列的寬度就要自適應,不然很影響美觀的。自適應代碼如下所示:
public void SetWidth(DataGridView data) { int width = 0; //對於DataGridView的每一個列都調整 for (int i = 0; i < data.Columns.Count; i++) { //將每一列都調整為自動適應模式 data.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells); //記錄整個DataGridView的寬度 width += data.Columns[i].Width; } //判斷調整後的寬度與原來設定的寬度的關系,如果是調整後的寬度大於原來設定的寬度, //則將DataGridView的列自動調整模式設置為顯示的列即可, //如果是小於原來設定的寬度,將模式改為填充。 if (width > data.Size.Width) { data.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells; } else { data.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; } //凍結某列 從左開始 0,1,2 data.Columns[1].Frozen = true; }View Code
數據填入DataGridView後就是定時更新的問題了,定時更新有兩個方法,一個是寫一個線程,通過線程定時來定時訪問數據庫實現更新數據,第二個是使用定時器,寫一個定時器來定時執行。簡單線程很簡單,只需要實例化一個Thread,然後調star()方法。代碼如下:
private void UpData() { while (true) { //運行時間 Thread.Sleep(10000); DataTable dt = bllQueueList.GetTable(); // dataGridView4.DataSource = dt4; SetDT(dt); //qubiaotou(dataGridView4); //SetWidth(dataGridView4); } } //使用線程調用方法 //在Load方法裏面執行 Thread th = new Thread(UpData); th.Start();View Code
定時器的話也很簡單,拉一個定時器控鍵,設置Enabled=true,Interval=1000;//執行時間間隔,單位為毫秒
//方法二:使用定時器 System.Timers.Timer timer = new System.Timers.Timer(); timer.Enabled = true; timer.Interval = 10000;//執行間隔時間,單位為毫秒 timer.Start(); timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer1_Elapsed); private void Timer1_Elapsed(object sender, ElapsedEventArgs e) { DataTable dt = bllQueueList.GetTable(); SetDT(dt); }View Code
但是這樣寫出來的定時器還是會報錯,錯誤信息是“線程間操作無效: 從不是創建控件“”的線程訪問它”。解決方法是通過寫一個委托來執行
private delegate void SetDtCallback(DataTable dt); private void SetDT(DataTable dt) { // InvokeRequired需要比較調用線程ID和創建線程ID // 如果它們不相同則返回true if (this.InvokeRequired) { SetDtCallback d = new SetDtCallback(SetDT); this.Invoke(d, new object[] { dt }); } else { // dataGridView4.DataSource = dt; ShowData(); } }View Code
雖然功能實現了,但是還是不懂什麽意思。。
將一個表裏面數據通過條件分成多個表:
DataTable dt = bllQueueList.GetTable(); DataView dataview = dt.DefaultView; DataTable dt1 = new DataTable(); //通過視圖篩選符合條件的數據 dataview.RowFilter = "Window=‘1001‘"; //創建一個新的表,該表只顯示"Queueno","Name"這兩個列的值並把表數據賦值給表dtTemporary, //true:不顯示相同的數據,false:顯示全部數據 dt1 = dataview.ToTable(true, "Queueno", "Name"); dataGridView1.DataSource = dt1; qubiaotou(dataGridView1); SetWidth(dataGridView1);View Code
還有一些細節方面的問題。。用戶體驗真的很重要!!!
操作數據庫時,往表裏添加數據時報將截斷字符串或二進制數據。的錯誤。原因是數據的長度不符合才造成的。只要把數據長度增加就行了!!
2018/6/4~2018/6/8 周記