Zeichnen von verschiedenen Formen mit Hilfe von Methoden

Beantwortet Zeichnen von verschiedenen Formen mit Hilfe von Methoden

  • Samstag, 18. Februar 2012 01:29
     
      Enthält Code

    Ich hoffe ich bin als Anfänger hier richtig. Und zwar mein Problem ist folgendes ich möchte ein Zeichenprogramm realisieren mit verschiednen Formen wie Linien, Kreise und Rechtecke. Zu jeder Form gibt es in einem Toolstrip ein Button, der Zeichenbereich soll eine Usercontroll sein. Zum Zeichnen Beispielsweise einer Linie soll man nun in der Usercontroll durch 1 maliges anklicken den Startpunkt setzten und durch einen 2. Klick den Endpunkt. 

    Bisher sieht es bei mir so aus das ich für jede Form eine eigende Klasse erstellt habe, durch den Mouse Event Handler (in der User Control) wird die Methode aufgerufen. (Außerdem wird bei mir noch der Endpunkt mit einem Mouse Up Event gestetzt.) Für das Zeichnen einer Linie sieht das bisher so aus.

                Zeichne_Linie ln = new Zeichne_Linie();
                this.MouseDown += new MouseEventHandler(ln.Linie_Startpunkt);
                this.MouseMove += new MouseEventHandler(ln.Linie_Hilfslinie);
                this.MouseUp += new MouseEventHandler(ln.Linie_Endpunkt);
            

    Jetzt zu meinem Problem: Bisher haben die Buttons noch keine Funktion und ich muss jedesmal per Hand die Methode ändern, wenn ich eine andere Form zeichnen möchte. Meine Frage lautet nun wie ich es elegant Lösen kann das die Buttons eine Funktion erhalten und je nach gewählter Form sich die Methode ändert.

    Danke im Vorraus, ich hoffe ich habe mich verständlich ausgedrückt.



    • Bearbeitet RisingGSM Samstag, 18. Februar 2012 01:32
    •  

Alle Antworten

  • Samstag, 18. Februar 2012 08:39
     
     Beantwortet Enthält Code

    Hi,

    Du kannst die einzelnen Formen von einer Basisklasse erben lassen und diese Klassen dann die Zeichenoperationen ausführen lassen... Iregendwas in dieser Art (hier mit einer ComboBox zur Auswahl):

        public partial class Form1 : Form
        {
            Shape _tmpShape = null;
            List<Shape> _shapes = new List<Shape>();
    
            ComboBox c = new ComboBox();
            private bool _renderTemp;
    
            public Form1()
            {
                InitializeComponent();
    
                //avoid flickering
                this.DoubleBuffered = true;
                this.MouseDown += new MouseEventHandler(Form1_MouseDown);
                this.MouseMove += new MouseEventHandler(Form1_MouseMove);
                this.MouseUp += new MouseEventHandler(Form1_MouseUp);
                this.Paint += new PaintEventHandler(Form1_Paint);
    
                this.ClientSize = new System.Drawing.Size(800, 600);
    
                c.DropDownStyle = ComboBoxStyle.DropDownList;
                c.Items.Add("Line");
                c.Items.Add("Rectangle");
                c.Items.Add("Ellipse");
    
                this.Controls.Add(c);
                c.SelectedIndexChanged += new EventHandler(c_SelectedIndexChanged);
    
                c.SelectedIndex = 0;
            }
    
            void c_SelectedIndexChanged(object sender, EventArgs e)
            {
                GetNewTmpShape();
            }
    
            private void GetNewTmpShape()
            {
                if (c.SelectedIndex == 0)
                    this._tmpShape = new LineShape();
                else if (c.SelectedIndex == 1)
                    this._tmpShape = new RectShape();
                else if (c.SelectedIndex == 2)
                    this._tmpShape = new EllipseShape();
            }
    
            private void Form1_MouseDown(object sender, MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _renderTemp = true;
                    _tmpShape.PtBottomRight = new Point(-1, -1);
                    _tmpShape.PtTopLeft = e.Location;
                }
            }
    
            private void Form1_MouseMove(object sender, MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _tmpShape.PtBottomRight = e.Location;
                    this.Invalidate();
                }
            }
    
            private void Form1_MouseUp(object sender, MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _tmpShape.PtBottomRight = e.Location;
                    this.Invalidate();
    
                    _shapes.Add(_tmpShape);
                    GetNewTmpShape();
                    _renderTemp = true;
                }
            }
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                if (_shapes != null)
                {
                    foreach (Shape sh in _shapes)
                        sh.Render(e.Graphics);
                }
                if (_tmpShape != null && _tmpShape.PtBottomRight.X >= 0 && _renderTemp)
                    _tmpShape.Render(e.Graphics);
            }
        }
    
        public abstract class Shape
        {
            public Point PtTopLeft { get; set; }
            public Point PtBottomRight { get; set; }
            public Color ForeColor { get; set; }
            public float Width { get; set; }
    
            public abstract void Render(Graphics g);
        }
    
        public class LineShape : Shape
        {
            public LineShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawLine(p, PtTopLeft, PtBottomRight);
            }
        }
    
        public class RectShape : Shape
        {
            public RectShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawRectangle(p, new Rectangle(PtTopLeft.X, PtTopLeft.Y, PtBottomRight.X - PtTopLeft.X, PtBottomRight.Y - PtTopLeft.Y));
            }
        }
    
        public class EllipseShape : Shape
        {
            public EllipseShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawEllipse(p, new Rectangle(PtTopLeft.X, PtTopLeft.Y, PtBottomRight.X - PtTopLeft.X, PtBottomRight.Y - PtTopLeft.Y));
            }
        }

    Viele Grüße,

      Thorsten


  • Mittwoch, 22. Februar 2012 21:12
     
     

    Erstmal ein Verspätetes aber dennoch großes Danke für deine Mühe. : ) Das meiste habe jetzt schonmal hingekriegt allerdings habe ich jetzt noch ein Problem und zwar benutze ich ja einmal die Form1 mit Buttons für die Formen und zum anderen ein Benutzersteuerelement auf dem gezeichnet werden soll. Mein Problem besteht nun darin das beide nun komunizieren müssen, den der Zeichenbereich muss ja wissen welcher Button gedrück wurde, um die richtigen Methode zu starten. Also LineShape, RecShape oder EllipseShape. Wenn mir da noch einer helfen könnte wäre das Super.

    Danke : )


    • Bearbeitet RisingGSM Mittwoch, 22. Februar 2012 21:13
    •  
  • Mittwoch, 22. Februar 2012 21:57
     
     Beantwortet Enthält Code

    Hi,

    wenn das entsprechende Shape vom ZeichenControl ausgewählt werden soll, dann machte dieses Control das ja aufgrund von bestimmten Kriterien, zum Beispiel ein int index, oder so. Somit kannst Du eine public Property in Deinem Control definieren, der Du dann das entsprechende Kriterium (wenn der entsprechende Button gedrückt wurde) zuweist.

    Das gleiche Beispiel wie oben, nur mit einem (custom) Panel als Zeichenbereich:

        public partial class Form1 : Form
        {
            ComboBox c = new ComboBox();
            DBCanvas p = new DBCanvas();
    
            public Form1()
            {
                InitializeComponent();
    
                //avoid flickering
                p.Dock = DockStyle.Fill;
                this.Controls.Add(p);
    
                this.ClientSize = new System.Drawing.Size(800, 600);
    
                c.DropDownStyle = ComboBoxStyle.DropDownList;
                c.Items.Add("Line");
                c.Items.Add("Rectangle");
                c.Items.Add("Ellipse");
    
                this.Controls.Add(c);
                c.SelectedIndexChanged += new EventHandler(c_SelectedIndexChanged);
    
                c.SelectedIndex = 0;           
                c.BringToFront();
            }
    
            void c_SelectedIndexChanged(object sender, EventArgs e)
            {
                p.Index = c.SelectedIndex;
                p.GetNewTmpShape();
            }
        }
    
        public class DBCanvas : Panel
        {
            Shape _tmpShape = null;
            List<Shape> _shapes = new List<Shape>();
    
            private bool _renderTemp;
    
            public int Index { get; set; }
    
            public DBCanvas()
            {
                this.DoubleBuffered = true;
                this.BackColor = SystemColors.ControlDark;
            }
    
            protected override void OnMouseDown(MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _renderTemp = true;
                    _tmpShape.PtBottomRight = new Point(-1, -1);
                    _tmpShape.PtTopLeft = e.Location;
                }
            }
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _tmpShape.PtBottomRight = e.Location;
                    this.Invalidate();
                }
            }
            protected override void OnMouseUp(MouseEventArgs e)
            {
                if (_tmpShape != null && e.Button == MouseButtons.Left)
                {
                    _tmpShape.PtBottomRight = e.Location;
                    this.Invalidate();
    
                    _shapes.Add(_tmpShape);
                    GetNewTmpShape();
                    _renderTemp = true;
                }
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                if (_shapes != null)
                {
                    foreach (Shape sh in _shapes)
                        sh.Render(e.Graphics);
                }
                if (_tmpShape != null && _tmpShape.PtBottomRight.X >= 0 && _renderTemp)
                    _tmpShape.Render(e.Graphics);
            }
    
            public void GetNewTmpShape()
            {
                if (Index == 0)
                    this._tmpShape = new LineShape();
                else if (Index == 1)
                    this._tmpShape = new RectShape();
                else if (Index == 2)
                    this._tmpShape = new EllipseShape();
            }
        }
    
        public abstract class Shape
        {
            public Point PtTopLeft { get; set; }
            public Point PtBottomRight { get; set; }
            public Color ForeColor { get; set; }
            public float Width { get; set; }
    
            public abstract void Render(Graphics g);
        }
    
        public class LineShape : Shape
        {
            public LineShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawLine(p, PtTopLeft, PtBottomRight);
            }
        }
    
        public class RectShape : Shape
        {
            public RectShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawRectangle(p, new Rectangle(PtTopLeft.X, PtTopLeft.Y, PtBottomRight.X - PtTopLeft.X, PtBottomRight.Y - PtTopLeft.Y));
            }
        }
    
        public class EllipseShape : Shape
        {
            public EllipseShape()
            {
                this.ForeColor = Color.Black;
                this.Width = 1;
            }
    
            public override void Render(Graphics g)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                using (Pen p = new Pen(ForeColor, Width))
                    g.DrawEllipse(p, new Rectangle(PtTopLeft.X, PtTopLeft.Y, PtBottomRight.X - PtTopLeft.X, PtBottomRight.Y - PtTopLeft.Y));
            }
        }

    Viele Grüße,

      Thorsten

  • Mittwoch, 22. Februar 2012 22:11
     
     

    Ahh, so kann man das nartürlich auch machen ist irgendwie auch viel leichter als meine Variante. Vielen Herzlichen Dank nochmal du hast mir sehr geholfen. Einen schönen Abend noch. : )

    • Bearbeitet RisingGSM Mittwoch, 22. Februar 2012 22:11
    •  
  • Donnerstag, 23. Februar 2012 00:54
     
     

    ... vernünftigerweise sollte man aber nicht einfach einen int zur Auswahl nehmen, sondern eher eine enum erstellen und dann Werte davon auswählen.

    Viele Grüße,

      Thorsten