C#: formulare modale și salvare numai la confirmare
Editează o valoare într-un dialog C# fără să modifici modelul la anulare. Folosește ShowDialog, DialogResult și o copie temporară a datelor introduse.
În acest material
Un dialog de editare trebuie să facă diferența dintre „am tastat” și „am confirmat”. Dacă legi direct câmpul la obiectul original, butonul Anulează poate lăsa modificări deja aplicate. Lucrăm cu un buffer local, apoi transferăm rezultatul numai dacă ShowDialog întoarce OK.
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
Formularul principal păstrează titlul. Dialogul primește valoarea inițială și o afișează într-un TextBox. Butonul OK validează textul și setează DialogResult numai după succes. Butonul Anulează are DialogResult.Cancel și CausesValidation=false. AcceptButton și CancelButton fac Enter și Escape previzibile.
ShowDialog(this) stabilește proprietarul și blochează interacțiunea cu formularul principal până la închiderea dialogului. Folosim using pentru a elibera dialogul după utilizare. Nu citim controale deja eliminate după blocul using; copiem rezultatul înainte de ieșire.
Exemplu și rezultat așteptat
Titlul inițial este Algoritmi. Deschizi dialogul, tastezi Grafuri și apeși Escape: principalul rămâne Algoritmi. Repeți editarea și confirmi cu Enter: apare Grafuri. Un text gol nu închide dialogul prin OK și permite corectarea valorii.
Model: Algoritmi → Buffer: Grafuri → Cancel → Algoritmi → OK → Grafuri.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 EditDialog : Form {
public string Result {get;private set;}
public EditDialog(string initial) {
Text="Titlu"; ClientSize=new Size(340,120);
var input=new TextBox {Left=15,Top=15,Width=300,Text=initial};
var ok=new Button {Left=15,Top=60,Text="OK"};
var cancel=new Button {Left=120,Top=60,Text="Anuleaza",DialogResult=DialogResult.Cancel,CausesValidation=false};
ok.Click += (s,e) => {
if(string.IsNullOrWhiteSpace(input.Text)) { MessageBox.Show(this,"Titlul este obligatoriu."); return; }
Result=input.Text.Trim(); DialogResult=DialogResult.OK;
};
AcceptButton=ok; CancelButton=cancel;
Controls.AddRange(new Control[] {input,ok,cancel});
}
}
class LessonForm : Form
{
string title="Algoritmi";
public LessonForm() {
Text="Editare modala"; ClientSize=new Size(360,140);
var output=new Label {Left=20,Top=20,Width=300,Text=title};
var edit=new Button {Left=20,Top=60,Text="Editeaza"};
edit.Click += (sender,e) => {
using(var dialog=new EditDialog(title)) {
if(dialog.ShowDialog(this)==DialogResult.OK) { title=dialog.Result; output.Text=title; }
}
};
Controls.AddRange(new Control[] {output,edit});
}
}
Greșeli și limite
Nu seta DialogResult.OK în Designer pe un buton care trebuie să execute validare manuală înainte de închidere, fără să controlezi efectul. Nu folosi variabile globale pentru schimbul dintre formulare. Nu ascunde formularul principal pentru fiecare dialog simplu: poți rămâne fără o fereastră accesibilă dacă apare o eroare.
Exersează
Testează confirmarea, anularea prin buton, Escape și închiderea prin X. Numai confirmarea validă trebuie să schimbe titlul. Adaugă un al doilea câmp și verifică regula „totul sau nimic”: un câmp invalid nu trebuie să salveze doar primul. Desenează momentul în care datele trec din buffer în model.
Continuă parcursul
Parcursul complet de 50 de lecții
Lecția precedentă: C#: DataGridView și actualizarea unei liste de obiecte
Lecția următoare: C#: meniuri și alegerea fișierelor prin dialog.
Referință: documentația Microsoft.
Întrebări frecvente
Show și ShowDialog sunt echivalente?
Nu. ShowDialog este modal și întoarce un rezultat la închidere.
Anularea repară automat modelul?
Nu. De aceea editezi un buffer și aplici schimbările doar după confirmare.
Cine eliberează dialogul?
Codul apelant îl poate deține într-un bloc using, după finalizarea ShowDialog.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.