Auf Linie zugreifen können

kuhlmaehn

Erfahrenes Mitglied
Hi!
Ich hab beim Suchen nur gefunden wie ich eine Linie zeichnen kann.
Mein Problem ist nun aber das ich gerne auf jede gezeichnete Linie und am besten auch auf die Eckpunkte zugreifen können möchte.
Ich will also auf die Linie klicken können und zB die Farbe verändern. Oder auch vorhandene Linien verschieben können.
Ich denke dabei an das Line-Steuerelement bei Visual Basic 6.0.

Wie stell ich das am besten an?
Danke!
 

Alexander Schuc

crazy-weasel
Wie stell ich das am besten an?

Kommt drauf an was das Ziel sein soll. Wenn du das einfach nur benutzen willst, um eine Linie darzustellen, könntest du dir ein eigenes Steuerelement schreiben, welches die benötigte Linie darstellt.

Wenns nur horizontal / vertikal sein soll, ohne irgendwelche Extras (diagonal.. runde Ecken bei dickeren Linien..) könntest ein Panel missbrauchen. Das wäre für dich am wenigsten Aufwand. *G*

lg, Alex
 

kuhlmaehn

Erfahrenes Mitglied
Danke für die schnelle Antwort :)
Also um Grunde könnte ich sogar drauf verzichten, dass man die Linien bewegen kann. Mir reicht es, dass man auf eine Linie klicken kann und sie dann eine andere Farbe bekommt. Achso ja und ich will auch diagonale Linien.
Die einzige Möglichkeit die mir einfällt ist, dass man die Koordinaten von der Form nimmt und immer überprüft ob der Klick auf Linie liegt. Aber dann müsste ich ja für jede Linie eine Funktion aufstellen oder? Das muss doch leichter gehen!?
 

Alexander Schuc

crazy-weasel
Die einzige Möglichkeit die mir einfällt ist, dass man die Koordinaten von der Form nimmt und immer überprüft ob der Klick auf Linie liegt. Aber dann müsste ich ja für jede Linie eine Funktion aufstellen oder? Das muss doch leichter gehen!?

Für jede Linie eine eigene Funktion ist nicht gnaz richtig. Einfach im MouseUp Event die Koordinaten prüfen. Die Daten deiner Linien müsstest dann halt speichern.. und bei Bedarf anpassen.

Das ganze solltest dann aber wirklich in ein eigenes Control auslagern. Damit du erstens ohne Probleme mehrere Linien darstellen kannst, ohne das sich der Code in deiner Form vermehrt,..
 

kuhlmaehn

Erfahrenes Mitglied
Mh sorry das ist mir irgendwie nicht ganz klar.
Nehmen wir mal nur eine Linie.. dann müsste ich es doch (wie in der Schule ^^) machen, dass ich den Punkt in die Funktion einsetzt und wenn eine wahre Aussage rauskommt liegt er auf der Geraden. Oder wie könnt das einfacher machen?
Und wenn ich dann mehere linien habe muss ich dann doch mehere Funktionen aufstellen und alle einzeln testen?
Also anders kann ich mir das gerade nich vorstellen vielleicht kannst du mir gerade mal auf die Sprünge helfen :) .
Und wie genau erstellt man Steuerelemente? Muss ich da auf was achten? Und muss da später was mit der exe mitgeliefert werden oder wird das dann reinkompiliert?
 

kuhlmaehn

Erfahrenes Mitglied
Mh ich hab jetzt mal das hier (http://msdn2.microsoft.com/de-de/library/yk3ysydt(VS.80).aspx) ausprobiert. Da ich nicht wusste wie man das nun verwendet habe ich den Inhalt einfach in Form_Paint kopiert.
Das ist aber blöd. Ich würde gerne, dass es beim Klick auf einen Button erstellt wird.
Außerdem muss ich ja den GraphicsPath() überalle verwenden können (zB in Form1_MouseDoubleClick).
Irgendwie steig ich da nicht so ganz durch :(
 

Alexander Schuc

crazy-weasel
Ist jetzt nur ein ganz einfaches, nicht schönes Beispiel wie du das machen könntest, und ich hab jetzt auch nicht die Syntax und dergleichen geprüft.


Es wird ein Button angenommen, bei dessen Betätigung ein neues zu zeichnendes Objekt erstellt wird. Die Infos zum Zeichnen werden in einem GraphicsPath gespeichert, und diese werden in einem Dictionary gemeinsam mit dem zu verwendenden Stift gesammelt.

Bei jedem MouseUp werden die Pfade überprüft, und wenn einer "getroffen" wurde, wird dessen Stift "geändert".

Nur kurz schnell runtergeschrieben.. Syntaxfehler vorbehalten. ;)

C#:
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing;

public class Form1 : Form
{

// ...

  private int colorCount = 0;
  
  public int ColorCount // immer ne andere farbe.. bei jedem aufruf wird hochgezählt.. obere grenze: 255
  {
    get { ++colorCount > 255 ? return 0 : return colorCount; }
  }
  
  private Dictionary<GraphicsPath, Pen> drawings = new Dictionary<GraphicsPath, Pen>();

  private Pen drawingPen = Pens.Black;
  
  private void NewDrawingButton_OnClick(object sender, EventArgs ea)
  {
    GraphicsPath gp = new GraphicsPath();
    gp.AddLine(...);
    
    int color = ColorCount;
    
    drawings.Add(gp, new Pen(Color.FromArgb(color, color, color)));
    
    this.Invalidate();
  }
  
  protected override void OnPaint(object sender, PaintEventArgs ea)
  {
  
    foreach (GraphicsPath gp in drawings.Keys)
    {
      ea.Graphics.DrawPath(drawings[gp], gp);
    }
  
  }
  
  private void Form1_MouseUp(object sender, MouseEventArgs mea)
  {
    foreach (GraphicsPath path in drawings.Keys)
    {
      Pen pen = drawings[path];
      
      if (path.IsOutlineVisible(mea.X, mea.Y, pen))
      {
      // neue farbe setzen ....
        pen.Dispose();
        pen = null;
        int color = ColorCount;
        
        pen = new Pen(Color.FromArgb(color, color, color));
        drawings[path] = pen;
        Invalidate();
        return;
      }
    }
  }
}
 

kuhlmaehn

Erfahrenes Mitglied
Ach verdammt ich find C# irgendwie nicht logisch :(
Vielen Dank auf jeden Fall ich werd das mal außprobieren und mich dann bestimmt nochmal melden. :-(
Wofür ist eigentlich diese Zeile:
C#:
private Dictionary<GraphicsPath, Pen> drawings = new Dictionary<GraphicsPath, Pen>();