Данный вопрос тесно связан с этим. Но ещё раз вкратце о реальной задаче: реализую текстовый редактор с поддержкой форматирования текста (выделение фрагмента текста, изменение гарнитуры его шрифта, размера и т.п.). Для решения сей задачи выбрал Text Formatter. Сейчас же меня интересует реализация текстового хранилища, для чего надо наследовать и реализовать абстрактный класс TextSource. Чтобы разобраться, как это сделать, хотелось бы увидеть какие-то примеры. Желательно, более сложные, нежели в официальном примере
Ответ
Ответ на вопрос получил на форуме MSDN - ссылка. Код примера привожу ниже:
class SampleTextSource : TextSource
{
string text = "Foo Bar
Next Line";
List spans = new List {
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] == '
')
return new TextEndOfLine(1);
return new TextCharacters(text, span.Start, span.Length, new SampleTextRunProperties(span.Color));
}
public override TextSpan
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;
}
}
}
SDK-пример можно скачать здесь
Если необходимо, чтобы текст отображался с переносом (а это зачастую и требуется), то нужно, во-первых, в реализации TextParagraphProperties переопределить свойство TextWrapping, а во-вторых, в реализации метода TextRun GetTextRun(int textSourceCharacterIndex) в последнем выражении return использовать следующий фрагмент кода, вместо выше приведённого:
return new TextCharacters(text, textSourceCharacterIndex, span.Length - (textSourceCharacterIndex - span.Start), new SampleTextRunProperties(span.Color));
Это делается для поддержки возможности разбивать span на несколько строк.
Комментариев нет:
Отправить комментарий