This question is closely related to this . But once again in brief about the real task : I implement a text editor with support for text formatting (highlighting a fragment of text, changing the typeface of its font, size, etc.). To solve this problem chose Text Formatter . Now I am interested in the implementation of a text store, for which it is necessary to inherit and implement the abstract TextSource class. To figure out how to do this, I would like to see some examples. It is desirable more complex than in the official example .
- I got the answer here . - Artemy pm
- Voted for re-opening the issue. If it is rediscovered, publish it as an answer? - VladD
- @VladD, Good evening. No problem. Recently noticed that the question was closed. - Artemy
- oneOpen, you can answer) - YurySPb β¦
|
1 answer
The answer to the question received on the MSDN forum - link . I give the example code below:
class SampleTextSource : TextSource { string text = "Foo Bar\nNext Line"; List<Span> spans = new List<Span> { new Span { Start = 0, Length = 3, Color = Brushes.Blue }, new Span { Start = 3, Length = 1, Color = Brushes.Black }, new Span { Start = 4, Length = 3, Color = Brushes.Red }, new Span { Start = 7, Length = 1, Color = Brushes.Black }, new Span { Start = 8, Length = 4, Color = Brushes.Green }, new Span { Start = 12, Length = 5, Color = Brushes.Black }, }; class Span { public int Start; public int Length; public Brush Color; public bool Contains(int index) { return Start <= index && index < Start + Length; } } public int Length { get { return text.Length; } } public override TextRun GetTextRun(int textSourceCharacterIndex) { var span = spans.Find(s => s.Contains(textSourceCharacterIndex)); if (span == null) return new TextEndOfParagraph(1); if (span.Length == 1 && text[span.Start] == '\n') return new TextEndOfLine(1); return new TextCharacters(text, span.Start, span.Length, new SampleTextRunProperties(span.Color)); } public override TextSpan<CultureSpecificCharacterBufferRange> GetPrecedingText(int textSourceCharacterIndexLimit) { throw new NotImplementedException(); } public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int textSourceCharacterIndex) { throw new NotImplementedException(); } } class SampleTextRunProperties : TextRunProperties { private readonly Brush foregroundBrush; public SampleTextRunProperties(Brush foregroundBrush) { this.foregroundBrush = foregroundBrush; } ...ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΡ
ΡΠ²ΠΎΠΉΡΡΠ² (ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡΡ ΠΈΠ· SDK-ΠΏΡΠΈΠΌΠ΅ΡΠ°) } class SampleTextParagraphProperties : TextParagraphProperties { ...ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΡ
ΡΠ²ΠΎΠΉΡΡΠ² (ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡΡ ΠΈΠ· SDK-ΠΏΡΠΈΠΌΠ΅ΡΠ°) } class SampleTextElement : UIElement { protected override void OnRender(DrawingContext drawingContext) { TextFormatter text = TextFormatter.Create(); SampleTextSource source = new SampleTextSource(); SampleTextParagraphProperties paraProps = new SampleTextParagraphProperties(); int index = 0; double y = 0.0; while (index < source.Length) { TextLine line = text.FormatLine(source, index, RenderSize.Width, paraProps, null); line.Draw(drawingContext, new Point(0.0, y), InvertAxes.None); index += line.Length; y += line.TextHeight; } } } An SDK example can be downloaded here .
If you want the text to be displayed with the transfer (and this is often required), then you must first override the TextWrapping property in the implementation of the TextWrapping , and second, use the following in the implementation of the TextRun GetTextRun(int textSourceCharacterIndex) method TextRun GetTextRun(int textSourceCharacterIndex) code snippet, instead of the above:
return new TextCharacters(text, textSourceCharacterIndex, span.Length - (textSourceCharacterIndex - span.Start), new SampleTextRunProperties(span.Color)); This is done to support the ability to split a span into several lines.
|