C#: miniaplicație cu grilă și stare separată de butoane
Construiește o grilă interactivă C# din controale generate dinamic. Transformă indexul în linie și coloană și păstrează starea într-o matrice separată.
În acest material
O grilă de joc sau de selecție are două reprezentări: matricea logică și controalele afișate. Dacă păstrezi starea numai în culoarea butonului, regulile devin greu de testat. Folosim o matrice bool de 3×3 și generăm nouă butoane. Fiecare click inversează o celulă, apoi actualizează prezentarea.
Cum lucrezi cu exemplul
Exemplul complet se compilează ca Windows Forms App pe .NET Framework 4.8, cu C# 7.3. Deschide Lesson.csproj din arhivă în Visual Studio pe Windows. Rulează scenariile descrise mai jos; verificarea compilării nu înlocuiește testarea ferestrei și a dispozitivelor folosite.
Descarcă sursele și instrucțiunile.
Ideea și pașii de implementare
Transformarea dintre indexul liniar și coordonate este row=index/3, col=index%3. În bucla de creare, copiem indexul într-o variabilă locală capturată de handler. Aceasta face explicită identitatea butonului și evită folosirea accidentală a unei variabile de buclă schimbate ulterior.
TableLayoutPanel distribuie butoanele în trei coloane și trei rânduri cu procente egale. Tag nu este necesar aici, dar ar putea păstra un ID; modelul rămâne matricea. Textul ON/OFF însoțește culoarea, astfel încât starea nu depinde exclusiv de perceperea culorilor.
Exemplu și rezultat așteptat
Clickul pe celula cu index 5 corespunde liniei 1 și coloanei 2, în indexare de la zero. Prima apăsare schimbă false în true și textul în ON. A doua revine la OFF. Celelalte opt celule rămân neschimbate.
Index 5 → Linie 1, coloană 2 → false → true → Buton: ON.Mărește schema ↗
Codul complet
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LessonForm());
}
}
class LessonForm : Form
{
readonly bool[,] state=new bool[3,3];
public LessonForm() {
Text="Grila 3 x 3";ClientSize=new Size(360,360);
var grid=new TableLayoutPanel {Dock=DockStyle.Fill,RowCount=3,ColumnCount=3};
for(int i=0;i<3;i++) {grid.RowStyles.Add(new RowStyle(SizeType.Percent,100f/3));grid.ColumnStyles.Add(new ColumnStyle(SizeType.Percent,100f/3));}
for(int i=0;i<9;i++) {
int index=i;var button=new Button {Dock=DockStyle.Fill,Text="OFF",AccessibleName="Celula " + (i+1)};
button.Click += (s,e) => {
int row=index/3,col=index%3;state[row,col]=!state[row,col];
button.Text=state[row,col] ? "ON" : "OFF";
button.BackColor=state[row,col] ? Color.PaleGreen : SystemColors.Control;
};
grid.Controls.Add(button,i%3,i/3);
}
Controls.Add(grid);
}
}
Greșeli și limite
Nu amesteca indexarea de la unu a explicației pentru utilizator cu indexarea de la zero din matrice. Nu citi BackColor pentru a decide starea logică. Nu adăuga un handler nou la fiecare redesenare. Dacă mărești grila, actualizează coerent dimensiunea matricei și formulele de conversie.
Exersează
Verifică cele patru colțuri și celula centrală. Adaugă un contor al celulelor active și compară-l după fiecare click cu o parcurgere independentă a matricei. După activarea tuturor celulelor trebuie să obții nouă; după o a doua apăsare pe fiecare, zero. Adaugă Reset fără să recreezi toate controalele.
Continuă parcursul
Parcursul complet de 50 de lecții
Lecția precedentă: C#: miniaplicație quiz cu răspuns unic și scor
Lecția următoare: C#: relații și chei în DataTable și DataSet.
Referință: documentația Microsoft.
Întrebări frecvente
De ce nu păstrez starea în culoare?
Culoarea este prezentare. Modelul separat permite testarea și schimbarea designului fără schimbarea regulilor.
Cum transform indexul 5?
Pentru trei coloane: linia este 5/3=1, iar coloana este 5%3=2.
De ce copiez indexul în buclă?
Pentru ca fiecare handler să folosească explicit identitatea celulei pentru care a fost creat.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.