知识管理系统Data Solution研发日记之六 窗体设计器
知識管理系統Data Solution已經有五篇文章對它進行介紹,可以通過下面的連接,找到前面的文章
知識管理系統Data Solution研發日記之一 場景設計與需求列出
知識管理系統Data Solution研發日記之二 應用程序系列
知識管理系統Data Solution研發日記之三 文檔解決方案
知識管理系統Data Solution研發日記之四 片段式數據解決方案
知識管理系統Data Solution研發日記之五 網頁下載,轉換,導入
每一篇文章都試圖從一個角度來分析這個系統的目的,設計思路。至于源代碼,并沒有什么特別的難度,問題的關鍵在于思路,找到了合適的解決方案,實現起來就相對容易一些。這篇文章講解窗體設計器的主要內容。
設計器生成的的窗體文件,可以以二種方式保存,一種是源代碼方式,C#,VB.NET代碼的形式,另一種是XML格式,這里采用的是XML格式保存窗體設計格式。如果你對此并不熟悉,請通過查看文章《基于窗體設計器的企業管理軟件開發工具》來了解更多的內容。
在Windows Forms的開發中,BindingSource控件扮演著數據與控件連接的橋梁,而且是雙向的數據綁定。這句話在學習ASP.NET時,一直不得其解,雙向的數據綁定與單向的有什么區別。用直白的話說,雙向的數據綁定,可以讓控件中被用戶修改的數據,重新寫到綁定的數據源中,在窗體的保存功作中,可以保存用戶修改的數據。雙向的數據綁定可以節省大量的數據綁定代碼,想像一下,在剛學編程時,經常寫出這樣的代碼
protected override void OnLoad() {txtUserName.Text=user.UserName;txtEmal.Text=user.Email; }protected override void OnClosing() {user.UserName=txtUserName.Text;user.Emal=txtEmail.Text; }在窗體打開時,需要從數據實體類型中,綁定數據到控件中,在窗體關閉時,再從控件的值寫到數據實體類型中。如果沒有雙向的數據綁定,界面中會大量的重復這樣的代碼。
?
先來看一個,讀取單一個數據表的情況。比如,只讀取采購單PUORDH一個表。在上圖中的窗體設計器中,有兩個FlexDataTable控件,它用來獲取數據源。它的Name就是數據庫中的表名,SQL屬性是讀取數據的SQL語句,比如有一個表是PUORDH(采購單),那么需要為它寫SQL屬性為SELECT * FROM PUORDH。理論上,在知道表名之后,是不需要寫SQL屬性的,因為可以生成默認的SELECT語句,出于效率的考慮,可以簡化對SQL的編寫,比如上面的窗體,它只讀取PUORD的Ref No.和Vendor,這時,如果自動生成的SQL語句還是SELECT * FROM PUORDH,則效率損失很多,其它的不需要的字段也被讀取到內存中。所以,FlextDataTable的SQL屬性,可來用優化SQL性能,當它的值是空時,窗體設計器會自動生成SELECT * FROM PUORDH。
?
再來看一下,讀取主從表的情況。如上圖所示,主表PUORDH,明細表PUORDD,它們的關系存在于數據庫中,是一對多關系。這時,數據綁定的關鍵代碼是這三行
this.bsH.DataSource = this.DataSet; //this.bsD.DataSource=this.DataSet; this.bsD.DataSource =bsH; this.bsD.DataMember = "FK_PUORDD_PUORDH";表頭的數據仍然是DataSet,初試化窗體時,根據FlexDataTable表名和它的SQL屬性,讀取數據到DataSet中。從表的數據如果是DataSet,沒有錯,但是沒有正常顯示出主表與從表的數據關聯數據,它會選出所有的從表數據。所以,后面兩行代碼是綁定從表數據的關鍵。窗體設計器在生成CS源代碼時,則需要生成正確的主從數據關系綁定代碼。
?
在生成主從數據關系方面,XSD是首選的方案,參考下面的調用代碼,它可以生成包含關系的XSD文件
string connectionString = "data source=(local);initial catalog=Emp5;integrated security=SSPI;persist security info=False;packet size=4096"; string destinationFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, xsdName);List<string> tables = new List<string>(); foreach (IComponent comp in host.Container.Components){if (comp is FlexDataTable){tables.Add(comp.Site.Name);}} DatasetGeneratorForm dlgXsd = new DatasetGeneratorForm(connectionString, destinationFile, false, "CS", tables); dlgXsd.GenerateXsdSource();窗體設計器正是從這個生成的XSD文件中獲取到表與表之間的關系,以生成上面提到的主從表的數據綁定代碼。
?
在窗體設計器生成代碼方面,CodeDom是首選的代碼生成技術。這主要歸咎于它可以以一套代碼,同時生成C#,VB.NET兩套代碼,這種靈活性比硬編碼的字符串拼湊,效果要好很多。代碼示例如下
//this.DataAdapter = da; CodeVariableReferenceExpression da = new CodeVariableReferenceExpression("da"); CodePropertyReferenceExpression thisda = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "DataAdapter"); CodeAssignStatement as1 = new CodeAssignStatement(thisda, da); method.Statements.Add(as1);為了寫一個賦值語句,竟然用了四行代碼,而且CodeDom調試時,也不可以看到它生成的目標代碼的模樣。這與調試帶參數的SQL語句的體驗差不多,無法得知最終要發送到服務器的SQL語句的模樣。好在有MSDN和大量的在線資源,可以很容易的獲取到一個C#語句如何用CodeDom表達出來。而且大部分情況是,你寫對了CodeDom語句,感覺對了,它運行時的結果,就是對的。微軟的人真了不起,竟然創造了CodeDom這種威力巨大的代碼生成技術。
?
再來看一下窗體間互操作的代碼,打開一個窗體,可以用這條語句
=Open("PURCHASE") 或是=Open("PURCHASE",this)
帶一個參數的Open方法,會以參數為XML文件名,拼湊成PURCHASE.XML字符串,到系統的指定目錄中查找PURCHASE.XML窗體定義格式文件,讀取并轉化成窗體類型,顯示出來;帶二個參數的Open方法,會在系統指定的目錄中,查找PURCHASE.dll程序集文件,反射它的類型成員,調用并顯示了出來。這里也有個約定,窗體設計器生成的源代碼文件,只包含一個類型定義,然后經過CodeDomProvider編譯,生成窗體的程序集文件。
繼續看窗體設計器設計的窗體,它的另外幾個按鈕的Click事件的寫法
保存按鈕的Click事件的寫法是:=Save();
刪除按鈕的Click事件的寫法是:=Delete(bsH,bsD) ;
創建按鈕的Click事件的寫法是:=New(bsH,bsD);
在這里,完全不需要指定主外鍵,或是表與表之前的關聯關系,所以這些,都由后臺程序自動判斷。這樣做,也沒有效率。讀取數據的操作是把它讀到一個DataSet中,然后依照FlexDataTable表名依次分配與綁定;保存操作會把數據寫回到數據庫中,依照DataSet中數據是否發生改變,這個寫回數據庫的過程,效率很低。當然,大多數的情況,是用來查看數據庫中的數據,而不是編輯數據,依照這個標準,窗體設計器也達到了它的目的。
?
把這幾條技術整合到一起,就完成了窗體設計器的開發。我在思考這些關系時,通常零亂的,不完整的,設計的過程也是代碼演化,思路調整的過程。也許你不知道我這里講的是什么內容,或許你有更好的實現方法,歡迎反饋。
轉載于:https://www.cnblogs.com/JamesLi2015/archive/2011/10/26/2225492.html
總結
以上是生活随笔為你收集整理的知识管理系统Data Solution研发日记之六 窗体设计器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】FPGA+CPU:并行处理大行其道
- 下一篇: win7 右键菜单增加“在此以管理模式运