Construindo um Formulário de Dashboard em C# WinForms
Na Lição 21 da série C# App From Start to Finish, Tim Corey se concentra na conexão do Formulário de Dashboard do Torneio em um aplicativo WinForms. Este formulário atua como a tela de inicialização do aplicativo e serve como o ponto de entrada do usuário para carregar um torneio existente ou criar um novo. Um dashboard WinForms é um programa que aproveita a funcionalidade orientada a eventos do Windows Forms, onde ações do usuário disparam eventos específicos tratados por código.
Tim explica que esta lição não é sobre trabalho de IU complexo, mas sim sobre conectar dados, modelos, procedimentos armazenados e formulários juntos de maneira limpa e consistente. Nota: WinForms é particularmente adequado para software interno da empresa, como gerenciamento de inventário, sistemas CRM e ferramentas de contabilidade. Para realmente entender como um dashboard WinForms funciona em uma aplicação do mundo real, Tim caminha passo a passo através de carregamento de torneios, hidratação de modelos, manuseio de conexões de banco de dados e conexão de controles de interface do usuário.
Neste artigo, vamos analisar mais a fundo o Formulário de Dashboard seguindo a explicação do Tim vídeo exatamente, seção por seção, com marcas de tempo incluídas para fácil referência. Aplicações WinForms são geralmente leves e oferecem excelente desempenho, tornando-as ideais para hardware mais antigo ou menos potente.
Introdução ao Formulário de Dashboard
Logo no início, Tim introduz a Lição 21 e explica o objetivo: conectar o Formulário de Dashboard do Torneio, que será o primeiro formulário a ser iniciado quando a aplicação for aberta.
Tim aponta que este formulário é intencionalmente simples. Ele faz apenas algumas coisas:
-
Carrega uma lista de torneios existentes
-
Permite que o usuário selecione e carregue um torneio
- Permite que o usuário crie um novo torneio
Ele tranquiliza os espectadores de que esta não será uma lição longa ou excessivamente complicada, mas que tocará muitas partes importantes do sistema.
Para que o Formulário de Dashboard é Responsável
Tim explica que o formulário do dashboard possui duas responsabilidades principais:
-
Carregar torneios existentes em um dropdown
- Abrir outros formulários com base nas ações do usuário
Se um torneio já existir, o usuário pode selecioná-lo e clicar em Carregar Torneio (que será conectado mais tarde). Se o usuário quiser criar um novo torneio, ele clica em Criar Torneio, o que abre um formulário que já existe no projeto.
Neste ponto, Tim esclarece que o botão Carregar Torneio ainda não está conectado e será tratado em uma lição posterior.
Criando a Lista de Torneios para o Dropdown
Após selecionar o modelo de projeto C#, o Visual Studio abre um formulário para você projetar a interface do usuário.
Tim muda para o código por trás do formulário e explica que o dropdown precisa de uma lista de apoio. Note como o formulário aparece no designer, pronto para a personalização de IU. Como o dropdown é destinado a exibir torneios, a lista de apoio deve ser uma List
Ele cria uma lista privada chamada torneios e explica que em vez de criar manualmente uma nova lista, os dados devem vir da conexão GlobalConfig, que abstrai se a fonte de dados é SQL ou arquivos de texto.
Tim então tenta chamar um método chamado GetTournament_All, percebe que ele ainda não existe, e explica que esse método deve ser adicionado à camada de acesso a dados.
Adicionando GetTournament_All à Camada de Dados
Tim se move para o Conector SQL e implementa o método GetTournament_All que estava faltando. Ele explica que este método retornará uma lista de objetos TournamentModel.
Ele copia um padrão existente usado em outro lugar no projeto e adapta-o para torneios. A principal diferença é que este método chama um procedimento armazenado chamado:
spTournaments_GetAll
Tim explica que este procedimento armazenado recupera apenas os dados básicos do torneio:
-
ID
-
Nome do Torneio
-
Taxa de Inscrição
- Status ativo
Ele observa que embora o TournamentModel contenha muito mais propriedades, este é apenas o primeiro passo.
Entendendo a Hidratação Parcial do Modelo
Tim faz uma pausa para explicar um conceito importante: hidratação parcial.
Embora o modelo de torneio inclua equipes, prêmios e rodadas, essas propriedades ainda não estão populadas. Neste estágio:
-
Equipes estão vazias
-
Prêmios estão vazios
- Rodadas estão vazias
Espera-se que apenas as propriedades básicas do torneio estejam populadas neste momento, enquanto entidades relacionadas como equipes, prêmios e rodadas permanecem vazias até um carregamento mais adiante.
Tim enfatiza que isso é intencional e que essas entidades relacionadas devem ser populadas após os registros base do torneio serem carregados.
Populando Prêmios para Cada Torneio
Tim introduz um loop foreach que itera sobre cada torneio retornado do banco de dados.
Para prêmios, ele explica que o processo é simples:
-
Chamar um procedimento armazenado que recupera prêmios por ID do torneio
- Atribuir o resultado a T.Prizes
Ele faz referência ao procedimento armazenado spPrizes_GetByTournament e explica que ele retorna todos os prêmios associados a um determinado torneio.
Esse padrão—carregar dados base, depois carregar dados filhos por ID—é algo que Tim destaca como recorrente em todo o aplicativo.
Carregando Equipes e Integrantes das Equipes
Em seguida, Tim se move para as equipes inscritas.
Ele explica que carregar equipes é um processo de duas etapas:
-
Carregar as equipes associadas ao torneio
- Para cada equipe, carregar os integrantes da equipe
Ele usa um procedimento armazenado chamado spTeams_GetByTournament para recuperar apenas as equipes relevantes para o torneio atual.
Então, para cada equipe, Tim reutiliza um método existente para carregar membros da equipe por ID da equipe. Ele aponta que isso é quase idêntico ao código já escrito anteriormente na série, apenas adaptado para dados específicos do torneio.
Introduzindo a Complexidade das Rodadas
Tim explica que as rodadas são a parte mais complexa do modelo de torneio.
As rodadas são armazenadas como:
List<List<MatchupModel>>
Para populá-las, Tim precisa:
-
Carregar todos os confrontos para o torneio
-
Carregar entradas de confronto para cada confronto
- Resolver relações como confrontos pai e vencedores
Ele começa revisando os procedimentos armazenados:
-
spMatchups_GetByTournament
- spMatchupEntries_GetByMatchup
Lidando com IDs de Vencedores e Modelos Aninhados
Tim aponta um problema comum ao trabalhar com bancos de dados: SQL retorna IDs, mas o aplicativo espera objetos.
A propriedade Winner é um TeamModel, mas o banco de dados retorna apenas um WinnerId. Tim explica que você não pode hidratar objetos aninhados diretamente do SQL.
Para resolver isso, ele adiciona uma propriedade temporária WinnerId ao modelo, que é usada apenas durante o carregamento de dados. Uma vez que todas as equipes estejam carregadas, ele usa o ID para atribuir o TeamModel correto à propriedade Winner.
Populando Entradas de Confronto e Confrontos Pai
Para cada confronto, Tim:
-
Carrega entradas de confronto por ID de confronto
-
Verifica por IDs de equipe válidos
- Usa uma lista em cache de todas as equipes para resolver relações
Ele explica por que IDs padrão para 0 quando nenhum valor existe e por que verificar > 0 é essencial.
Tim também explica como confrontos pai são resolvidos referenciando confrontos já carregados, confiando no fato de que confrontos são ordenados por rodada.
Construindo a Estrutura das Rodadas
Uma vez que todos os confrontos estejam completamente populados, Tim explica como as rodadas são construídas.
Ele introduz:
-
Uma variável currentRound
- Uma lista currentRow
À medida que ele percorre os confrontos:
-
Se o número da rodada mudar, a rodada anterior é adicionada a T.Rounds
-
Uma nova lista de rodada é criada
- Confrontos são agrupados adequadamente
Tim percorre um exemplo completo para garantir que a lógica está clara e enfatiza que separar os loops torna o código mais fácil de entender.
Conectando o Menu Suspenso do Painel
Você pode adicionar controles comuns como rótulos, caixas de texto e menus suspensos ao formulário arrastando-os da Caixa de Ferramentas no Visual Studio.
De volta ao Formulário do Painel, Tim cria um método WireUpLists().
Ele atribui:
-
DataSource à lista de torneios
- DisplayMember ao TournamentName
Rótulos são frequentemente usados para descrever o propósito do menu suspenso, enquanto caixas de texto podem ser usadas para entrada do usuário no formulário. Para lidar com interações do usuário, você pode clicar duas vezes em um botão no designer para gerar automaticamente um manipulador de evento Click no arquivo Form1.cs.
Ele explica que é isso que faz o menu suspenso exibir nomes legíveis em vez de referências de objeto.
Testando Conexões de Arquivo de Texto e SQL
Tim executa o aplicativo usando ambas as fontes de dados:
-
A conexão de arquivo de texto funciona imediatamente
- A conexão SQL gera um erro
Você pode executar o aplicativo selecionando o botão Iniciar ou pressionando F5 no Visual Studio.
Ele percorre a mensagem de erro, identifica que esse bug foi causado por parâmetros ausentes e observa que tais bugs são comuns ao integrar várias fontes de dados. Este bug foi corrigido passando o ID do torneio corretamente para os procedimentos armazenados.
Após corrigir tanto prêmios quanto equipes, Tim confirma que ambas as fontes de dados agora funcionam corretamente. Identificar e corrigir erros é uma parte normal do processo de desenvolvimento, especialmente ao integrar várias fontes de dados.
Conectando o Botão Criar Torneio
Finalmente, Tim conecta o botão Criar Torneio manipulando seus eventos, especificamente o evento Click.
Ele explica que escrever o código de manipulação de eventos para o botão é feito no arquivo code-behind (Form1.cs), não no arquivo Form1.Designer.cs. O arquivo Form1.Designer.cs gera automaticamente o código da UI para Windows Forms e não deve ser editado manualmente.
O botão simplesmente:
-
Cria uma nova instância do formulário Criar Torneio
- Chama Show()
Ele discute decisões de design sobre onde o usuário deve ir após criar um torneio e explica por que navegar diretamente para o visualizador de torneios faz mais sentido.
Conclusão e O Que Vem a Seguir
Tim conclui resumindo o trabalho feito:
-
O painel carrega torneios
-
O menu suspenso é populado corretamente
- O formulário Criar Torneio abre com sucesso
Ele observa que atualizar a lista após criar um torneio será tratado mais tarde.
Na próxima lição, Tim visualiza o Formulário de Visualização de Torneio, onde rodadas, confrontos, pontuação e progressão serão implementados, trazendo o sistema de torneio à vida. Versões futuras desta lição cobrirão recursos e melhorias adicionais, incluindo atualizações relacionadas a novas versões de WinForms e .NET.
Esta aula mostra como um painel WinForms não é apenas uma UI, mas um ponto de coordenação entre modelos, acesso a dados e navegação — algo que Tim demonstra cuidadosamente passo a passo.
WinForms continua extremamente relevante por sua estabilidade, velocidade de desenvolvimento rápido e integração profunda com o sistema operacional Windows.
