Entwickler-Ecke

C# - Die Sprache - Variablen sind abhängig von einander


Namenlosnameless - Fr 15.10.10 16:52
Titel: Variablen sind abhängig von einander
Hallo!

Ich habe mir ein Buch über C# gekauft, dabei wird ein simples Zeichenprogramm vorgestellt, dass jede Millisekunde einen Punkt auf die aktuelle Position des Cursers setzt!
Das liefert allerdings nicht sonderlich schöne Ergebnisse...

Darum will ich einfach nur fast das gleiche machen, nur das ich mit Splines arbeiten will!

Das Zeichnen lasse ist ziemlich einfach und auch schon (bis auf ein paar Feinheiten) fertig, ich will das aber auch nicht wirklich ausbauen weil es ein Üungsprojekt ist.
Allerdings ist es nicht sonderlich vorteilhaft, wenn beim Neuzeichnen des Fensters alles selber gemalte gelöscht ist. Dabei habe ich ein Problem. Ich will sobald die linke Maustaste losgelassen wird um das Zeichnen zu beenden alle in einer Liste gespeicherten Punkte an ein Objekt "Spline" weitergegeben und dieser Spline dann in einer weiteren List gespeichert werden. In der Methode in der die Splines "gespeichert" werden, wird am Schluss die List mit den alten Punkten geleert. Dabei werden auch die Punkte im gespeichertem Spline geleert! Warum??



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MySimpleDrawingApp
{
    public partial class Form1 : Form
    {
        Graphics g;
        Timer th = new Timer();
        Timer th1 = new Timer();
        List<Spline> Splines = new List<Spline> { };
        List<Point> lP1 = new List<Point> { };

        public Form1()
        {
            InitializeComponent();

            th.Interval = 3;
            th.Tick += new EventHandler(th_Tick);
            th1.Interval=15;
            th1.Tick+=new EventHandler(th1_Tick);
        }

        void th1_Tick(object sender, EventArgs e)
        {
            Point[]  lP = lP1.ToArray();
            if (lP.Length >= 5)
            {
                 g= panel1.CreateGraphics();
                g.DrawCurve(new Pen(new SolidBrush(Color.Red)), lP);
                
            }
        }

        void th_Tick(object sender, EventArgs e)
        {
            lP1.Add(Cursor.Position);
            
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button==MouseButtons.Left)
            {
                lP1.Add(Cursor.Position);
                th.Start();
                th1.Start();
                
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                th.Stop();
                th1.Stop();
                Spline spline = new Spline(lP1);
                Splines.Add(spline);
                
               lP1.Clear();
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            
            Pen pen=new Pen(new SolidBrush(Color.Red));
            foreach (Spline spline in Splines)
            {
                if (Splines.Count != 0)
                {
                    if (spline.lp2.Count >= 5)
                    {
                        e.Graphics.DrawCurve(pen, spline.lp2.ToArray());
                    }
                }
            }
        }
    }
}


Und hier die Spline Klasse:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace WindowsFormsApplication5
{
    class Spline
    {
        public List<Point> lp2 = new List<Point> { };
        public Spline(List<Point> lP)
        {
            lp2 = lP;
        }
       
    }
}


kann mir bitte irgendjemand helfen... ich hatte noch nie so ein Problem!

mfg Christoph


Kha - Fr 15.10.10 17:26

List<> ist eine Klasse, also ein Referenztyp. Du übergibst die Referenz in lp2 an die Klasse, aber beide verweisen immer noch auf dasselbe Objekt. Deshalb musst du innerhalb der Klasse eine Kopie der Liste anlegen.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
class Spline
{
  List<Point> points;

  public Spline(IEnumerable<Point> points)
  {
    this.points = points.ToList();
  }

  public void Draw(Graphics g, Pen pen) { ... }
}

Dabei habe ich noch gleich ein paar andere Punkte eingebaut:


/edit: Über die Zeile if (Splines.Count != 0) würde ich noch einmal nachdenken :) .
Außerdem habe ich dein Konzept übernommen, erst für eine fertige Spline ein Objekt zu erzeugen. Sinnvoller wäre es aber wahrscheinlich, auch für die aktuell gezeichnete Spline bereits ein Objekt anzulegen und die Punkte nach und nach hinzuzufügen.


Namenlosnameless - Fr 15.10.10 21:00

Wow... so einfach war das XD


Zitat:
Über die Zeile if (Splines.Count != 0) würde ich noch einmal nachdenken :) .


das ist nur ein Überbleibsel von Zahlreichen Debugging Vorgängen :lol:

Dankeschön!