Bonjour,
Je suis en train d'essayer de faire un éditeur de code et forcément certaines fonctionnalités basiques sont de rigueur, notamment la coloration syntaxique.
Comme j'ai déjà suffisamment joué avec la RichTextBox et que ce contrôle est trop "poussé" pour faire simplement ce que je souhaite, je me suis mis à essayer d'implémenter mon propre système d'affichage de texte.
Pour le coup, j'utilise une TextBox totalement transparente, et je glisse dessous un FrameworkElement me permettant l'affichage de DrawingVisuals.
Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 <!--Editor Box--> <Border BorderBrush="Black" BorderThickness="1"> <Grid> <local:DrawingCanvas x:Name="canvas" ClipToBounds="True"></local:DrawingCanvas> <TextBox x:Name="tbox" Background="Transparent" Foreground="Transparent" AcceptsReturn="True" AcceptsTab="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible" BorderThickness="0" LayoutUpdated="LayoutUpdatedHandler"></TextBox> </Grid> </Border>
Et le code-behind en est :
Code C# : 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 private void LayoutUpdatedHandler(object sender, EventArgs e) { try { // Récupération du texte présent dans la partie visible de la textbox int lineIndexStart = tbox.GetFirstVisibleLineIndex(); int lineIndexEnd = tbox.GetLastVisibleLineIndex(); String visibleText = ""; for (int i = lineIndexStart; i <= lineIndexEnd; i++) { visibleText += tbox.GetLineText(i); } FormattedText ft = GetFormattedText(visibleText); Rect rect = tbox.GetRectFromCharacterIndex(tbox.GetCharacterIndexFromLineIndex(lineIndexStart)); // Ouverture du DrawingVisual et dessin du texte dans son Context canvas.Open(); canvas.GetContext().DrawText(ft, rect.TopLeft); canvas.Close(); } catch (Exception ex) { return; } } public FormattedText GetFormattedText(String text) { FormattedText ft = new FormattedText( text, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Foreground); return ft; }
Toutefois, cette méthode a de gros problèmes de performances, car dès que la zone d'affichage est un peu grosse et que j'essaie de mettre des dizaines de longues lignes de texte, les perfs s'écroulent. Pourtant, un TextBox classique n'a aucun réel problème de perf.
Quelle est la solution pour afficher efficacement des FormattedText à l'écran ?
Partager