熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

在VB.NET中怎麼實現多窗體同步

2013-11-13 09:47:32  來源: .NET編程 
這是一個有趣的問題我保證某些聰明的編程好手會建議我使用委托在這種事情發生之前讓我們 先探究一下這個問題的幾種解決方案     

  假定我有兩個窗體每個窗體都有兩個 textbox 控件txtstData 和 txtndData我怎樣才能保持這兩個窗體中的控件同步呢?對於我們討論的問題來說有兩個或十個窗體都不重要問題是相同的

  第一個辦法相對簡單事實上它甚至比我們直接使用委托更為簡單我想委托有時會給人用牛刀殺雞的感覺首先我建立一個類它包含我希望與應用程序中的所有窗體共享的屬性(參見 Figure )例如MyData 和 MoreData 擁有每個窗體都能顯示的數據我將很快回到這個類來

  第二正如我早先提到的我用相同的控件(txtstData 和 txtndData)建立了兩個窗體你可以參考 Figure 的布局兩個窗體都有完全相同的數據並且我將很快解釋為什麼  

  
在VB.NET中怎麼實現多窗體同步
  下面我建立一個名為 modGeneral 的模塊並加入下面一行代碼

  Friend DataStuff As DataClass

  這一行代碼為我的新類 DataClass 創建了一個友元變量使你可以完全訪問程序集對這個簡單例子來說也就是指完整的應用程序然後我添加了下面的代碼到 Form 的 Load 事件

  DataStuff = New DataClass

  MetxtstDataDataBindingsAdd(Text DataStuff MyData)

  MetxtndDataDataBindingsAdd(Text DataStuff MoreData)

  第一行建立一個 DataClass 新實例下面兩行代碼將數據綁定到 textbox 控件對這個窗體而言就這麼些操作!

  現在你怎樣讓它們與 Form 和其它窗體上的數據同步呢?將下面兩行加入到 Form 的窗體load 事件中去

  MetxtstDataDataBindingsAdd(TextDataStuff MyData)

  MetxtndDataDataBindingsAdd(TextDataStuff Moredata)

  這個方法容易確保所有窗體上的幾乎任何類型的數據處於同步狀態你可以簡單地將控件綁定到某個類的相同實例上這就行了

  現在來看另一個方法我創建了一個名為 frmBase 的新窗體這時我在上面放一個 textbox (txtNextData)和 label我想 讓應用程序的每個窗體都共享這個 textbox 和 label並且我希望它們互相之間保持同步於是我重建這個工程通過從新的 frmBase 中的繼承 我創建了 Form 和Form因此它們繼承了所有新的控件但是我怎樣能保持這些控件同步呢?這時必須寫一點代碼去達到此效果這些代碼在單個的類中通過簡單地調用一個函數而被復用

  Figure 中的代碼展示了這個稱為 modGeneral 模塊它的第一個任務是定義兩個變量MyForms 和 localNextDataMyForms 是一個 集合它將包含我想要同步的窗體列表localNextData變量將儲存所有我想要在窗體裡顯示的數據注意這些變量可以駐留於某個類中而不是某個模塊裡

  AddForm 過程來自 modGeneral帶一個窗體實例參數並將其加入 MyForms 集合中我將在UpdateControlsNextData 過程中使用這個 集合以決定哪些窗體要更新AddForm 也調用UpdateControlsNextData 來確保一個新窗體是用正確的數據更新的

  modGeneral 中的其它代碼是 NextData 屬性這些屬性的 set 存取器更新 localNextData 並也調用 UpdateControlsNextData 去同步所有窗體這時所有我需要做的是 在想要改變它時設置 NextData通過調用 UpdateControlsNextData所有窗體將被更新  第三個方法是定制鏈接它是第二個方法的精華版我創建它以獲得多一些窗體控件處理的靈活性例如我只想跟蹤和處理某些窗體這些窗體包含必須同步的控件這個方法 還可以讓我自己定義擬同步的控件並且只處理這些控件的窗體

  我為這個辦法添加了另一個模塊 (modGeneralv)如 Figure 所示該模塊包括一個集合(MyFormsToUpdate)其中包含所有我想要同步的窗體這個模塊 還有一個新的數組 (ControlsToUpdate)它提供一個我要同步的控件列表該數組的定義如下

  Private ControlsToUpdate() As String = {txtCustomer txtAddress txtName}

  這個模塊裡有一個新的替代 AddForm 的改良版本叫做 AddFormToUpdate該方法工作方式與AddForm 類似但現在它只添加擁有一個或多 個 ControlsToUpdate 數組中控件的窗體因此只有那些含有特定控件的窗體在更新集合中它使我可以從每個窗體中調用該函數如果我決定以後添加某個特定的控件它將會被自動添加到窗體列表我只需對窗體代碼做細小的改動便可以實現

  這個模塊還包含 UpdateControlsOnAllForms 過程它執行更新代替上一個方法中使用的一個應用程序級變量我現在使用主窗體的概念因此我可以將那個窗體的值拷貝到集合中的所有其它窗體UpdateControlsOnAllForms 其實就是一組簡單的 ForNexts 循環遍歷某個窗體的所有控件找到需要更新的控體並更新它們

  為了在我的窗體中實現這一功能我在窗體的 Load 事件中加入了這一行代碼 AddFormToUpdate(Me)

  另外一種可選的方法我可以將它添加到構造函數這一行代碼將把當前窗體實例添加到集合進行更新   現在讓我們考察單個事件過程

  Private Sub txt_Leave(ByVal sender As Object _

  ByVal e As SystemEventArgs) Handles txtAddressLeave _

  txtCustomerLeave txtNameLeave

  UpdateControlsOnAllForms(Me)

  End Sub

  這段代碼將我想要同步的所有三個控件 (txtAddresstxtCustomer 和 txtName)的 Leave 事件捆綁到一個事件句柄上這時我可以添加一行代碼 來調用 UpdateControlsOnAllFormsMe 被傳遞到該過程調用從而導致其它窗體與該窗體同步

  現在我有三個版本的代碼它們都可以同步窗體中控件因此我可以進行選擇我可能已經使用了自定義事件在 DataClass 中定義某個事件並讓每個窗體都預訂它 然後當這個事件觸發時這些窗體可以從每個事件句柄中獲取新的數據並設置適當的控件但是這樣做所需的代碼量一點也不會比第一種方法中將控件綁定到類來得少我可以構建單個實現更新的過程並將該過程放到某個模塊中我需要向該過程傳遞窗體實例來實現更新我可以用類中的某個事件句柄觸發這個過程此過程看起來就像這樣

  Sub UpdateControls(ByVal ThisForm As frmBase)

  With ThisForm

  txtNextDataText = localNextData

  End With

  End Sub

  ThisForm 參數被定義為 frmBase 類型以便它可以訪問 IntelliSense 並獲得窗體的自定義屬性簡單地將它寫成 Form 將無法顯示 frmBase 中的屬性及其派生窗體

  另一選擇是使用委托當然委托可以讓我將委托調用重定向到每個窗體的方法上如果我使用多播機制那麼我可以讓每個窗體都處理該事件並更新相應的控件用委托建立這樣的功能聽起來確實簡單但 對我來說它更麻煩且沒有實踐價值此外與第三個方法中的 ForNext 循環嵌套相比這個代碼並不難理解畢竟一個應用程序花費最大的部分仍然是它的維護
From:http://tw.wingwit.com/Article/program/net/201311/11593.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.