2010-08-12 38 views
5

免責聲明:在這個問題標籤頁,對話框實際上意味着同樣的事情,對不起。我的藉口:我不確定最終產品應該是什麼樣子 - 一堆單獨的窗戶或一個整體。尋找一個偉大的嚮導實例與WinForms和/或建議regrding設計

我正在尋找改進現有的,難以維護的嚮導與WinForms烘烤。我需要儘量保持外觀和感覺相同,但我需要清理內部邏輯。總共有5個對話框,在一個巨大的方法內,所有這些對話框都會一個接一個地顯示出來(在點擊Next按鈕之後)。來回跳躍的方式是...... 5或6個標籤和GOTO!

現在,這個嚮導是線性的,而不是樹。從任何一個對話框/頁面中,您最多可以訪問另外兩個對話框。不知怎的,雙鏈接列表浮現在腦海。現在有5 * 4 = 20潛在的狀態轉換,而只有2*1 + 3*2 = 8是有效的。我不必使用goto s。他們通常是邪惡的,在這種情況下,他們 - 很難保持這一點......我正在考慮增加另一個第6頁。 goto s之所以在這裏存在的原因很可能是因爲A)時間壓力1.0時,B)這是5年前,所以在當時可用的奇才最好的例子/教程可能不是很好。

現在,嚮導的大部分頁面都會詢問用戶的輸入。隨後的頁面將根據用戶輸入的內容進行渲染。如果用戶在第3頁上說,並且決定將後退按鈕一直設置爲1,並且沒有改變任何內容,並且擊中Next兩次,則該狀態不應該改變。但是,在第x頁上更改內容通常會使第x + 1頁和更多頁面上的內容無效。然而,也有例外,因爲頁面x上的一些或全部設置可能取決於頁面x-1,x-2等,但頁面x + 1,x + 2等不依賴於該x一些x。

我希望事情很清楚。我們試圖通過爲用戶默認一些東西來幫助用戶。事物存儲的方式也不是很好。該對話框具有讀取/寫入屬性,從/到實際控件複製的東西。然後,在主要的方法,有一個「超級存儲」,它擁有每個頁面的存儲。因此,當用戶完成頁面x並接着點擊時,首先將東西從控件複製到本地的存儲中,然後將這些東西保存到超級存儲的相應成員中。

陣列(對話框/存儲區)和索引沒有被使用。對於每個goto目的地(標籤),都有單獨的但類似的「創建&填充」邏輯。當頁面不再被顯示時,對話框會被扔掉(它們不會被丟棄,但每次被顯示時,它們都會被重新創建並重新填充。我不認爲這是必要的,因爲只有單手柄是需要的,並且在顯示和關閉之後,我相信它可以以相同的狀態再次顯示,而不必重新填充控件。如果浪費內存是唯一的問題,我可能會讓事情滑動,但事情不是很維護,所以我也可以解決這一切

我想:

  1. 商店對話框集合中,如數組,但最好DLL,因爲我只能向前移動1或向後移動1,或者只有兩個選項中的一個我列出(第一個和最後一個對話框)。
  2. 實際上,我的標籤/頁面都擴展了一個共同的抽象類(因爲「下一個」,「後退」,「退出」按鈕及其行爲對於所有人都是共同的)。
  3. 每個標籤頁/頁面/對話框(針對此問題的目的相同,對於混淆抱歉)將具有「導體」類可見的只讀屬性。這些屬性將從控件中的值(信息的真正來源)派生而來,有時這些屬性會稍微處理這些值。 「指揮家」有責任抓住這些人並將他們存放起來。當指揮希望用單一方法填充對話框時(我們稱之爲「種子」)。我在這裏遇到了一些困難,因爲每個種子方法的參數都會有所不同。我希望既能利用強大的打字功能,又能保持通用性。我懷疑應該給些什麼。我可以將字典傳遞給每種種子方法,但感覺太Pythonic,就像鴨子打字一樣。如果我搞砸了,我會在運行時間之前不知道。而且,對於任何給定的頁面,字典的打包和解包總是更好。這就是你要進來的地方。
  4. 全球存儲可以是一個巨大的字典。爲了保證所有密鑰的不同,我可以遵守規則,或者在「p1_」到「p5_」之間加上前綴名稱,具體取決於頁面。我相信其他方案也存在。擁有巨大的字典可以在最後得到方便 - 只要正確完成,用戶輸入的順序並不重要。我也可以有一臺狀態機......有點。這也是我在設計中迷失的地方。如果我把東西放在字典中,我將不得不執行很多條件邏輯,例如:如果我在第2頁上,並且做了修改,那麼我通常(可能有例外)需要設置舊的默認值if任何3,4,5頁無效。取決於它變得多醜,它可能不會比現在的基於goto的設計好得多。然而,我認爲我可以做得更好,因爲我可以用一堆委託來實現我的狀態或狀態轉換專用邏輯,其中的句柄存儲在兩個字典中(一個用於下一個,一個用於後面),其中當前狀態是鍵。

正如您所看到的,存在一些挑戰。然而,我很有希望,因爲通過一個好的巫術師設計思考是一個肯定會被重新發明的輪子。也許你可以推薦一個開放源代碼的C#/ mono應用程序,它帶有一個線性但不重要的嚮導,以便我可以查看實現。呃,甚至Java/Swing可能適合我,只要嚮導在本質上是相似的。 WPF對我來說將是另一個挑戰,我不想有2個問題而不是1.

讓我知道你能想到什麼。我應該保留gotos,但儘可能清理其他部分?隨意問的問題。謝謝,

-HG

回答

0

爲什麼不創建一個具有屬性的每一頁每一輸入字段類和跟蹤它們,而用戶點擊通過嚮導,這樣你就可以回跳和在幾頁之間出現,並且仍然保留用戶在他的會話下添加的數據。你甚至可以在這些頁面模型輸入驗證所以當用戶點擊下一個你可以做類似

if(!page1model.IsValid) 
{ 
    List<RuleViolation> ruleViolations = page1model.GetRuleViolations(); 
} 

是,如果我理解你的一些問題。

(保持頁面的跟蹤,你可以在頁面模式實現相同的接口,並創建一個List<IPageModel>或東西和頁面模型添加到它)

0

我投上層建築傳遞到每個頁面的參數因爲它正在顯示。第二個參數是我們到達頁面的方向(Next或Back)。如果是Back,那麼只顯示已經存在的數據。如果是下一個,則使用前一頁中的數據(在上層結構中找到)來顯示當前頁面中的適當數據。如果該頁面首次顯示,該頁面還應該具有該信息。如果是,那麼它應該提供默認數據,如果不是,那麼它可以回收歸因於該頁面的現有數據(假設它們不與前一頁的數據相矛盾)。狀態只是一個數字,在每個頁面後增加或減少。主代碼是一個小的while循環,它只顯示當前狀態的頁面,並在用戶完成頁面時更新狀態。當用戶離開最後一頁,然後退出循環。

如果有可選頁面,那麼主代碼會變得有點複雜,因爲您需要一個邏輯來決定下一頁是什麼(以及之前的所有頁面都是什麼),但其他所有內容仍然相同。

+0

嗯...那種方式每個「頁面」必須知道所有其他人是什麼。我正在考慮在創建任何新的重要信息之後能夠刷新「頁面」,並讓頁面返回所要求的任何重要信息。然後是外部的某種控制器... – 2010-08-23 01:12:46

+0

該頁面處於最佳位置,可以「瞭解」用戶需要在該頁面中看到的內容,並瞭解實現該目的所需的信息。該頁面需要所有需要的信息:-)。沒有理由隱藏頁面中的信息,因爲沒有必要使整個事物過度模塊化。也就是說,除非你想在另一個項目中重用「模塊」。在這個解決方案中,您仍然可以刷新頁面,事實上,每次顯示頁面時都應該刷新。但是,如果你有一個解決方案,那麼就去做吧。 – Dialecticus 2010-08-23 12:33:27

0

創建一個winform,它將託管實現接口的用戶控件。使所有頁面實現此接口的用戶控件,並控制頂級窗體的流程。如果你喜歡這種方法,我可以挖掘一些舊的代碼來提供更多的細節。

+0

這看起來很有希望,是的,我確實需要代碼,然後才能下定決心。即使沒有成功,我也不會投票。我鼓勵他人不要懲罰幫助他人的企圖。 – 2010-09-08 15:29:43

1

我有一些的WinForms嚮導代碼,這是總體架構:

在主嚮導有步驟列表方式列表(中baseWizardStep)..當嚮導主要形式是創建一切可能的措施清單。

還有下一個返回和取消按鈕。

與上面的Alex一樣,擁有一個基類(baseWizard)主窗體,該主窗體包含一個用於當前步驟的用戶控件。 每個嚮導步驟本身都是一個用戶控件(從繼承自UserControl的baseWizardStep繼承) baseWizardStep具有一些內置事件(ArriveAtStep,ValiateStep,LeaveStep等..) 同樣在InitliaseStep子集中,它以主嚮導作爲參數並存儲屬性中的主要嚮導形式的引用。 所有步驟訪問主嚮導以將其數據存儲在屬性/對象/數據集等中。(通常在LeaveStep事件上完成數據的存儲) 這些步驟將數據裝載到其在ArriveAtStep事件中的控件上。

我有時需要在許多向導之間共享嚮導步驟,在這種情況下,mainWizard實現一個接口,嚮導步驟將其主要嚮導屬性轉換爲接口以訪問/存儲數據。

我有2個事件通過嚮導的頂部控制流。

如果你沒有處理這兩個事件中的任何一個,那麼嚮導會從StepList中的第一個到最後一個,一次只執行一個步驟。

事件1:如果你處理了ShoudlStepOccur,這個事件允許開發者決定是否應該在步驟列表中出現一個步驟(這樣你就可以跳過步驟)。這似乎與大多數嚮導在一個易於隱藏的隱喻中對應。事件給你的步驟和利用(前進,後退)

事件2 :(高級控制)在主窗體上有另一個事件NavigateToStep,事件給你它打算去的步驟,但你可以將其更改爲導航到完全不同的步驟。我們用它循環多次(例如,在註冊課程嚮導中,我們通過嚮導的幾個步驟多次遍歷每個課程一次)

我也有一個網格,列出所有步驟當前步驟突出顯示,並且用戶可以點擊跳轉向導。我使用StepShouldOccur事件來隨時瞭解步驟列表中要展示哪些步驟。

One gatchas: - 當關閉嚮導時,您必須處理面板中沒有任何資源的步驟,只是放置在StepList中,否則它們不會釋放其窗口句柄。

不知道有多少意義,所以我要離開那裏。也許有一天,我會把這個嚮導代碼放在代碼項目上或者其他什麼東西上,我很滿意它是如何爲我們工作的。

+0

謝謝,你能分享代碼嗎? – 2010-09-12 14:39:07