1. 程式人生 > >2018/6/4~2018/6/8 周記

2018/6/4~2018/6/8 周記

als val lap 如果 每一個 信息 pset 調整 IE

一轉眼一周時間已經過去,這一周的任務是做一個實時更新的窗體運用,項目的要求有如下三點:

1、界面上窗口號不能寫死,要可配置的。

2、設置一個定時器,每隔10秒更新數據。

3、由於有五個窗口,所以要使用五個DataGridView控鍵,但是更新數據時要求只能訪問一次數據庫,以此來提高性能。

這個項目邏輯很簡單,可以說沒有邏輯,就是去數據庫取到數據然後定時更新到界面上,本來想著給個Demo的話,馬上就能照著Demo寫出來,但是主管說這次不給Demo,要我自己寫出來,剛聽的時候還有點心裏沒底。畢竟這個項目是要拿出去用的,所以有點慌。後來主管又說他已經做好了,這個就相當於給我練手用的,所以必須用三層來寫。一聽已經做完,只是拿來練手的,心理壓力馬上就小了好多好多。而且不懂的還可以問主管。

首先第一個,界面上窗口號不能寫死,要可配置的。實現這個很簡單,對比將數據庫信息存放在配置文件裏面,我也直接將窗口號信息直接寫在配置文件裏面,將數據讀出來並賦值給lable就行了。實現代碼如下所示:

技術分享圖片
            lblRoomName1.Text = ConfigurationManager.AppSettings["0001"];
            lblRoomName2.Text = ConfigurationManager.AppSettings["0002"];
            lblRoomName3.Text = ConfigurationManager.AppSettings["
0003"]; lblRoomName4.Text = ConfigurationManager.AppSettings["0004"]; lblRoomName5.Text = ConfigurationManager.AppSettings["0005"];
View Code

後面主管說要我通過數據庫表裏的數據將值賦值給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 周記