FormattedText クラスを使用して Text を作成していますが、このクラスを使用する場合、上付き文字または上付き文字のテキストを下付きにする方法を教えてください。TextBlock を使用するときにこれを行う方法に関する解決策を見つけましたが、 TextBlock ではなく FormattedText を使用しています):ヒントをありがとう!
2 に答える
FormattedText
下付き/上付きはできませんが、TextFormatter
できます。
TextFormatter
は低レベルの API であり、それを使用するには多くのコードを記述する必要がありますが、ほとんどのコードは、書式設定パラメーター int を渡すために使用されるすべてのクラスをサブクラス化するだけTextFormatter
です。
テキストフォーマッターの使い方
TextFormatter
はTextSource
オブジェクトを受け取り、複数のTextLine
オブジェクト (線ごとに 1 つ) を生成しTextLine.Draw
ます。その後、このメソッドを使用して線を描画コンテキストに描画できます。
TextSource
クラスは抽象的です。それをサブクラス化し、提供された文字位置にあるオブジェクトを単に返すメソッドをオーバーライドする必要がありますGetTextRun
。TextRun
TextRun
も抽象的ですが、使用できるサブクラスがあります。興味深いクラスはTextCharacters
、文字列とフォーマット情報を含むクラスです。
フォーマット情報はTextRunProperties
オブジェクトにありますが、残念ながら、これはサブクラス化する必要がある別の抽象クラスです。
TextRunProperties
タイプのTypographyProperties
プロパティがありますTextRunTypographyProperties
。
TextRunTypographyProperties
サブクラス化する必要があるさらに別の抽象クラスです。
最後TextRunTypographyProperties
にVariants
、TextBlock の例のように使用できるプロパティがあります。
コード例
上付きテキストを描画するために記述できる最小限のコードは次のとおりです。
まず、上付き文字のフォント バリアントを返すことができる TextRunProperties と TextRunTypographyProperties:
class CustomTextRunProperties : TextRunProperties
{
private bool _superscript;
public CustomTextRunProperties(bool superscript)
{
_superscript = superscript;
}
public override System.Windows.Media.Brush BackgroundBrush
{
get { return null; }
}
public override CultureInfo CultureInfo
{
get { return CultureInfo.CurrentCulture; }
}
public override double FontHintingEmSize
{
get { return 22; }
}
public override double FontRenderingEmSize
{
get { return 22; }
}
public override Brush ForegroundBrush
{
get { return Brushes.Black; }
}
public override System.Windows.TextDecorationCollection TextDecorations
{
get { return new System.Windows.TextDecorationCollection(); }
}
public override System.Windows.Media.TextEffectCollection TextEffects
{
get { return new TextEffectCollection(); }
}
public override System.Windows.Media.Typeface Typeface
{
get { return new Typeface("Calibri"); }
}
public override TextRunTypographyProperties TypographyProperties
{
get
{
return new CustomTextRunTypographyProperties(_superscript);
}
}
}
class CustomTextRunTypographyProperties : TextRunTypographyProperties
{
private bool _superscript;
public CustomTextRunTypographyProperties(bool superscript)
{
_superscript = superscript;
}
public override int AnnotationAlternates
{
get { return 0; }
}
public override bool CapitalSpacing
{
get { return false; }
}
public override System.Windows.FontCapitals Capitals
{
get { return FontCapitals.Normal; }
}
public override bool CaseSensitiveForms
{
get { return false; }
}
public override bool ContextualAlternates
{
get { return false; }
}
public override bool ContextualLigatures
{
get { return false; }
}
public override int ContextualSwashes
{
get { return 0; }
}
public override bool DiscretionaryLigatures
{
get { return false; }
}
public override bool EastAsianExpertForms
{
get { return false; }
}
public override System.Windows.FontEastAsianLanguage EastAsianLanguage
{
get { return FontEastAsianLanguage.Normal; }
}
public override System.Windows.FontEastAsianWidths EastAsianWidths
{
get { return FontEastAsianWidths.Normal; }
}
public override System.Windows.FontFraction Fraction
{
get { return FontFraction.Normal; }
}
public override bool HistoricalForms
{
get { return false; }
}
public override bool HistoricalLigatures
{
get { return false; }
}
public override bool Kerning
{
get { return true; }
}
public override bool MathematicalGreek
{
get { return false; }
}
public override System.Windows.FontNumeralAlignment NumeralAlignment
{
get { return FontNumeralAlignment.Normal; }
}
public override System.Windows.FontNumeralStyle NumeralStyle
{
get { return FontNumeralStyle.Normal; }
}
public override bool SlashedZero
{
get { return false; }
}
public override bool StandardLigatures
{
get { return false; }
}
public override int StandardSwashes
{
get { return 0; }
}
public override int StylisticAlternates
{
get { return 0; }
}
public override bool StylisticSet1
{
get { return false; }
}
public override bool StylisticSet10
{
get { return false; }
}
public override bool StylisticSet11
{
get { return false; }
}
public override bool StylisticSet12
{
get { return false; }
}
public override bool StylisticSet13
{
get { return false; }
}
public override bool StylisticSet14
{
get { return false; }
}
public override bool StylisticSet15
{
get { return false; }
}
public override bool StylisticSet16
{
get { return false; }
}
public override bool StylisticSet17
{
get { return false; }
}
public override bool StylisticSet18
{
get { return false; }
}
public override bool StylisticSet19
{
get { return false; }
}
public override bool StylisticSet2
{
get { return false; }
}
public override bool StylisticSet20
{
get { return false; }
}
public override bool StylisticSet3
{
get { return false; }
}
public override bool StylisticSet4
{
get { return false; }
}
public override bool StylisticSet5
{
get { return false; }
}
public override bool StylisticSet6
{
get { return false; }
}
public override bool StylisticSet7
{
get { return false; }
}
public override bool StylisticSet8
{
get { return false; }
}
public override bool StylisticSet9
{
get { return false; }
}
public override FontVariants Variants
{
get { return _superscript ? FontVariants.Superscript: FontVariants.Normal; }
}
}
段落書式設定用の同様のクラス (MSDN TextFormatter サンプルから取得):
class GenericTextParagraphProperties : TextParagraphProperties
{
public GenericTextParagraphProperties(
FlowDirection flowDirection,
TextAlignment textAlignment,
bool firstLineInParagraph,
bool alwaysCollapsible,
TextRunProperties defaultTextRunProperties,
TextWrapping textWrap,
double lineHeight,
double indent)
{
_flowDirection = flowDirection;
_textAlignment = textAlignment;
_firstLineInParagraph = firstLineInParagraph;
_alwaysCollapsible = alwaysCollapsible;
_defaultTextRunProperties = defaultTextRunProperties;
_textWrap = textWrap;
_lineHeight = lineHeight;
_indent = indent;
}
public override FlowDirection FlowDirection
{
get { return _flowDirection; }
}
public override TextAlignment TextAlignment
{
get { return _textAlignment; }
}
public override bool FirstLineInParagraph
{
get { return _firstLineInParagraph; }
}
public override bool AlwaysCollapsible
{
get { return _alwaysCollapsible; }
}
public override TextRunProperties DefaultTextRunProperties
{
get { return _defaultTextRunProperties; }
}
public override TextWrapping TextWrapping
{
get { return _textWrap; }
}
public override double LineHeight
{
get { return _lineHeight; }
}
public override double Indent
{
get { return _indent; }
}
public override TextMarkerProperties TextMarkerProperties
{
get { return null; }
}
public override double ParagraphIndent
{
get { return _paragraphIndent; }
}
private FlowDirection _flowDirection;
private TextAlignment _textAlignment;
private bool _firstLineInParagraph;
private bool _alwaysCollapsible;
private TextRunProperties _defaultTextRunProperties;
private TextWrapping _textWrap;
private double _indent;
private double _paragraphIndent;
private double _lineHeight;
}
今 TextSource 実装:
public class CustomTextSourceRun
{
public string Text;
public bool IsSuperscript;
public bool IsEndParagraph;
public int Length { get { return IsEndParagraph ? 1 : Text.Length; } }
}
class CustomTextSource : TextSource
{
public List<CustomTextSourceRun> Runs = new List<CustomTextSourceRun>();
public override TextRun GetTextRun(int textSourceCharacterIndex)
{
int pos = 0;
foreach (var currentRun in Runs)
{
if (textSourceCharacterIndex < pos + currentRun.Length)
{
if (currentRun.IsEndParagraph)
{
return new TextEndOfParagraph(1);
}
var props =
new CustomTextRunProperties(currentRun.IsSuperscript);
return new TextCharacters(
currentRun.Text,
textSourceCharacterIndex - pos,
currentRun.Length - (textSourceCharacterIndex - pos),
props);
}
pos += currentRun.Length;
}
// Return an end-of-paragraph if no more text source.
return new TextEndOfParagraph(1);
}
public override TextSpan<CultureSpecificCharacterBufferRange> GetPrecedingText(int textSourceCharacterIndexLimit)
{
throw new Exception("The method or operation is not implemented.");
}
public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int textSourceCharacterIndex)
{
throw new Exception("The method or operation is not implemented.");
}
public int Length
{
get
{
int r = 0;
foreach (var currentRun in Runs)
{
r += currentRun.Length;
}
return r;
}
}
}
あとは、CustomTextSource を初期化してテキストを描画するだけです。
var textStore = new CustomTextSource();
textStore.Runs.Add(new CustomTextSourceRun() { Text = "3" });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "rd", IsSuperscript = true });
textStore.Runs.Add(new CustomTextSourceRun() { IsEndParagraph = true });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "4" });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "th", IsSuperscript = true });
int textStorePosition = 0;
System.Windows.Point linePosition = new System.Windows.Point(0, 0);
textDest = new DrawingGroup();
DrawingContext dc = textDest.Open();
TextFormatter formatter = TextFormatter.Create();
while (textStorePosition < textStore.Length)
{
using (TextLine myTextLine = formatter.FormatLine(
textStore,
textStorePosition,
96*6,
new GenericTextParagraphProperties(FlowDirection.LeftToRight,
TextAlignment.Left,true,false, new CustomTextRunProperties(false), TextWrapping.Wrap,
30,0), null))
{
myTextLine.Draw(dc, linePosition, InvertAxes.None);
textStorePosition += myTextLine.Length;
linePosition.Y += myTextLine.Height;
}
}
dc.Close();
それだけです。描画コンテキストに上付きテキストがあります。
を使用する方法はありませんFormattedText
。ここで完全なリファレンスを参照してください。
http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext_members.aspx
TextBlock
あなたがすでに発見したように、あなたはそれで行うことができます:
FormattedText
または、小さい方 ( SetFontSize
) を作成し、手動で上下に配置することもできます。
FormattedText
を使用している状況、解決しようとしている問題、または を使用できない理由について、さらにコンテキストを提供できる場合はTextBlock
、この回答への返信を投稿してください。より具体的な例を提供して喜んでお手伝いします。 .
それが役立つことを願っています!