跳過到頁腳內容
Iron Academy Logo
C# 應用程式
C# 應用程式

其他分類

將 C# WinForms 比賽數據保存到數據庫—與 Tim Corey 一同深入探討

Tim Corey
2h 32m 16s

在"C#從開始到完成應用程式"系列的第19課中,Tim Corey 走過了專案的一個重要里程碑:將完整構建的WinForms比賽保存到資料庫(和文字檔案)中。 WinForms 是建立 Windows 桌面應用程式的框架,使其成為展示資料持久性在現實世界中的理想選擇。

本文完全基於課程19–創建比賽表單(第5部分),並遵循Tim自己的逐步推理、調試過程和編碼模式。

Tim不是提出理論,而是走過真實應用程式代碼,展示模型如何保存、重建、調試和修正當事情不可避免地中斷時。 這讓這課對於理解WinForms中實際的資料持久性尤其有價值。

介紹

一開始,Tim介紹了第19課,並解釋今天終於是完成創建比賽表單的那天。 他承認這個表單到目前為止是最大的之一,有很多可動部件,可能會讓人感到不知所措。 在這課中,您將學習如何應用WinForms的事件驅動模型和快速應用程式開發功能來完成一個現實世界的表單。

Tim 讓觀眾放心,複雜性已被分解成可管理的部分,並且今天的重點是保存比賽資料所需的最終邏輯—無論是到 SQL 資料庫還是文字檔案—然後功能就完成了。 WinForms 是快速應用程式開發 (RAD) 和構建內部業務工具或輕量級工具的理想選擇,其相對簡單的事件驅動模型和大量的線上資源使新開發者能輕鬆學習。

在 Visual Studio 中創建新專案

使用 Visual Studio 開始使用 Windows Forms 應用程式很簡單。 首先開啟 Visual Studio,然後從起始窗口選擇"創建新專案"。 在"創建新專案"對話框中,使用搜索欄鍵入"Windows Forms App"—這會快速帶出您需要的範本。 為了縮小您的選擇範圍,篩選 C# 作為語言和 Windows 作為平台。

一旦找到"Windows Forms App (.NET Framework)"專案類型,選擇它並點擊下一步。 在"配置您的新專案"窗口中,給您的專案一個名稱(例如,HelloWorld),選擇一個位置,然後點擊創建。 Visual Studio 會生成一個新的解決方案並開啟您的主表單,作為您的應用程式的圖形使用者介面。 這個表單是您將設計使用者介面並添加控制項的地方,為您的Windows桌面應用程式奠定基礎。 範本包括所有必要的檔案和對 .NET Framework 的引用,因此您可以立即專注於構建應用程式的功能。

審核創建比賽按鈕邏輯

Tim 開始於回顧。 他解釋程序中的一切都從創建比賽按鈕開始。 在 C# WinForms 程序中,寫事件處理器以針對特定的用戶操作(如單擊創建比賽按鈕)執行代碼。 迄今為止,應用程式已經:

  • 驗證了用戶輸入

  • 構建了比賽對象

  • 創建了記憶體中的比賽回合和對陣

Tim 解釋說,缺失的信息就是持久化那些數據。 之前,應用程式可以保存比賽、獎品以及參賽者的資料,但回合信息缺失。 這就是本課程要解決的問題。

在 SQL 中保存比賽:大畫面

Tim 導航到 SQL 連接器的 CreateTournament 方法,提醒觀眾保存數據遵循明確的模式:

  1. 保存比賽本身

  2. 獲取比賽 ID

  3. 保存獎品

  4. 保存參賽者

  5. 現在:保存回合和對陣

注意:遵循這一保存順序以確保所有相關數據正確關聯,並保持應用程式的數據完整性是重要的。

Tim 強調模式是好的,並且這課遵循了早已建立的相同模式。

WinForms 也支持創建可重用的UI元素,如按鈕、文本框和標籤,這有助於在應用程式的數據結構中保持一致性。

了解資料結構的複雜性

在這裡,Tim 暫停解釋為什麼保存回合更複雜。

  • 一個比賽有回合

  • 每一回合是一個 MatchupModel 的列表

  • 每個對陣包含 MatchupEntryModel 對象

Tim 解釋說這是一個列表的列表,這種複雜性在這個階段很正常。 他鼓勵觀眾不要驚慌——這只是對现实世界数据建模的自然结果。

他還指出,WinForms 應用程式是使用組件構建的,如數據網格和 UI 控制項,這有助於開發人員高效創建功能豐富的桌面應用程式。 在 Windows Forms 類庫中,所有可視元素都派生自 Control 類,為構建和定制用戶介面提供了一個一致的基礎。

為什麼保存順序很重要

視頻中最關鍵的解釋之一發生在這裡。

Tim 解釋數據必須按順序保存,因為:

  • 對陣項目在父對陣 ID 存在之前不能保存

  • 一個回合在之前回合擁有 IDs 之前不能引用下一回合

他解釋說,由於對象引用相同的記憶體地址,一旦 ID 在某一處被填充,所有引用會自動更新。 不過,開發人員可能需要在分配ID時修改對象引用,這是典型的 C# WinForms 應用程式事件驅動過程的一部分,其中應用程式回應用戶操作和資料變更。

確保所有模型都有 ID

Tim 指出一個重要修正:MatchupEntryModel 尚未有 ID 屬性。

即使目前不需要,Tim 仍然添加它,解釋說每個數據庫支持的模型都應該有一個 ID 以保持一致性和未來用途。 默認情況下,Windows Forms 應用程式使用像 Form1.Designer.cs 這樣的文件來自動生成 UI 代碼,確保應用程式的標準結構和行為。

將邏輯分解為簡單步驟

此部分作為在 C WinForms 應用程式中保存數據的教程。

Tim 使用了他最喜歡的教學比喻之一:像吃大象一樣,一次吃一口。

他將保存邏輯分解為清晰的步驟:

  1. 通過每回合循環

  2. 在每回合內,遍歷比賽

  3. 保存每場比賽

  4. 循環比賽條目

  5. 保存每條目

每個步驟本身都很簡單,並且融合在一起時,它們具有強大的力量。

Visual Studio 的直觀拖放可視設計器使 WinForms 為構建內部工具、原型和簡單應用程式出色。

遍歷回合和比賽

Tim 顯示如何遍計一個回合列表,其中每個回合本身是一個 MatchupModel 的列表。

一開始他刻意避免使用 var 並解釋原因:明確的類型幫助開發者理解他們正在遍歷的內容,特別是當處理嵌套列表時。 在 Windows Forms 開發中,寫明確的代碼尤其重要,因為這提高了可維護性,並支持多種語言的本地化。

他還分享了一種重要的哲學觀念:

"最佳代碼是初級開發者可以理解的代碼。"

Windows Forms 應用程式是事件驅動的,並受 Microsoft 的 .NET Framework 支持。

創建比賽插入存儲過程

Tim 切換到 SQL 並創建 spMatchups_Insert。

他清晰地解釋字段:

  • 比賽 ID

  • 比賽回合

  • 獲勝者 ID(可空)

可以包括其他字段,如日期,以跟踪比賽發生時間。

Tim 在這個階段故意不設置獲勝者。 即使一場比賽是一個輪空,他更喜歡稍後用相同的邏輯處理贏家,就像真正的比賽一樣。

Windows Forms 通過用受控代碼包裹現有的 Windows API 提供對原生 Windows 使用者介面通用控制的訪問。

保存比賽條目和處理 NULLs

Tim 創建了另一個存儲過程:spMatchupEntries_Insert。

他解釋:

  • 分數為 NULL 因為比賽尚未進行

  • NULL 不同於零

  • TeamCompeting 可以在後幾回合為 NULL

他用足球和高爾夫的一個令人難忘的例子來解釋為什麼零是一個真正的值,而 NULL 表示仍不存在值。

您可以在 Windows Forms 專案中配置應用程式設置以處理不同的數據場景,例如如何在控件中顯示或處理 NULL 值。

Windows Forms 是 Microsoft .NET,.NET Framework,或 Mono 的一部分。

.NET Framework 應用程式的功能與特性

基於 .NET Framework 建立的 Windows Forms 應用程式提供了一組功能強大的功能,用於創建現代 Windows 桌面應用程式。 通過 Windows Forms (WinForms),您可以訪問豐富的圖形用戶介面 (GUI) 函數庫,使設計直觀和互動的用戶介面變得輕鬆。 WinForms 是免費、開源的框架,包含在 Microsoft .NET,.NET Framework 和 Mono 中,通過受控代碼與原生 Windows 控制項和Windows API無縫集成。

Visual Studio IDE 增強您的開發體驗,添加了 Windows Forms Designer 等工具,允許您將常用控件(如按鈕、文本框和標籤)直接拖拽到表單上。 這種可視化方法加快UI設計步驟,並可以使用屬性窗口自定義屬性和事件。 通過內建支持的代碼編輯、調試和項目管理,Visual Studio 簡化了構建、測試和完善您的 Windows 桌面應用程式的過程。 無論您是在創建業務工具、工具程式還是教育軟體,.NET Framework 和 WinForms 都提供了堅實的平台來交付功能豐富、響應快速、用戶友好的應用程式。

使用 Edit and Continue 調試

當異常發生時,Tim 不會驚慌,他教學。

他使用 Visual Studio 的 Edit and Continue 特點來:

  • 暫停執行

  • 插入空值檢查

  • 在不重新啟動應用的情況下繼續執行

鍵盤快捷鍵,如使用 'Ctrl' 組合(例如,'Ctrl + Alt + X' 打開工具箱),可以加快調試和 UI 控件的訪問速度於 Visual Studio。

他顯示如何:

  • 檢查 TeamCompeting 是否為 NULL

  • 傳遞 NULL 給 SQL 而不是訪問 .ID

  • 將相同邏輯應用於 ParentMatchup

這是 Tim 使用的真實調試工作流程。

Visual Studio 為 C# 開發提供了廣泛的特點和工具,包括 Windows Forms Designer。

在 SQL 中驗證數據

在修復兩個小錯誤後, Tim 查詢了資料庫。

他確認:

  • 比賽保存正確

  • 回合次數準確

  • 由邏輯工作

  • 父子關係正確

注意到在保存後資料庫中正確的關係和數據,因為這種視覺反饋對於驗證應用邏輯是否按預期運行很重要。

Tim 指出只有兩個錯誤發生在一個非常複雜的特徵中之中,並將此歸因於規劃、模式和分解工作成小片。

Windows Forms 為桌面、膝上型和平板電腦 PC 開發提供了一個平台,使其成為 Windows 開發的多元選擇。

編譯和準備查詢方法

Tim 先確保專案仍然能編譯,然後才著手處理未完的部分。 在 1:17:08,他解釋系統會將字串傳入方法,然後返回一個或多個從文本文件中提取的 MatchupEntryModel 物件。

在 1:17:40,Tim 實施了一個名為 LookupTeamById(int id) 的方法。 他解釋當數據儲存在文本文件中時,只有 ID 被保存,而不是完整的物件。 因此,在加載數據時,應用程式必須將該 ID 重新灌水到完整的 TeamModel 中。

Tim 指出這不是新的邏輯—他只是重用已經用於從文件加載所有隊伍的模式。他強調這種重用是故意的,是正確編碼結構的核心優勢。 開發者也可以參考現有的方法和官方文檔,以獲得實施類似邏輯的額外指導。

Windows Forms 被視為曾經是 C++ 基於微軟基礎類庫的 GUI 開發的更早、更複雜的替代品。

使用 GlobalConfig 集中文件路径

在 1:20:27,Tim 暫停並指出設計問題:文件名被傳遞到每個地方,儘管它們是常量。 他公開表示感到這"荒謬"。

為了解決這個問題,Tim 將文件名常量移到 GlobalConfig 中,並將其公開。 在 1:21:33,他解釋這避免了通過多層方法傳遞文件路徑。 Visual Studio 的解決方案資源管理器有助於管理這些項目文件和總體結構,易於定位和更新這類常量。

然而, 在 1:22:24,Tim 誠實地談到了一個缺陷:這些常量現在存在於兩個地方—GlobalConfig 和 TextConnector。 他明確表示這是對 DRY(不要重複自己)原則的違反,並指出應該在以後進行重構,但今天不是那一天。

還需要注意的是 Windows Forms 不提供默認的應用框架,例如 Microsoft Foundation Class (MFC)。

將字串轉換成 MatchupEntryModel

在 1:24:37,Tim 開始實施 ConvertStringToMatchupEntryModel。 他解釋比賽條目被存儲為管道分隔的 IDs,所以第一步是按管道分割字串(|)。 與使用頁面作為導航和佈局主 UI 容器的 Web 應用程式不同,WinForms 使用表單來組織用戶介面。

到 1:25:17,他遍歷每個 ID,從對陣條目文件中查找,並將對應的模型添加到輸出列表中。模式仍然有一致性:

裝載 → 轉換 → 按 ID 篩選 → 返回模型

Tim 強調一致性使以後的調試成為可能。

可以使用 .NET 程式語言(如 C# 或 Visual Basic)開發 Windows Forms 應用程式。

構建 ConvertToMatchupEntryModels 擴展

在 1:27:56,Tim 創建了一個擴展方法 ConvertToMatchupEntryModels(List< string>)。 為了指導過程,他複製了一個現有的轉換方法(用於 PersonModel)並僅作為模式參考。

到 1:30:28,Tim 明確映射欄位:

  • 欄位 0 → ID

  • 欄位 1 → TeamCompeting ID

  • 欄位 2 → 分數

  • 欄位 3 → ParentMatchup ID

他解釋儲存的值只是 ID,因此必須使用查詢方法重新構建完整的物件。 WinForms 中的一些 UI 組件和主題受 Microsoft Office 的啟發,例如 Office 2019 Colorful 和 Office 2019 Black,以提供熟悉的用戶體驗。

像 DevExpress 這樣的第三方供應商提供完善的 WinForms UI 組件套組。

安全處理父對陣

在 1:38:49,Tim 發現一個主要問題:父對陣可能不存在(尤其是第一個回合中)。 在一個丟失的 ID 上調用 First() 會導致應用崩潰。

在 1:39:09 他的修正使用了 int.TryParse。 如果解析失敗,ParentMatchup 設置為 null。 Tim 仔細解釋這正是第一回合對陣應該發生的情況。 WinForms 或第三方庫的每次發行通常包括新功能和修正件,改善了這樣的場景處理方式。

他強調崩潰僅可接受於在無效數據永不應存在的情況下,比如無效的隊伍ID。

DevExpress WinForms 訂閱包括超過 190 個 UI 控件和庫,提供豐富的選擇來構建穩健的應用程式。

將比賽和條目保存到文件中

在 1:44:00,Tim 開始進入保存數據階段。 他加載所有比賽,確定下一個可用 ID,分配它,然後進入保存比賽條目的步驟。 保存數據後,您可以單擊 Start 按鈕或在 Visual Studio 中按 F5 運行 WinForms 應用程式來測試應用程式。

到 1:46:44,Tim 強調可重用方法的力量—加載和轉換文件現在變得"無聊",他說這是件好事。

他先保存比賽條目,因此每個條目會獲得一個ID,然後保存比賽本身,將那些條目ID作為管道分隔字串儲存。

此外,DevExpress WinForms 訂閱包括一個帶終端用戶報告設計器的報告套件,可增強您的 WinForms 應用程式。

將比賽條目寫入資料庫

在 1:49:43,Tim 在構建保存邏輯時一行接一行。他仔細逆向了早期的轉換模式:

  • ID

  • TeamCompeting ID(或空字串)

  • 分數

  • ParentMatchup ID(或空字串)

在解釋保存邏輯後,值得注意的是 WinForms 在各種 .NET 平台上得到支持,確保了兼容性和持續更新。

在 1:52:02,Tim 解釋為什麼空字串是必需的:它們不會打亂解析邏輯並保持欄位順序。

此外,DevExpress WinForms 控件支持 DirectX 硬件加速以改善性能。

保存比賽和獲勝者

在 1:55:02,Tim 保存比賽本身。 由於比賽可以擁有多個條目,他使用重用的助手方法將條目列表轉換為管道分隔字串。 開發者可以使用 Visual Studio 的工具箱添加如按鈕和標籤等控件到他們的 Windows Forms 中,令設計用戶介面更簡單。

在 1:58:30,他對獲勝者欄位應用了相同的空值處理邏輯。 如果尚不存在任何獲勝者,則保存一個空字串。

Windows Forms 使開發人員能夠為桌面、平板電腦和 PCs 創建應用程式。

加載比賽時重建回合

在 2:02:03,Tim 處理最後的 TODO:加載回合信息。 他解釋回合分別被儲存為比賽 ID 列表,首先按管道符分割,再用尖簇 (^) 分割。

到 2:09:13,他重建了完整的嵌套結構:

  • ID → MatchupModels

  • MatchupModels → Round lists

  • Round lists → TournamentModel

在解釋重建後,Tim 指出,不同於其他框架,WinForms 使用不同的方法來組織 UI 和資料,這可能影響開發者如何管理嵌套結構。

Tim 強調,這種嵌套解釋了為什麼代碼顯得複雜—以及為什麼手動一步步走過它是如此重要。

此外,值得一提的是 DevExpress WinForms 訂閱包括了對 WinForms 應用的可自定義主題和皮膚。

調試真正的錯誤

從 2:11:22 開始,Tim 故意運行應用並調試:

  • NullReferenceException

  • 輸入字串格式不正確

  • 序列不包含元素

Tim不隱藏錯誤,而是展示如何精確地追踪它們、檢查值並推理執行順序。 WinForms 多年前首次發布,並隨著時間演進。

在 2:20:30,他指出一個循環保存問題:比賽需要先存在才能讓條目引用它們。 他的解決方案是務實的—保存兩次。他公開承認這不夠優雅,但說道:

"運行的代碼比重新提煉的仍有錯的代碼要好。"

Windows Forms 現在作為 .NET Core 的一個開源專案在 GitHub 上可用。

部署 Windows Forms 應用程式

在 Visual Studio 中構建和測試您的 Windows Forms 應用後,下一步是部署—使您的應用程式可供用戶使用。 Visual Studio 提供了幾種部署選項,其中 ClickOnce 是 Windows 桌面應用程式最方便的一種。 ClickOnce 允許您將應用程式發佈到網路文件共享、Web 伺服器或甚至光盤/DVD 上,使最終用戶的安裝變得簡單明瞭。

要部署,只需使用 Visual Studio 的發布工具打包您的應用程式。在發佈前,使用 Visual Studio 的調試工具徹底測試您的應用程式以捕捉並修正代碼中的任何錯誤或問題。 一旦部署,用戶可以通過運行設置文件或點擊快捷方式安裝您的應用程式,應用程式將執行並顯示其圖形用戶介面以供即時互動。 無論您選擇 ClickOnce、Windows Installer 或第三方部署工具,該過程可確保您的用戶可以輕鬆訪問您的 Windows Forms 應用程式的完整功能和特色。 這種精簡的部署過程幫助您向觀眾交付可靠的、專業的 Windows 桌面應用程式。

結束思考

到這 課程 結束時,Tim Corey 展示了一個完整的、使用文本文件作為數據庫的資料持久性系統。 更重要的是,他展示了現實世界的錯誤如何出現,如何用模式引導修正,以及為什麼理解執行順序比完美重要。

這課程不是關於花哨的數據庫—而是關於像開發人員一樣思考。

Hero Worlddot related to 將 C# WinForms 比賽數據保存到數據庫—與 Tim Corey 一同深入探討
Hero Affiliate related to 將 C# WinForms 比賽數據保存到數據庫—與 Tim Corey 一同深入探討

通過分享您所愛的東西賺得更多

您是否在為使用.NET、C#、Java、Python或Node.js的開發者創建內容?將您的專業知識轉化為額外收入!

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我