大文字を使用すると、表示される文字とドキュメントの間のマッピング (ビジュアル列とドキュメント オフセット) が変わる可能性があるため、これは困難です。
たとえば、1 文字の 'ß' (ドイツ語のシャープ s) は小文字としてのみ存在し、 を呼び出すと 2 文字の文字列 "SS" に変換されstring.ToUpper()
ます。このテキストの編集には注意が必要です。基になるドキュメントには 'ß' しか含まれていないため、ユーザーが 'S' の 1 つだけを置き換えることを許可することはできません。
簡単な解決策は、char.ToUpper()
代わりにメソッドを使用して、元の文字と大文字の間で 1 対 1 のマッピングを強制することです。これにより、'ß' などの文字は変更されません。
AvalonEdit 4.2 では、生成済みの VisualLineElements で許可される変換は 2 つだけです。
- テキスト ランのプロパティ (フォント サイズ、テキストの色など) を変更します。
- VisualLineElement を 2 つに分割します。これは
ChangeLinePart()
、テキスト部分のプロパティを変更できるように内部で使用されます。
これは、カラーライザーでテキスト置換を行うことができないことを意味しますVisualLineElementGenerator
。.
/// <summary>
/// Makes all text after a colon (until the end of line) upper-case.
/// </summary>
public class UppercaseGenerator : VisualLineElementGenerator
{
public override int GetFirstInterestedOffset(int startOffset)
{
TextDocument document = CurrentContext.Document;
int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset;
for (int i = startOffset; i < endOffset; i++) {
char c = document.GetCharAt(i);
if (c == ':')
return i + 1;
}
return -1;
}
public override VisualLineElement ConstructElement(int offset)
{
DocumentLine line = CurrentContext.Document.GetLineByOffset(offset);
return new UppercaseText(CurrentContext.VisualLine, line.EndOffset - offset);
}
/// <summary>
/// Displays a portion of the document text, but upper-cased.
/// </summary>
class UppercaseText : VisualLineText
{
public UppercaseText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)
{
}
protected override VisualLineText CreateInstance(int length)
{
return new UppercaseText(ParentVisualLine, length);
}
public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
{
if (context == null)
throw new ArgumentNullException("context");
int relativeOffset = startVisualColumn - VisualColumn;
StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset);
char[] uppercase = new char[text.Count];
for (int i = 0; i < text.Count; i++) {
uppercase[i] = char.ToUpper(text.Text[text.Offset + i]);
}
return new TextCharacters(uppercase, 0, uppercase.Length, this.TextRunProperties);
}
}
}
AvalonEdit 4.3.0.8868 では、メソッドを追加しましたVisualLine.ReplaceElement()
。VisualText
これを使用して、デフォルトの要素をUppercaseText
ライン トランスフォーマー (カラーライザー) 内の要素に置き換えることができます。
「ß」を「SS」として表示するためのサポートを実装することも可能であることに注意してください。そのためにはVisualLineText
、既存のものをオーバーライドするだけでなく、独自のコピーを実装する必要があります。次に、ドキュメントの長さとは異なる視覚的な長さを使用できます。GetRelativeOffset
メソッドとGetVisualColumns
メソッドを使用して、ドキュメントとビジュアル座標の間のマッピングを提供します。
使用できる別のオプションがあります。スモール キャップです。
// in the colorizer:
ChangeLinePart(start, end, e => e.TextRunProperties.SetTypographyProperties(new CapsTypography()));
// helper class
class CapsTypography : DefaultTextRunTypographyProperties
{
public override FontCapitals Capitals {
get { return FontCapitals.SmallCaps; }
}
}
ただし、WPF は、小さい大文字をサポートする OpenType フォントを使用している場合にのみ小さい大文字をレンダリングします。私のテストでCambria
は、小さな大文字で動作しましたが、他のほとんどのフォントでは動作しません。また、SetTypographyProperties
メソッドとDefaultTextRunTypographyProperties
クラスには AvalonEdit 4.3 が必要です。