Comment dessiner sur une fenêtre dans WPF (best practice)?
J'essaie d'écrire une petite application interactive de type jeu, où j'ai besoin d'une méthode Draw
qui va dessiner à l'écran, mais qui ne peut pas comprendre 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 devrais-je avoir dans le xaml (actuellement seulement un Grid
), et que devrait recevoir cette méthode Draw
comme argument?
D'abord, je veux le faire comme ça pour le faire fonctionner, alors je peux penser à la façon de faire il plus WPF
, etc. Mais maintenant, je suis plus intéressé à faire fonctionner cela.
5 réponses
Typiquement, 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 graphiques.
Dans WPF, cependant, les choses fonctionnent différemment. Vous dessinez rarement directement - à la place, c'est 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 de penser de celui-ci, dans Windows Forms, vous diriez "tracez une ligne de X1 à Y1. Puis tracez une ligne de X2 à Y2. Puis ...". Et vous répétez cela chaque fois que vous avez besoin de "redessiner" puisque 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.
Ceci est fait en plaçant les formes sur un canevas, puis en laissant WPF faire tout le travail dur.
Quand il y a juste 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
.
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));
}
Pour implémenter un comportement de type de Boucle De Tirage dans WPF, vous pouvez utiliser CompositionTarget.Rendu événement. Ceci est soulevé une fois par image lorsque le système de dessin WPF peint des cadres.
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 la position du canevas d'un élément sur CompositionTarget.Rendu événement.
Par exemple, pour faire voler une ellipse sur tout l'écran, Faites ceci:
Dans votre XAML (pour une fenêtre de taille 640 par 480):
<Canvas x:Name="theCanvas">
<Ellipse x:Name="theEllipse" Height="10" Width="10" Fill="Black" />
</Canvas>
Dans votre Code derrière pour la fenêtre dans laquelle se trouve le XAML ci-dessus (assurez-vous d'ajouter une référence au système.Windows.Pour 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);
}
Yow devrait ajouter une toile (ou changer la grille pour une toile), puis dessiner dessus. Voici Microsoft tut sur le dessin sur une toile
Aussi, je ne sais pas à quel point cette autre question est liée à la vôtre, mais vous voudrez peut-être la vérifier.