web-dev-qa-db-fra.com

Comment dessiner sur une fenêtre dans WPF (meilleure pratique)?

J'essaie d'écrire une petite application de type jeu interactif, où j'ai besoin d'avoir une méthode Draw qui va dessiner à l'écran, mais je ne sais pas comment structurer la méthode pour WPF.

Si c'était Winforms, je pourrais utiliser:

public void Draw (Graphics g)
{

}

Mais pour un WPF Window, que dois-je y avoir dans le xaml (actuellement seulement un Grid), et que doit recevoir cette méthode Draw comme argument?

Je veux d'abord le faire comme ça pour le faire fonctionner, puis je peux penser à comment le rendre plus WPF, etc. Mais maintenant, je suis plus intéressé à faire fonctionner cela.

25
Joan Venge

En règle générale, vous "dessinez" dans WPF d'une manière complètement différente.

Dans Windows Forms/GDI, l'API graphique est une API graphique en mode immédiat. Chaque fois que la fenêtre est actualisée/invalidée, vous dessinez explicitement le contenu à l'aide de Graphics.

Dans WPF, cependant, les choses fonctionnent différemment. Vous dessinez rarement rarement directement - c'est plutôt une API graphique en mode conservé. Vous dites à WPF où vous voulez les objets, et il s'occupe du dessin pour vous.

La meilleure façon d'y penser est, dans Windows Forms, vous diriez "Tracez une ligne de X1 à Y1. Puis tracez une ligne de X2 à Y2. Ensuite ...". Et vous répétez cela chaque fois que vous avez besoin de "redessiner" car l'écran est invalidé.

Dans WPF, à la place, vous dites "Je veux une ligne de X1 à Y1. Je veux une ligne de X2 à Y2". WPF décide alors quand et comment le dessiner pour vous.

Pour cela, placez les formes sur un canevas, puis laissez WPF faire tout le travail.

20
Reed Copsey

Lorsqu'il y a trop d'objets à dessiner très rapidement (énorme arbre visuel), une autre option serait d'utiliser un WriteableBitmap. Utilisez simplement la propriété Pixels pour définir les pixels et/ou utilisez la méthode Render pour dessiner UIElements.

9
Erno

Je préfère utiliser la méthode OnRender comme dans cet exemple:

protected override void OnRender(DrawingContext drawingContext)
{
    base.OnRender(drawingContext);
     drawingContext.DrawRectangle(null, new Pen(Brushes.Black, 2), new Rect(0, 0, ActualWidth, Height));
}
6
Marek Kwiendacz

Pour implémenter un comportement de type boucle Draw dans WPF, vous pouvez utiliser l'événement CompositionTarget.Rendering. Ceci est augmenté une fois par image lorsque le système de dessin WPF peint des images.

Comme d'autres l'ont souligné, ce n'est pas très convivial pour WPF mais cela fonctionnera et peut être utilisé pour obtenir un comportement de dessin plus immédiat d'une application WPF.

Dans la plupart des cas, vous utiliseriez un canevas racine unique et mettriez à jour, par exemple, la position du canevas d'un élément sur l'événement CompositionTarget.Rendering.

Par exemple, pour faire voler une ellipse sur tout l'écran, procédez comme suit:

Dans votre XAML (pour une fenêtre de 640 x 480):

<Canvas x:Name="theCanvas">
    <Ellipse x:Name="theEllipse" Height="10" Width="10" Fill="Black" />     
</Canvas>

Dans votre code derrière la fenêtre dans laquelle se trouve le XAML ci-dessus (assurez-vous d'ajouter une référence à System.Windows.Media afin de voir l'objet CompsitionTarget:

    public static Random Rand = new Random();
    public View()
    {
        InitializeComponent();
        CompositionTarget.Rendering += CompositionTarget_Rendering;
    }

    void CompositionTarget_Rendering(object sender, System.EventArgs e)
    {
        double newLeft = Rand.Next(0, 640);
        double newTop = Rand.Next(0, 480);

        theEllipse.SetValue(Canvas.LeftProperty,newLeft);
        theEllipse.SetValue(Canvas.TopProperty, newTop);
    }
4
Brad Cunningham

Vous devez ajouter un canevas (ou modifier la grille d'un canevas), puis dessiner dessus. Voici Microsoft tut sur le dessin sur une toile

De plus, je ne sais pas quel est le lien cette autre question avec la vôtre, mais vous voudrez peut-être la vérifier.

2
Felix Martinez