Bonjour,
Je débute dans la programmation "moderne" avec C#.
En effet, j'ai une bonne expérience en mode console et Windows Forms, ainsi que mobile à l'époque de Windows Mobile 5 et 6... Mais WPF, XAML et autres consors sont pour moi du chinois.
Je fais donc faire (et je pense que c'est là que ça pose problème) un parallèle avec ce que je ferais en Windows Forms.
J'ai une application, dans laquelle j'alimente un fichier qui me sert de mini base de donnée.
Je souhaite, dans un écran, faire afficher le contenu de ce fichier sous forme d'un graphique (des lignes).
En Windows Forms, j'aurais créé un custom control, j'aurais surchargé OnPaint, puis j'aurais dessiné à l'aide d'un Graphics.
Mais là, pas trouvé de OnPaint sur un custom control. En lieu et place, j'ai trouvé Polyline, qui, finalement, me permet de remplacer sans difficulté la Graphics et DrawLines.
Seulement voilà, j'ai beau avoir créé un custom control de taille respectable, que j'ai intégré dans un écran de taille respectable, je dessine dans un timbre poste.
J'ai donc voulu mesurer la taille de mon custom control, mais rien à faire : tout ce qui parle de width et height est doit égal à 0 soit à NaN (quand c'est pas int.MaxValue). Bref, pas moyen de mesurer la taille de mon contrôle afin de dessiner mon graphique de façon proportionnelle.
Voici mon code :
CourbePoids.xaml
Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 <UserControl x:Class="SuiviPoids.CourbePoids" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:SuiviPoids" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="140" d:DesignWidth="225.333"> <Canvas x:Name="canvas" Margin="0,10,193,163"> <Polyline x:Name="poly1" Stroke="Blue" StrokeThickness="4" Points="10,100,60,40,130,40,180,20" Margin="10"/> <Polyline x:Name="poly2" Stroke="Red" StrokeThickness="4" Points="10,80,60,30,130,30,180,40" Margin="10"/> </Canvas> </UserControl>
CourbePoids.xaml.cs
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Shapes; namespace SuiviPoids { public sealed partial class CourbePoids : UserControl { private Dictionary<string, Dictionary<DateTime, float>> Series = new Dictionary<string, Dictionary<DateTime, float>>(); private Color[] LineColors = new Color[] { Colors.Red, Colors.Blue, Colors.Green }; public CourbePoids() { // Sample data Dictionary<DateTime, float> serie1 = new Dictionary<DateTime, float>(); serie1.Add(DateTime.Now.AddDays(-10), 76.4f); serie1.Add(DateTime.Now.AddDays(-7), 74.6f); serie1.Add(DateTime.Now.AddDays(-3), 75.1f); serie1.Add(DateTime.Now.AddDays(-1), 73.2f); Dictionary<DateTime, float> serie2 = new Dictionary<DateTime, float>(); serie2.Add(DateTime.Now.AddDays(-10), 46.4f); serie2.Add(DateTime.Now.AddDays(-8), 46.5f); serie2.Add(DateTime.Now.AddDays(-4), 45.9f); serie2.Add(DateTime.Now.AddDays(-2), 45.5f); Series.Add("Sylvain", serie1); Series.Add("Stéphanie", serie2); this.InitializeComponent(); } public void SetRecords(DBRecord[] records) { Series = new Dictionary<string, Dictionary<DateTime, float>>(); Dictionary<DateTime, float> serie = new Dictionary<DateTime, float>(); foreach (DBRecord record in records) { serie.Add(record.Date.DateTime, record.Poids); } Series.Add("Série 1", serie); Redraw(); } public void Redraw() { canvas.Children.Clear(); double availableX = canvas.ActualWidth; // Saperlipopette ! double availableY = canvas.ActualHeight; int numSerie = 0; // get min and max X and Y DateTime minX = DateTime.MaxValue; DateTime maxX = DateTime.MinValue; double minY = float.MaxValue; double maxY = float.MinValue; foreach (KeyValuePair<string, Dictionary<DateTime, float>> Serie in Series) { foreach (KeyValuePair<DateTime, float> Valeur in Serie.Value) { if (Valeur.Key < minX) { minX = Valeur.Key; } if (Valeur.Key > maxX) { maxX = Valeur.Key; } if (Valeur.Value < minY) { minY = Valeur.Value; } if (Valeur.Value > maxY) { maxY = Valeur.Value; } } } double Xlength = maxX.Subtract(minX).Days; double Ylength = maxY - minY; double ratioX = availableX / Xlength; double ratioY = availableY / Ylength; foreach (KeyValuePair<string, Dictionary<DateTime, float>> Serie in Series) { Polyline poly = new Polyline(); poly.Stroke = new SolidColorBrush(LineColors[numSerie++ % 3]); foreach (KeyValuePair<DateTime, float> Valeur in Serie.Value) { poly.Points.Add(new Point((double)Valeur.Key.Subtract(minX).Days * ratioX, ((double)Valeur.Value - minY) * ratioY)); } canvas.Children.Add(poly); } } } }
MainPage.xaml (extrait)
Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 <local:CourbePoids x:Name="courbePoids" Margin="9,107,23,369" RenderTransformOrigin="0,0.5"> <local:CourbePoids.RenderTransform> <CompositeTransform ScaleY="-1"/> </local:CourbePoids.RenderTransform> </local:CourbePoids>
MainPage.xaml.cs (extrait)
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public async Task DisplayItems() { DBRecord[] records = await DBManager.ChargePoids(); courbePoids.SetRecords(records); }
C'est dans la méthode "Redraw()" de CourbePoids.xaml.cs que j'ai mon problème. Quand elle est appelée, tout mon écran est déjà dessiné.
Aussi, comment rendre la taille et le positionnement de mes contrôles dynamiques, comme c'est possible de le faire avec Windows Forms, avec les Dock et Anchor ?
Partager