構建C# WinForms度量儀表板表單
[[academy-video-youtube({"vid": "IOo1ZFtPOBI", "start_time": "0", "title": "C# App Start To Finish Lesson 21 - Dashboard Form", "creator": "Tim Corey", "length": "51m 42s"})]]
在C# App From Start to Finish系列的第21課中,Tim Corey專注於在WinForms應用程式中連接比賽儀表板表單。 此表單作為應用程式的啟動畫面,並且是使用者進入點,可以載入現有的比賽或建立新的比賽。 WinForms儀表板是一個利用Windows Forms事件驅動功能的程式,其中使用者操作會觸發由程式碼處理的特定事件。
Tim解釋說,這一課不關於複雜的UI工作,而是關於將資料、模型、儲存過程和表單以一種清晰且一致的方式連接在一起。 注意:WinForms特別適合於內部公司軟體,例如庫存管理、CRM系統和會計工具。 為了真正理解WinForms儀表板在實際應用中的工作方式,Tim逐步演示了載入比賽、填充模型、處理資料庫連接和連接UI控制項。
在本文中,我們將通過跟隨Tim的影片解釋逐節深入了解儀表板表單,並包含時間戳以便於參考。 WinForms應用程式一般較輕量,提供優良的性能,使其非常適合較舊或性能較弱的硬體。
儀表板表單介紹
一開始,Tim介紹了第21課並解釋了目標:連接比賽儀表板表單,這將是應用程式啟動時首先載入的表單。
Tim指出,這個表單故意設計得簡單。 它只做幾件事情:
載入現有比賽的列表
允許使用者選擇並載入比賽
- 允許使用者建立新的比賽
他向觀眾保證,這不會是一個長篇大論或過於複雜的課程,但它會涉及系統的許多重要部分。
儀表板表單負責的內容
Tim解釋說,儀表板表單有兩個主要責任:
將現有比賽載入下拉列表
- 根據使用者行動開啟其他表單
如果比賽已存在,使用者可以選擇它並點選載入比賽(將在以後進行連接)。 如果使用者想要建立新的比賽,他們點選建立比賽,這將開啟項目中已存在的表單。
在這時,Tim澄清載入比賽按鈕尚未連接,將在以後的課程中處理。
為下拉列表建立比賽列表
選擇C#專案模板後, Visual Studio 會打開一個表單讓您設計使用者介面。
Tim切換至表單的後置程式碼,並解釋了下拉列表需要一個後端列表。注意表單在設計器中顯示準備進行UI自定義。 由於下拉列表旨在顯示比賽,後端列表必須是List<TournamentModel>。
他建立了一個名為tournaments的私人列表,並解釋代替手動建立一個新列表,資料應來自GlobalConfig連接,這抽象了資料源是SQL還是文字文件。
接著,Tim嘗試調用名為GetTournament_All的方法,注意到它尚不存在,並解釋必須將此方法新增到資料存取層。
新增GetTournament_All到資料層
Tim移到SQL連接器中並實現缺失的GetTournament_All方法。 他解釋說,這個方法將返回一個TournamentModel物件列表。
他複製了專案中其他地方使用的現有模式,並將其調整為比賽使用。 主要區別在於此方法調用了名為:
spTournaments_GetAll 的存儲過程Tim解釋這個儲存過程只檢索基本的比賽資料:
ID
比賽名稱
報名費
- 活動狀態
他指出,雖然TournamentModel包含更多屬性,這只是第一步。
理解部分模型填充
Tim暫停解釋一個重要概念:部分填充。
雖然比賽模型包括團隊、獎項和回合,那些屬性尚未填充。 在這個階段:
團隊是空的
獎品是空的
- 回合是空的
預計此時只有基本的比賽屬性被填充,而相關實體如團隊、獎品和回合保持空白,直到進一步載入。
Tim強調,這是有意的,這些相關實體必須在基本比賽記錄載入後填充。
填充每個比賽的獎金
Tim介紹了一個foreach迴圈,遍歷資料庫返回的每場比賽。
對於獎金,他解釋過程很簡單:
呼叫儲存過程以比賽ID檢索獎金
- 將結果分配給T.Prizes
他提到儲存過程spPrizes_GetByTournament,並解釋它返回與給定比賽相關的所有獎金。
這種模式——載入基本資料,然後根據ID載入子資料是Tim強調應用程式中經常出現的。
載入團隊和團隊成員
接下來Tim轉到輸入團隊。
他解釋載入團隊是個兩步驟過程:
載入與比賽相關的團隊
- 對於每個團隊,載入團隊成員
他使用儲存過程spTeams_GetByTournament檢索只與當前比賽相關的團隊。
然後對於每個團隊,Tim重用現有方法依據團隊ID載入團隊成員。 他指出這幾乎與系列中早些時候寫的程式碼相同,只是為特定比賽資料進行了調整。
介紹回合的複雜性
Tim解釋回合是比賽模型中最複雜的部分。
回合儲存為:
List<List<MatchupModel>>為了填充它們,Tim需要:
載入比賽的所有對決
載入每場對決的對決項目
- 解決如父對決和獲勝者等關係
他首先檢查儲存過程:
spMatchups_GetByTournament
- spMatchupEntries_GetByMatchup
處理獲勝者ID和巢狀模型
Tim指出處理資料庫時常見的問題: SQL返回ID,但應用程式期待物件。
Winner屬性是TeamModel,但資料庫僅返回WinnerId。 Tim解釋無法直接從SQL填充巢狀物件。
為解決這個問題,他在模型中新增了一個暫時的WinnerId屬性,只在載入資料過程中使用。 一旦所有團隊載入完畢,他使用ID為Winner屬性分配正確的TeamModel。
填充對決項目和父對決
對於每場對決,Tim:
依對決ID載入對決項目
檢查有效的團隊ID
- 使用所有團隊的快取列表解析關係
他解釋為何ID預設為0當不存在值時,以及為何檢查 > 0 是必需的。
Tim還解釋父對決是如何通過引用已載入的對決來解決的,依賴於對決按回合排序事實。
構建回合結構
一旦所有對決都完全填充,Tim解釋如何構造回合。
他介紹:
一個currentRound變數
- 一個currentRow列表
當他遍歷對決時:
如果回合號改變,先前回合新增至T.Rounds
一個新的回合列表被建立
- 對決依據分組
Tim透過完整範例確保邏輯明確,並強調分離迴圈使程式碼更易理解。
連接儀表板下拉選單
您可以通過從Visual Studio中的工具箱拖動控件將標籤、文字框和下拉選單等常見控件新增到表單中。
返回儀表板表單中,Tim建立了一個WireUpLists()方法。
他分配:
DataSource至tournaments列表
- DisplayMember to TournamentName
標籤通常用於描述下拉選單的用途,而文字框可用於表單中的使用者輸入。 處理使用者互動,您可以雙擊設計師中的一個按鈕自動生成Form1.cs文件中的Click事件處理器。
他解釋這使下拉選單顯示易讀名字而非物件引用。
測試SQL和文字文件連接
Tim使用兩個資料來源運行應用程式:
文字文件連接立即工作
- SQL連接則拋出一個錯誤
您可透過選擇開始按鈕或在Visual Studio中按F5運行應用程式。
他步驟查看錯誤資訊,指出此錯誤由缺少參數導致,並指出當結合多個資料來源時這類錯誤很常見。 此錯誤已被通過正確傳遞比賽ID至儲存過程修正。
在修正獎品和團隊後,Tim確認兩個資料來源現在都正常運行。 標識並修復錯誤是開發過程的正常部分,尤其在整合多個資料來源時。
連接建立比賽按鈕
最後,Tim透過處理事件特別是Click事件連接了建立比賽按鈕。
他解釋說為按鈕撰寫事件處理程式碼在code-behind文件(Form1.cs),而不是Form1.Designer.cs文件。Form1.Designer.cs文件自動為Windows Forms生成UI程式碼不應手動編輯。
按鈕簡單地:
建立一個新的建立比賽表單實例
- 調用Show()
他討論了關於使用者在建立比賽後該前往何處的設計決策,並解釋為何直接導航到比賽檢視器最有意義。
結論和接下來的內容
Tim總結了完成的工作:
儀表板載入比賽
下拉選單正確填充
- 建立比賽表單成功打開
他指出建立比賽後刷新列表將在稍後處理。
在下節課中,Tim預覽了比賽檢視表單,其中將實施回合、對決、計分和進展——為比賽系統注入活力。未來版本的這一課程將涵蓋附加功能和改進,包括與WinForms和.NET的新版本發布相關的更新。
此課程顯示WinForms儀表板不僅是一個UI,而是模型、資料存取和導航之間的協調點——這是Tim小心翼翼逐步展示的。
WinForms因其穩定性、快速開發速度和與Windows操作系統深度整合性而仍具有高度相關性。

