Skip to footer content
Iron Academy Logo
C# Application
C# Application

Other Categories

Building a C# WinForms Dashboard Form

Tim Corey
51m 42s

In Lesson 21 of the C# App From Start to Finish series, Tim Corey focuses on wiring up the Tournament Dashboard Form in a WinForms application. This form acts as the startup screen of the application and serves as the user’s entry point for either loading an existing tournament or creating a new one. A WinForms dashboard is a program that leverages the event-driven functionality of Windows Forms, where user actions trigger specific events handled by code.

Tim explains that this lesson is not about complex UI work, but rather about connecting data, models, stored procedures, and forms together in a clean and consistent way. Note: WinForms is particularly suitable for internal company software such as inventory management, CRM systems, and accounting tools. To truly understand how a WinForms dashboard works in a real-world application, Tim walks step by step through loading tournaments, hydrating models, handling database connections, and wiring up UI controls.

In this article, we’ll take a deeper look at the Dashboard Form by following Tim’s video explanation exactly, section by section, with timestamps included for easy reference. WinForms applications are generally lightweight and offer excellent performance, making them ideal for older or less powerful hardware.

Introduction to the Dashboard Form

At the very beginning, Tim introduces Lesson 21 and explains the goal: wiring up the Tournament Dashboard Form, which will be the first form that launches when the application starts.

Tim points out that this form is intentionally simple. It does only a few things:

  • Loads a list of existing tournaments

  • Allows the user to select and load a tournament

  • Allows the user to create a new tournament

He reassures viewers that this will not be a long or overly complex lesson, but it will touch many important parts of the system.

What the Dashboard Form Is Responsible For

Tim explains that the dashboard form has two primary responsibilities:

  1. Loading existing tournaments into a dropdown

  2. Opening other forms based on user actions

If a tournament already exists, the user can select it and click Load Tournament (which will be wired later). If the user wants to create a new tournament, they click Create Tournament, which opens a form that already exists in the project.

At this point, Tim clarifies that the Load Tournament button is not yet wired up and will be handled in a later lesson.

Creating the Tournament List for the Dropdown

After selecting the C# project template, Visual Studio opens a form for you to design the user interface.

Tim switches to the code-behind of the form and explains that the dropdown needs a backing list. Notice how the form appears in the designer, ready for UI customization. Since the dropdown is meant to display tournaments, the backing list must be a List< TournamentModel>.

He creates a private list called tournaments and explains that instead of manually creating a new list, the data should come from the GlobalConfig connection, which abstracts away whether the data source is SQL or text files.

Tim then attempts to call a method named GetTournament_All, notices it doesn’t exist yet, and explains that this method must be added to the data access layer.

Adding GetTournament_All to the Data Layer

Tim moves into the SQL Connector and implements the missing GetTournament_All method. He explains that this method will return a list of TournamentModel objects.

He copies an existing pattern used elsewhere in the project and adapts it for tournaments. The key difference is that this method calls a stored procedure named:

spTournaments_GetAll

Tim explains that this stored procedure retrieves only the basic tournament data:

  • ID

  • Tournament Name

  • Entry Fee

  • Active status

He notes that although the TournamentModel contains far more properties, this is just the first step.

Understanding Partial Model Hydration

Tim pauses to explain an important concept: partial hydration.

Although the tournament model includes teams, prizes, and rounds, those properties are not populated yet. At this stage:

  • Teams are empty

  • Prizes are empty

  • Rounds are empty

It is expected that only the base tournament properties are populated at this point, while related entities like teams, prizes, and rounds remain empty until further loading.

Tim emphasizes that this is intentional and that these related entities must be populated after the base tournament records are loaded.

Populating Prizes for Each Tournament

Tim introduces a foreach loop that iterates over every tournament returned from the database.

For prizes, he explains the process is simple:

  • Call a stored procedure that retrieves prizes by tournament ID

  • Assign the result to T.Prizes

He references the stored procedure spPrizes_GetByTournament and explains that it returns all prizes associated with a given tournament.

This pattern—load base data, then load child data by ID—is something Tim highlights as recurring throughout the application.

Loading Teams and Team Members

Next, Tim moves on to entered teams.

He explains that loading teams is a two-step process:

  1. Load the teams associated with the tournament

  2. For each team, load the team members

He uses a stored procedure named spTeams_GetByTournament to retrieve only the teams relevant to the current tournament.

Then, for each team, Tim reuses an existing method to load team members by team ID. He points out that this is nearly identical to code already written earlier in the series, just adapted for tournament-specific data.

Introducing the Complexity of Rounds

Tim explains that rounds are the most complex part of the tournament model.

Rounds are stored as:

List<List<MatchupModel>>

To populate them, Tim needs to:

  • Load all matchups for the tournament

  • Load matchup entries for each matchup

  • Resolve relationships like parent matchups and winners

He starts by reviewing the stored procedures:

  • spMatchups_GetByTournament

  • spMatchupEntries_GetByMatchup

Handling Winner IDs and Nested Models

Tim points out a common issue when working with databases:\ SQL returns IDs, but the application expects objects.

The Winner property is a TeamModel, but the database only returns a WinnerId. Tim explains that you cannot hydrate nested objects directly from SQL.

To solve this, he adds a temporary WinnerId property to the model, which is only used during data loading. Once all teams are loaded, he uses the ID to assign the correct TeamModel to the Winner property.

Populating Matchup Entries and Parent Matchups

For each matchup, Tim:

  • Loads matchup entries by matchup ID

  • Checks for valid team IDs

  • Uses a cached list of all teams to resolve relationships

He explains why IDs default to 0 when no value exists and why checking > 0 is essential.

Tim also explains how parent matchups are resolved by referencing already-loaded matchups, relying on the fact that matchups are ordered by round.

Building the Rounds Structure

Once all matchups are fully populated, Tim explains how rounds are constructed.

He introduces:

  • A currentRound variable

  • A currentRow list

As he loops through matchups:

  • If the round number changes, the previous round is added to T.Rounds

  • A new round list is created

  • Matchups are grouped accordingly

Tim walks through a full example to ensure the logic is clear and emphasizes that separating loops makes the code easier to understand.

Wiring the Dashboard Dropdown

You can add common controls such as labels, text boxes, and dropdowns to the form by dragging them from the Toolbox in Visual Studio.

Back in the Dashboard Form, Tim creates a WireUpLists() method.

He assigns:

  • DataSource to the tournaments list

  • DisplayMember to TournamentName

Labels are often used to describe the purpose of the dropdown, while text boxes can be used for user input in the form. To handle user interactions, you can double click a button in the designer to automatically generate a Click event handler in the Form1.cs file.

He explains that this is what makes the dropdown display human-readable names instead of object references.

Testing SQL and Text File Connections

Tim runs the application using both data sources:

  • Text file connection works immediately

  • SQL connection throws an error

You can execute the application by selecting the Start button or pressing F5 in Visual Studio.

He walks through the error message, identifies that this bug was caused by missing parameters, and notes that such bugs are common when integrating multiple data sources. This bug was fixed by properly passing the tournament ID to stored procedures.

After fixing both prizes and teams, Tim confirms that both data sources now work correctly. Identifying and fixing bugs is a normal part of the development process, especially when integrating multiple data sources.

Wiring the Create Tournament Button

Finally, Tim wires up the Create Tournament button by handling its events, specifically the Click event.

He explains that writing the event-handling code for the button is done in the code-behind file (Form1.cs), not in the Form1.Designer.cs file. The Form1.Designer.cs file automatically generates UI code for Windows Forms and should not be manually edited.

The button simply:

  • Creates a new instance of the Create Tournament form

  • Calls Show()

He discusses design decisions about where the user should go after creating a tournament and explains why navigating directly to the tournament viewer makes the most sense.

Conclusion and What’s Next

Tim concludes by summarizing the work done:

  • The dashboard loads tournaments

  • The dropdown is populated correctly

  • The Create Tournament form opens successfully

He notes that refreshing the list after creating a tournament will be handled later.

In the next lesson, Tim previews the Tournament Viewer Form, where rounds, matchups, scoring, and progression will be implemented—bringing the tournament system to life. Future versions of this lesson will cover additional features and improvements, including updates related to new version releases of WinForms and .NET.

This lesson shows how a WinForms dashboard is not just a UI, but a coordination point between models, data access, and navigation—something Tim carefully demonstrates step by step.

WinForms remains highly relevant for its stability, rapid development speed, and deep integration with the Windows operating system.

Hero Worlddot related to Building a C# WinForms Dashboard Form
Hero Affiliate related to Building a C# WinForms Dashboard Form

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me