15. juni 2004 - 01:11Der er
13 kommentarer og 2 løsninger
Tegning med gdi+
Jeg sidder og skal lave et mindre tegne program i c# men har nogen problemer med at finde ud af hvordan jeg kan tegne samtidig med jeg flytter musen. Er der nogen der kan forklare mig hvordan man gør. Så vidt jeg har fundet ud af ser det ud som det har fjernet Draw modes som gjorde det muligt at tegne med xor mode så det ser pænt ud. Det eneste jeg har fundet var disse funktioner til at tegne direkte på kontrollen: ControlPaint.DrawReversibleLine ControlPaint.DrawReversibleFrame
men der kan jeg ikke tegne cirkler og jeg kan heller ikke sætte tykkelsen på pennen.
jeg overvejede også at nedarve fra Graphics klassen og implementere noget funktionalitet fra windows api, men da klassen var endelig kunne jeg heller ikke gøre dette.
Et lille udkast her fra morgenstunden. Tegningen foregår i et panel (Panel1) på en alm. windows form. Der er 2 knapper (buttonDraw og buttonCircle) og en textbox hvori bredden af pennen skrives.
Jeg kan umildbart ikke se ud fra de kode hvordan jeg f.eks kan tegne en cirkel mens jeg flytter mussen, du tegner cirklen efter du slipper musen. Det jeg er udeefter er at kunne tegne en cirkel mens jeg flytter mussen hvor den sletter den gamle cirkel så der ikke er 300 cirkler på skærmen når man rykker rundt på musen. I MFC verden tror jeg det hedder XOR mode som sletter den gamle cirkel ved at tegne cirklen oven i igen
Min løsning (Jeg laver en seperat kommentar, hvor jeg kommenterer den nøjere): using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data;
namespace CircleTest { public class Form1 : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; private bool IsMouseDown = false; private int CircleStartX = 0, CircleStartY = 0; private int CircleX = 0, CircleY = 0; private int CircleR = 0;
public Form1() { InitializeComponent(); Paint += new PaintEventHandler(DoPaint); MouseDown += new MouseEventHandler(DoMouseDown); MouseUp += new MouseEventHandler(DoMouseUp); MouseMove += new MouseEventHandler(DoMouseMove); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); }
#region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 273); this.Name = "Form1"; this.Text = "Form1";
Contructoreren: Binder fire events: Paint, MouseDown, MouseUp og MouseMove - dem skal vi bruge.
Med PaintEventet, får vi mulighed for selv at tegne på Controllen (Windows Formens's) Canvas.
- bemærk dette statement: SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
Hvis vi ikke gør det, så flimrer det mens vi flytter musen - .NET's svar på DoubleBuffering - med kun én linje kode.
De tre Museevents: Når musen trykkes ned, sætter jeg Cirklens centrum koordinat, samt et punkt på cirkel periferien (Cirkelsn ligning, anyone?).
I MouseUp, sætter jeg boolean variablen - IsMouseDown, til false... Navnet giver sig selv.
MouseMove. Her flytter vi punktet på cirkel periferien, og udregner en ny radius. Da jeg desværre ikke kan huske Cirklens ligning uden at konsulterer min matematikbog fra 1G, så bruger jeg bare Pythagoras's ligning til at finde radius på cirklen.
DoPaint: Hvis IsMouseDown er true, så tegner den en cirkel, med den dertil skabte funktion. Da der ikke er en DrawCircle funktion, bruger jeg en elipse, med identisk højde og brede - derfor den lidt omskrevede funktion PaintCircle.
--
Jeg håber det var dét du mente med dit spørgsmål :)
mange takker :) jeg har en document klasse som er en user control som indeholder en picture box hvor jeg skal kunne tegne i, og flytte rundt på de forskellige figure, men det med at flytte rundt på tingene burde ikke være noget problem når det andet er på plads.
jeg har lige selv siddet og rodet lidt med det. jeg kan ikke helt forstå du vil nedarve fra usercontrols er det ikke nemmenre at nedarve direkte fra picturebox klassen. Det har jeg lige gjort og det virker
men er det den rigtige måde at gøre det på, eller burde man gøre det fra usercontrol sådan som jeg ser det virker det mere logisk at gøre det direkte fra picturebox
Men vil du tegne Cirklerne oven på et billede? - i såfald giver det fin mening at bruge PictureBox :)
Det virker fint i PictureBox - fordi den nedarver direkte fra Control.
Hvis du ikke har planer om at bruge noget af det PictureBox kan, så implementerer du bare en masse kode som du alligevel ikke skal bruge. Det undgår du ved at bruge Control direkte.
det jeg skal er sådanset bare at kunne tegne et statediagram og kunne generere noget xml ud fra det og herudover kunne gemme billedet som bitmap ud fra det jeg har tegnet. jeg skal ikke kunne tegne oven i et billede der. Så bør jeg ikke nedarve fra picture box vel såvidt jeg kunne forstå vel ?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.