9
votes

Quelle est la bonne façon de dessiner une ligne avec la souris en C #

Ceci est mon code de dessin pour dessiner une ligne personnalisée avec la souris sur un graphique. Pouvez-vous m'aider s'il vous plaît à le faire correctement?

namespace Grafi
    {
        public partial class Form1 : Form
        {

            bool isDrawing = false;
            Point prevPoint;

            public Form1()
            {
                InitializeComponent();
            }

            private void chartTemperature_MouseDown(object sender, MouseEventArgs e)
            {
                isDrawing = true;
                prevPoint = e.Location;
            }

            private void chartTemperature_MouseMove(object sender, MouseEventArgs e)
            {
                Pen p = new Pen(Color.Red, 2); 
                if (isDrawing)
                {
                    Graphics g = chartTemperature.CreateGraphics();    
                    g.DrawLine(p, prevPoint, e.Location);
                    prevPoint = e.Location;

                    numOfMouseEvents = 0;              
                }
                p.Dispose();
            }

            private void chartTemperature_MouseUp(object sender, MouseEventArgs e)
            {
                isDrawing = false;
            }
        }
    }


4 commentaires

Pouvez-vous expliquer, qu'entendez-vous exactement par correctement ? Dans n'importe quel cas , vous devrez gérer le Mouse UP / Down / Down / Move Événements.


Pour plus de précision, cette question est en réponse à une question soulevée dans la réponse à une question précédente: Stackoverflow.com/questions/4164190/... . Il veut connaître le meilleur moyen de modifier le code existant pour dessiner dans l'événement , au lieu d'utiliser Creategraphics .


Il existe différents types d'échantillons de peinture d'échantillons sur CodeProject. Ils vont du très simple à assez complexe. Vérifiez certains d'entre eux. Vous verrez les différentes manières dont vous pouvez le faire correctement, bien que toutes les méthodes impliquent des points de déplacement de la souris dans une collection et la redéfinir dans un gestionnaire d'événements de peinture.


Il suffit de décider de préparer un échantillon basé sur l'idée des coups enregistrés de la peinture. S'il vous plaît voir le code dans ma réponse ci-dessous. (En fait, je l'ai testé.)


4 Réponses :


0
votes

J'ai posté un solution un moment Sur la façon de dessiner une ligne à l'aide de mouvements de la souris. Cela devrait fonctionner pour vous.

  Point mAnchorPoint = new Point(200, 200);
  Point mPreviousPoint = Point.Empty;

  private void panel1_MouseMove(object sender, MouseEventArgs e)
  {
     if (mPreviousPoint != Point.Empty)
     {
        // Clear last line drawn
        ControlPaint.DrawReversibleLine(PointToScreen(mAnchorPoint), PointToScreen(mPreviousPoint), Color.Pink);
     }

     // Update previous point
     mPreviousPoint = e.Location;
     mPreviousPoint.Offset(myPanel1.Location);

     // Draw the new line
     ControlPaint.DrawReversibleLine(PointToScreen(mAnchorPoint), PointToScreen(mPreviousPoint), Color.Pink);
  }


2 commentaires

-1 Veuillez poster quelques extraits du code et une brève explication avec votre lien. Répondre à @cross et je vais +1.


@Cross - Mise à jour. Faites-moi savoir si vous souhaitez plus de détails.



1
votes

Avez-vous des problèmes avec votre mise en œuvre actuelle? Est-ce que cela fonctionne, ou voulez-vous simplement rendre le code mieux pour une fonction déjà de travail?

Je pense que la logique semble très bien. Cependant, j'ajouterais une clause à l'aide du stylo comme celui-ci: xxx

De cette façon, votre stylo sera disposé même en cas d'exception de toute exception après sa création et votre appel à éliminer .

Cependant, vous pouvez également penser à faire de la variable de classe une variable de classe afin de ne pas avoir à créer et à le disposer chaque fois que vous Déplacez la souris.


2 commentaires

Le problème est que lorsque je redimensionnez la forme, ma ligne disparaît. Il disparaît lorsque l'événement de l'onpaint est soulevé.


@Primoz - C'est parce que vous ne stockez pas les points partout. Faites une collection de points de départ et de points de terminaison, ainsi que sur MouseUp, vous ajoutez le point de départ actuel et le point de terminaison des collections. Puis remplacez l'événement Onpaint et lorsque la fenêtre est repeinte, boucle à travers la collection et peignez les lignes à l'aide de l'objet graphique du graphique.



1
votes

Vous devez stocker votre ligne quelque part.

Les étapes que vous devez prendre sont:

  1. Créez quelque part pour stocker vos points dans la classe principale, par exemple. Un ArrayList >> - Où chaque ArrayList contient la liste des points d'une ligne.
  2. Attendez les événements de MouseDown et créez un tableau pour une nouvelle ligne (E.g A Nouvelle ArrayList ) à la fin de la liste des lignes
  3. Attendez les événements Mousemoved et ajoutez un point à la dernière ligne de votre liste, chaque fois que la souris est traînée. Demandez à mettre à jour votre fenêtre ici.
  4. dans votre peinture , itérer à travers toutes les lignes et dessinez chaque point de chaque ligne dans le tableau.
  5. Pour effacer le dessin, remplacez simplement une matrice avec une liste vierge et mettez à jour la fenêtre.

    Si vous ne stockez pas vos lignes quelque part, ils seront perdus. Cela a-t-il de sens?

    L'autre moyen de stocker des lignes consiste à utiliser un objet Canvas , où la carte de pixel de ce qui est dessinée est mémorisée et dessinée automatiquement. Si cela ne vous dérange pas de ne pas avoir vos données de ligne comme des points vectoriels et que vous souhaitiez également utiliser des images ou des couleurs, cela pourrait être une meilleure approche.


0 commentaires

9
votes

Essayez ceci ... c'est une méthode de dessin de course, implémentée très simplement et aussi proche que possible de votre propre code. Les Stokes sont des collections individuelles de mouvements de la souris. Chaque mouvement de souris entre le bas et le haut est enregistré comme une course, tous les coups sont collectés, puis redessinés chaque fois que l'événement de la peinture est viré. Cet exemple est simple mais pourrait être un bon point de départ.

Notez que vous devrez ajouter le gestionnaire de peinture pour votre objet graphique. xxx


2 commentaires

J'ai essayé votre méthode, cela fonctionne, mais mon panneau "clignote" quand je dessine. Il est probablement due aux appels d'actualisation continus (j'utilise une méthode invalidate (FALSE)). Connaissez-vous une solution de contournement?


@Nick: Oui, il y a. C'est vraiment une question distincte, mais vous devez définir la propriété DoubleBuffered de votre contrôle sur True. Double tampon empêche le scintillement. Voyez ici: msdn.microsoft.com/en-us/library/... Une note de prudence cependant: la dernière fois que tout dessin personnalisé était avec .NET 2.0. Dans cette version définissant la propriété DoubleBuffer n'était pas aussi simple pour certains contrôles. Form.Doublebuffered était facile mais certains contrôles ont nécessité un appel différent, alors faites attention à cela.