我需要在WPF畫布上顯示單詞,以便它們完全適合預定義的框。在WPF中渲染文本以使其完美適合給定的矩形
一個盒子通常包含一行文字,從一個字母到幾個單詞。
箱子內的文字必須儘可能大,即:觸摸箱子的所有邊框(除非由於箱子和高度比例異常導致文本變形太大)。
我找不到一個很好的方法來計算基於文本內容的適當的字體高度,縮放和偏移量。
第一個解決方案的原始文字寬高比不能改變已經非常好了!
我想使用TextBlock元素,但其他任何工作應該沒問題。
我需要在WPF畫布上顯示單詞,以便它們完全適合預定義的框。在WPF中渲染文本以使其完美適合給定的矩形
一個盒子通常包含一行文字,從一個字母到幾個單詞。
箱子內的文字必須儘可能大,即:觸摸箱子的所有邊框(除非由於箱子和高度比例異常導致文本變形太大)。
我找不到一個很好的方法來計算基於文本內容的適當的字體高度,縮放和偏移量。
第一個解決方案的原始文字寬高比不能改變已經非常好了!
我想使用TextBlock元素,但其他任何工作應該沒問題。
正如Robery Levy所說的答案,您可以使用Viewbox
來實現此目的。文本本身不會伸展,所以根據您的文本,您仍然會在零個或多個邊上留下一些「邊距」(如您注意的那樣)。要解決此問題,您可以創建一個自定義控件,該控件從FormattedText
構建Geometry
,然後在OnRender中使用DrawGeometry
進行繪製。您會注意到文本的質量如何提高,更大的FontSize
。一個非常小的文本(例如FontSize="10"
)也不會顯得非常銳利的大Viewbox
所以你必須做一些試驗
一些樣品的XAML
<Canvas Background="Black">
<Viewbox Canvas.Left="10" Canvas.Top="10"
Stretch="Fill" Width="200" Height="50">
<Border Background="Red">
<local:StretchText Text="Text" Foreground="Green" FontSize="100"/>
</Border>
</Viewbox>
<Viewbox Canvas.Left="230" Canvas.Top="10"
Stretch="Fill" Width="200" Height="50">
<Border Background="Red">
<local:StretchText Text="B" Foreground="Green" FontSize="500"/>
</Border>
</Viewbox>
</Canvas>
StretchText .cs
public class StretchText : Control
{
protected override void OnRender(DrawingContext drawingContext)
{
FormattedText formattedText = new FormattedText(
Text,
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface(FontFamily, FontStyle, FontWeight, FontStretches.Normal),
FontSize,
Foreground);
Geometry textGeometry = formattedText.BuildGeometry(new Point(0, 0));
this.MinWidth = textGeometry.Bounds.Width;
this.MinHeight = textGeometry.Bounds.Height;
TranslateTransform translateTransform = new TranslateTransform();
translateTransform.X = -textGeometry.Bounds.Left;
translateTransform.Y = -textGeometry.Bounds.Top;
drawingContext.PushTransform(translateTransform);
drawingContext.DrawGeometry(Foreground, new Pen(Foreground, 1.0), textGeometry);
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(StretchText),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender));
}
謝謝,剛剛嘗試過。有趣的,但它並不完全符合我的需要:它不知道原文內容。例如,除非字母跨越基線(如'g','p','y''q'),否則我在文本下方仍有空白。我真的需要輸入框作爲文本「bouding box」。 – Jem 2011-01-21 17:50:54
你可以看看查爾斯Petzold的文章 「Render Text on a Path with WPF」。不幸的是,由於MSDN網站出現問題,我無法刷新目前關於主題的知識,但他描述瞭如何在路徑中縮放文本。
謝謝!我測試了它,它工作得很好。與此同時,我找到了一種替代解決方案:通過一個臨時的FormattedText對象(歸功於屬性「寬度」,「範圍」和「OverhangAfter」)測量文本元素,然後相應地爲每個元素應用Scale + TranslateTransform。但是,它有兩個缺點:實際的文本塊對象變得太大(提示工具提示),並且渲染速度沒有我想要的那麼快。 – Jem 2011-01-26 16:12:04