C#: desene persistente cu Paint și Invalidate
Desenează starea aplicației C# în evenimentul Paint. Înțelege coordonatele, redesenarea și folosirea resurselor Graphics fără desene care dispar la restaurare.
În acest material
Un desen făcut o singură dată cu CreateGraphics poate dispărea când fereastra este acoperită și apoi restaurată. Soluția este să păstrezi datele desenului și să le reprezinți în Paint ori de câte ori Windows cere redesenare. Ecranul este rezultatul stării, nu locul în care păstrezi singura copie a acesteia.
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
Originea coordonatelor este colțul din stânga sus; x crește spre dreapta, y spre jos. Rectangle descrie poziția și dimensiunile figurii. Evenimentul Paint oferă Graphics prin PaintEventArgs. Nu elibera e.Graphics, fiindcă nu l-ai creat și nu îi deții durata de viață. Eliberează însă pensulele și creioanele create de tine.
Butonul schimbă lățimea dreptunghiului, apoi apelează Invalidate. Acesta solicită redesenare, fără să execute imediat și repetat un ciclu manual. DoubleBuffered reduce pâlpâirea pentru acest formular simplu. Paint doar citește modelul și desenează, fără să adauge puncte sau să schimbe dimensiunea.
Exemplu și rezultat așteptat
Dreptunghiul pornește la (30, 70), cu lățime 120 și înălțime 60. Un click mărește lățimea la 140. După minimizare și restaurare, figura rămâne de 140, fiindcă Paint o reconstruiește din câmpul width. La limita 240, următorul click revine la 120.
Model: width 120 → Click: width 140 → Invalidate → Paint: dreptunghi 140×60.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
{
int width=120;
public LessonForm() {
Text="Desen din model"; ClientSize=new Size(400,220); DoubleBuffered=true;
var change=new Button {Left=20,Top=15,Width=170,Text="Schimba latimea"};
change.Click += (sender,e) => { width=width>=240 ? 120 : width+20; Invalidate(); };
Controls.Add(change);
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
using(var brush=new SolidBrush(Color.SeaGreen)) e.Graphics.FillRectangle(brush,30,70,width,60);
e.Graphics.DrawString("Latime: " + width,Font,Brushes.Black,30,150);
}
}
Greșeli și limite
Nu modifica modelul în Paint: frecvența apelurilor depinde de sistem și nu reprezintă pașii unui joc. Nu crea un Timer pentru a reface permanent un desen static. Nu păstra Graphics într-un câmp pentru folosire ulterioară. Pentru mai multe forme, păstrează o colecție de date geometrice și parcurge-o la redesenare.
Exersează
Adaugă o a doua figură și un buton care schimbă numai culoarea. Verifică restaurarea după acoperirea ferestrei. Mută dreptunghiul în dreapta cu 10 pixeli la fiecare click și stabilește o limită raportată la ClientSize.Width. Explică ce trebuie recalculat când fereastra este micșorată.
Continuă parcursul
Parcursul complet de 50 de lecții
Lecția precedentă: C#: afișarea imaginilor și eliberarea resurselor
Lecția următoare: C#: selectarea figurilor prin coordonatele mouse-ului.
Referință: documentația Microsoft.
Întrebări frecvente
De ce dispare desenul făcut direct?
Zona poate fi invalidată și redesenată de Windows. Datele trebuie reprezentate din nou în Paint.
Invalidate desenează forma?
Solicită redesenarea; handler-ul Paint produce efectiv imaginea din model.
Eliberez e.Graphics?
Nu. Eliberezi numai resursele grafice pe care le creezi și le deții.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.