在WPF中构建自定义TextBlock控件

时间:2011-11-04 02:01:00

标签: wpf render textblock

我已经构建了自定义WPF控件,其中唯一的功能是显示文本。我尝试使用来自TextBlock命名空间的System.Windows.Controls,但它对我不起作用(我有~10000个字符串,位置不同,内存丢失太多)。
所以我尝试通过继承FrameworkElement来实现自己的控制,覆盖现在包含单行的OnRender方法:

drawingContext.DrawText(...);

但是... 我得到一个令人困惑的结果。 在比较10000个对象的性能之后,我意识到创建和添加到Canvas所需的时间仍然是~10秒,我的应用程序的内存使用量从大约32MB增加到大约60MB!
所以没有任何好处。

任何人都可以解释为什么会发生这种情况,以及使用两个函数创建简单(简单=分配更少的内存,花费更少的时间来创建)视觉效果的另一种方式:

  1. 显示文字
  2. 设置位置(使用厚度或TranslateTransform
  3. 感谢。

3 个答案:

答案 0 :(得分:0)

查看AvalonEdit

还不确定如何存储字符串,但之前是否使用过StringBuilder

答案 1 :(得分:0)

这是我的代码(稍加修改):

public class SimpleTextBlock : FrameworkElement
{
    #region Static

    private const double _fontSize = 12;
    private static Point _emptyPoint;
    private static Typeface _typeface;
    private static LinearGradientBrush _textBrush;

    public readonly static DependencyProperty TextWidthProperty;

    static SimpleTextBlock()
    {
        _emptyPoint = new Point();
        _typeface = new Typeface(new FontFamily("Sergoe UI"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);

        GradientStopCollection GSC = new GradientStopCollection(2);
        GSC.Add(new GradientStop(Color.FromArgb(160, 255, 255, 255), 0.0));
        GSC.Add(new GradientStop(Color.FromArgb(160, 180, 200, 255), 0.7));
        _textBrush = new LinearGradientBrush(GSC, 90);
        _textBrush.Freeze();


        SimpleTextBlock.TextWidthProperty = DependencyProperty.Register(
            "TextWidth",
            typeof(double),
            typeof(SimpleTextBlock),
            new FrameworkPropertyMetadata(0.0d, FrameworkPropertyMetadataOptions.AffectsRender));
    }

    #endregion

    FormattedText _formattedText;

    public SimpleTextBlock(string text)
    {
        _formattedText = new FormattedText(text, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, _typeface, _fontSize, _textBrush);
    }

    public SimpleTextBlock(string text, FlowDirection FlowDirection)
    {
        _formattedText = new FormattedText(text, System.Globalization.CultureInfo.InvariantCulture, FlowDirection, _typeface, _fontSize, _textBrush);
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        _formattedText.MaxTextWidth = (double)GetValue(TextWidthProperty);
        drawingContext.DrawText(_formattedText, _emptyPoint);
    }

    public double TextWidth
    {
        get { return (double)base.GetValue(TextWidthProperty); }
        set { base.SetValue(TextWidthProperty, value); }
    }

    public double ActualTextWidth
    {
        get { return _formattedText.Width; }
    }

    public double ActualTextHeight
    {
        get { return _formattedText.Height; }
    }
}

答案 2 :(得分:0)

因为听起来我们确定你应该对像listbox这样的控件进行样式化,这里有一些你可以做的不同事情的例子:

Use Images as Items

Stylized and Binding

老实说,一切都取决于你想要的样子。 WPF非常出色,它可以为您提供多少控制功能。

Crazy example using a listbox to make the planet's orbits