9
votes

Comment dessiner rectangle sur MouseDown / Move C #

Je ne suis pas tout à fait sûr de dessiner un rectangle (non rempli) lorsque je traîne mon MouseDown tout en cliquant sur la souris.

Je l'ai jusqu'à présent xxx

Mais les problèmes que je ne veux pas que tous les rectangles apparaissent


0 commentaires

4 Réponses :


5
votes

n'appelez pas la créationgraphics. À MouseDown, stockez la position de départ et un drapeau pour indiquer que vous dessinez. En MouseMove, vérifiez le drapeau. Si vous dessinez, créez le rectangle par rapport à la position de départ et stockez-le (que vous faites déjà), puis appelez invalidez (). Tous vos codes de dessin seront sur ONPAINT () (Toile.paint de l'extérieur de la classe, même si je voudrais probablement créer ma propre classe pour éviter de joindre votre code de formulaire avec ce truc).

Dessin devrait être fait dans votre gestionnaire de peinture (ONPINGING). Si vous dessinez en dehors de cela, votre objet graphique n'est pas effacé (d'où les multiples rectangles) et tout ce que vous dessinez à celui-ci peut / sera essuyé à des moments apparemment impairs lorsque votre fenêtre reçoit un message WM_Paint.

Edit: Maintenant que vous avez des problèmes de performance, il existe un couple de moyens simples d'optimiser un peu la peinture. Tout d'abord, invalidera éventuellement un rectangle comme argument afin de ne pas avoir à repeindre tout le contrôle. Deuxièmement, si vous dessinez sur MouseMove, vous allez dessiner un peu. L'utilisation de la double tampon vous aidera également beaucoup, il suffit de définir la propriété DoubleBuffered sur true ou de l'ajouter à la valeur de ControlStyle en appelant SetStyle sur le contrôle.


6 commentaires

BTW, je ne suis pas tout à fait sûr de ce qui est invalide pour


@Burnzy, invalide Innvalide les graphiques du contrôle afin que la fonction de peinture soit invoquée à nouveau par Windows. (Fondamentalement, une fois que le contrôle est invalidé, il doit se redéfinir)


une idée de la manière de résoudre le problème vacillant?


J'ai ajouté des conseils. Réalisez également que, si vous appelez de la créationgraphics (que vous ne devriez pas faire ici de toute façon), vous devez également appeler () sur l'objet graphique retourné.


Merci pour la pointe, mais pourquoi devrais-je faire ça?


Étant donné que la classe graphique implémente Idisposable, qui vous indique comme le client qu'il conserve des références aux ressources indigènes et qu'elle doit les libérer avant de sortir de la portée. S'appuyant sur le finaliseur est non déterministe, il est donc préférable d'envelopper la déclaration / l'affectation dans un bloc "Utilisation".



0
votes

D'accord maintenant, j'ai ceci, son travail, mais ça slickers beaucoup, même avec une double tampon. xxx pré>

puis sur la peinture p>

            private void canevas_Paint( object sender , PaintEventArgs e )
            {
                     Graphics g = canevas.CreateGraphics();
                     g.DrawImage( _buffer , new Rectangle( 0 , 0 , canevas.Width , canevas.Height ) );
                     g.DrawRectangle( Pens.White , new Rectangle( _topLeft.X , _topLeft.Y , ( _bottomRight.X - _topLeft.X ) , ( _bottomRight.Y - _topLeft.Y ) ) );
            }


1 commentaires

NE PAS UTILISEZ CREEGRAPHICS (). Utilisez E.Graphics dans l'événement de la peinture.



22
votes

Certains code pour accéder à la réponse correcte de ED:

using System;
using System.Windows.Forms;

class Canvas : Panel {
    public Canvas() {
        this.DoubleBuffered = true;
        this.SetStyle(ControlStyles.ResizeRedraw, true);
    }
}


8 commentaires

Merci, je l'avais correctement, mais cela m'a aidé avec la traînée retournée. :)


Tout semble bien jusqu'à présent, sauf les scintillants, des idées?


J'ai laissé un commentaire, utilisez-vous E.Graphics dans l'événement de peinture? J'ai testé ce code, il est sans scintillement, même sans double tampon.


Oui, je suis cependant que le scintillement pourrait dépendre de l'arrière-plan. Il ne glisse pas si c'est un jeu de jeu, mais sinon ça fait. Éditer NVM, il scintille toujours même lorsque l'arrière-plan est simple


Qu'est-ce que Heck est un "jeu de jeu"? Et ce qui est à l'arrière-plan?


Lol, désolé je voulais dire un gris clair. Le fond est une fractale de Mandelbrot, cependant, il scintille toujours s'il n'y a pas de fond.


n'est-ce pas censé être math.max (StartPos.y, CurrentPos.y) ???? Parce que vous essayez d'obtenir le coin supérieur gauche. en faisant la plus grande variable y


@LURON: Les coordonnées de l'écran démarrent dans le coin supérieur gauche, d'où le plus petit Y est le plus proche de celui-ci correspond au haut de l'écran. ERGO: L'exemple est correct.



0
votes
    public Form1()
    {
        InitializeComponent();
        // Use the cross "+" cursor
        this.Cursor = System.Windows.Forms.Cursors.Cross;
        // This will reduce flicker (Recommended)
        this.DoubleBuffered = true;
    }
Add this code to your form .this may reduce flickering!

0 commentaires