Создание пользовательского элемента управления TextBlock в WPF - PullRequest
0 голосов
/ 04 ноября 2011

Я создал собственный WPF Control, уникальная функция которого отображает текст.
Я пытался использовать TextBlock из System.Windows.Controls пространства имен, но у меня это не работает (у меня ~ 10000 строк с другим положением и слишком большой потерей памяти).
Поэтому я попытался создать свой собственный элемент управления, унаследовав FrameworkElement, переопределив метод OnRender, который теперь содержит одну строку:

drawingContext.DrawText(...);

Но ... Я получаю немного запутанный результат. После сравнения производительности для 10000 объектов я понял, что время, необходимое для создания и добавления в Canvas, все еще составляет ~ 10 секунд, а использование памяти для моего приложения увеличивается с ~ 32 МБ до ~ 60 МБ !!!
Так что никаких преимуществ вообще нет.

Может ли кто-нибудь объяснить, почему это происходит, и как можно создать простой (простой = выделить меньше памяти, меньше времени для создания) визуал с двумя функциями:

  1. отображаемый текст
  2. установка положения (с использованием толщины или TranslateTransform)

Спасибо.

Ответы [ 3 ]

0 голосов
/ 06 ноября 2011

Вот мой код (немного измененный):

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; }
    }
}
0 голосов
/ 06 ноября 2011

Поскольку звучит так, как мы определили, вам следует стилизовать элемент управления, такой как список, вот несколько примеров различных действий, которые вы можете сделать:

Использование изображений в качестве элементов

Стилизованный и обязательный

Честно говоря, все зависит от того, как вы хотите, чтобы он выглядел.WPF хорош тем, насколько он контролирует внешний вид.

Сумасшедший пример использования списка для создания орбит планеты

0 голосов
/ 04 ноября 2011

Выезд AvalonEdit

Также не уверен, как вы храните строки, но вы использовали StringBuilder раньше?

...