国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

Visual Basic .NET中多 Windows 窗體的同步

2024-07-10 13:01:11
字體:
來源:轉載
供稿:網友
國內最大的酷站演示中心!
這是一個有趣的問題。我保證某些聰明的編程好手會建議我使用委托。在這種事情發生之前,讓我們 先探究一下這個問題的幾種解決方案。
  假定我有兩個窗體,每個窗體都有兩個 textbox 控件:txt1stdata 和 txt2nddata。我怎樣才能保持這兩個窗體中的控件同步呢?對于我們討論的問題來說,有兩個或十個窗體都不重要,問題是相同的。
  第一個辦法相對簡單。事實上,它甚至比我們直接使用委托更為簡單,我想委托有時會給人用牛刀殺雞的感覺。首先,我建立一個類它包含我希望與應用程序中的所有窗體共享的屬性(參見 figure 1)。例如,mydata 和 moredata 擁有每個窗體都能顯示的數據。我將很快回到這個類來。
  第二,正如我早先提到的我用相同的控件(txt1stdata 和 txt2nddata)建立了兩個窗體。你可以參考 figure 2 的布局。兩個窗體都有完全相同的數據,并且我將很快解釋為什么。


figure 2 窗體布局

下面,我建立一個名為 modgeneral 的模塊并加入下面一行代碼:

friend datastuff as dataclass
  這一行代碼為我的新類 dataclass 創建了一個友元變量,使你可以完全訪問程序集,對這個簡單例子來說,也就是指完整的應用程序。然后我添加了下面的代碼到 form1 的 load 事件:
datastuff = new dataclass me.txt1stdata.databindings.add("text", datastuff, "mydata") me.txt2nddata.databindings.add("text", datastuff, "moredata")
  第一行建立一個 dataclass 新實例。下面兩行代碼將數據綁定到 textbox 控件。對這個窗體而言,就這么些操作!
  現在,你怎樣讓它們與 form2 和其它窗體上的數據同步呢?將下面兩行加入到 form 2 的窗體load 事件中去:
me.txt1stdata.databindings.add("text",datastuff, "mydata") me.txt2nddata.databindings.add("text",datastuff, "moredata")
  這個方法容易確保所有窗體上的幾乎任何類型的數據處于同步狀態。你可以簡單地將控件綁定到某個類的相同實例上,這就行了。
  現在來看另一個方法。我創建了一個名為 frmbase 的新窗體。這時我在上面放一個 textbox (txtnextdata)和 label。我想 讓應用程序的每個窗體都共享這個 textbox 和 label,并且我希望它們互相之間保持同步,于是我重建這個工程。通過從新的 frmbase 中的繼承 ,我創建了 form1 和form2,因此它們繼承了所有新的控件。但是我怎樣能保持這些控件同步呢?這時必須寫一點代碼去達到此效果,這些代碼在單個的類中,通過簡單地調用一個函數而被復用。
  figure 3 中的代碼展示了這個稱為 modgeneral 模塊。它的第一個任務是定義兩個變量:myforms 和 localnextdata。myforms 是一個 集合,它將包含我想要同步的窗體列表。localnextdata變量將儲存所有我想要在窗體里顯示的數據。注意這些變量可以駐留于某個類中而不是某個模塊里。
  addform 過程來自 modgeneral,帶一個窗體實例參數,并將其加入 myforms 集合中。我將在updatecontrolsnextdata 過程中使用這個 集合以決定哪些窗體要更新。addform 也調用updatecontrolsnextdata 來確保一個新窗體是用正確的數據更新的。
  modgeneral 中的其它代碼是 nextdata 屬性。這些屬性的 set 存取器更新 localnextdata 并也調用 updatecontrolsnextdata 去同步所有窗體。這時所有我需要做的是 在想要改變它時設置 nextdata,通過調用 updatecontrolsnextdata,所有窗體將被更新。
  第三個方法是定制鏈接,它是第二個方法的精華版。我創建它以獲得多一些窗體控件處理的靈活性。例如,我只想跟蹤和處理某些窗體,這些窗體包含必須同步的控件。這個方法 還可以讓我自己定義擬同步的控件,并且只處理這些控件的窗體。
  我為這個辦法添加了另一個模塊 (modgeneralv2),如 figure 4 所示。該模塊包括一個集合(myformstoupdate),其中包含所有我想要同步的窗體。這個模塊 還有一個新的數組 (controlstoupdate),它提供一個我要同步的控件列表。該數組的定義如下:
private controlstoupdate() as string = _ {"txtcustomer", "txtaddress", "txtname"}
  這個模塊里有一個新的替代 addform 的改良版本,叫做 addformtoupdate。該方法工作方式與addform 類似,但現在它只添加擁有一個或多 個 controlstoupdate 數組中控件的窗體,因此只有那些含有特定控件的窗體在更新集合中。它使我可以從每個窗體中調用該函數。如果我決定以后添加某個特定的控件,它將會被自動添加到窗體列表。我只需對窗體代碼做細小的改動便可以實現。
  這個模塊還包含 updatecontrolsonallforms 過程,它執行更新。代替上一個方法中使用的一個應用程序級變量,我現在使用主窗體的概念。因此我可以將那個窗體的值拷貝到集合中的所有其它窗體。updatecontrolsonallforms 其實就是一組簡單的 for...nexts 循環遍歷某個窗體的所有控件,找到需要更新的控體,并更新它們。
  為了在我的窗體中實現這一功能,我在窗體的 load 事件中加入了這一行代碼:
addformtoupdate(me)
  另外一種可選的方法,我可以將它添加到構造函數。這一行代碼將把當前窗體實例添加到集合進行更新。
  現在讓我們考察單個事件過程:
private sub txt_leave(byval sender as object, _ byval e as system.eventargs) handles txtaddress.leave, _ txtcustomer.leave, txtname.leave updatecontrolsonallforms(me) end sub
  這段代碼將我想要同步的所有三個控件 (txtaddress、txtcustomer 和 txtname)的 leave 事件捆綁到一個事件句柄上。這時我可以添加一行代碼 來調用 updatecontrolsonallforms。me 被傳遞到該過程調用,從而導致其它窗體與該窗體同步。
  現在我有三個版本的代碼,它們都可以同步窗體中控件,因此我可以進行選擇。我可能已經使用了自定義事件,在 dataclass 中定義某個事件并讓每個窗體都預訂它。 然后當這個事件觸發時,這些窗體可以從每個事件句柄中獲取新的數據并設置適當的控件。但是這樣做所需的代碼量一點也不會比第一種方法中將控件綁定到類來得少。我可以構建單個實現更新的過程,并將該過程放到某個模塊中。我需要向該過程傳遞窗體實例來實現更新。我可以用類中的某個事件句柄觸發這個過程。此過程看起來就像這樣:
sub updatecontrols(byval thisform as frmbase) with thisform .txtnextdata.text = localnextdata end with end sub
  thisform 參數被定義為 frmbase 類型,以便它可以訪問 intellisense 并獲得窗體的自定義屬性。簡單地將它寫成 form 將無法顯示 frmbase 中的屬性及其派生窗體。
  另一選擇是使用委托。當然,委托可以讓我將委托調用重定向到每個窗體的方法上。如果我使用多播機制,那么我可以讓每個窗體都處理該事件并更新相應的控件。用委托建立這樣的功能聽起來確實簡單,但 對我來說它更麻煩且沒有實踐價值。此外,與第三個方法中的 for...next 循環嵌套相比,這個代碼并不難理解。畢竟,一個應用程序花費最大的部分仍然是它的維護。

將你的問題以及對 ken 的評論發送到 [email protected]

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桃源县| 华容县| 张家界市| 东乌珠穆沁旗| 马山县| 宁蒗| 绍兴市| 息烽县| 房产| 牟定县| 运城市| 镇康县| 梨树县| 兴隆县| 华亭县| 静海县| 红桥区| 玉龙| 辛集市| 恩平市| 西乡县| 恭城| 蕉岭县| 浙江省| 阳春市| 清镇市| 德州市| 诸城市| 千阳县| 客服| 绥江县| 旬邑县| 日土县| 沛县| 沙坪坝区| 靖江市| 镇平县| 乐昌市| 桃园县| 德州市| 新干县|