WPF рисовать текст в окне - PullRequest
0 голосов
/ 05 января 2010

Я нашел эту ссылку: http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext.aspx

Это пример того, как рисовать текст путем переопределения метода OnRender.

Я переопределил OnRender метод Window, используя следующий код, но текст не отображается. Что я делаю не так?

protected override void OnRender(DrawingContext drawingContext)
{
    string testString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor";

    // Create the initial formatted text string.
    FormattedText formattedText = new FormattedText(
        testString,
        CultureInfo.GetCultureInfo("en-us"),
        FlowDirection.LeftToRight,
        new Typeface("Verdana"),
        32,
        Brushes.Black);

    // Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
    formattedText.MaxTextWidth = 300;
    formattedText.MaxTextHeight = 240;

    // Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
    // The font size is calculated in terms of points -- not as device-independent pixels.
    formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5);

    // Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
    formattedText.SetFontWeight(FontWeights.Bold, 6, 11);

    // Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
    formattedText.SetForegroundBrush(
                            new LinearGradientBrush(
                            Colors.Orange,
                            Colors.Teal,
                            90.0),
                            6, 11);

    // Use an Italic font style beginning at the 28th character and continuing for 28 characters.
    formattedText.SetFontStyle(FontStyles.Italic, 28, 28);

    // Draw the formatted text string to the DrawingContext of the control.
    drawingContext.DrawText(formattedText, new Point(10, 0));
}

Ответы [ 2 ]

1 голос
/ 05 января 2010

Переопределение OnRender для окна может не быть хорошей вещью; Я ожидал бы, что это будет хорошо, и я все еще думаю, что это должно быть связано с менеджером макета, границами отсечения или чем-то связанным, поскольку удаление этого переопределения в класс Window, безусловно, вызывает этот код. Весь контекст рисования - это отложенный рендеринг, я подозреваю, что родительский визуал либо не использует какой-либо контекст рисования, либо закрывает его непрозрачным блоком из макета.

В любом случае, если вы создадите пользовательский элемент управления в своем проекте и добавите в него код OnRender и добавите его в корневой каталог в своем xaml, этот фрагмент кода будет работать нормально.

0 голосов
/ 16 сентября 2011

Я только что написал это FrameworkElement, которое позволит получить геометрию текста рендера с контуром. На исследование ушло около 10 минут, а потом - 20 минут.

Использование:

<Grid>
    <local:OutlineTextElement Text="Hello" />
</Grid>

Код:

public class OutlineTextElement : FrameworkElement
{
    public FontFamily FontFamily { get; set; }
    public FontWeight FontWeight { get; set; }
    public FontStyle FontStyle { get; set; }
    public int FontSize { get; set; }
    public int Stroke { get; set; }

    public SolidColorBrush Background { get; set; }
    public SolidColorBrush Foreground { get; set; }
    public SolidColorBrush BorderBrush { get; set; }

    private Typeface Typeface;
    private VisualCollection Visuals;
    private Action RenderTextAction;
    private DispatcherOperation CurrentDispatcherOperation;

    private string text;
    public string Text
    {
        get { return text; }
        set
        {
            if (String.Equals(text, value, StringComparison.CurrentCulture))
                return;

            text = value;
            QueueRenderText();
        }
    }

    public OutlineTextElement()
    {
        Visuals = new VisualCollection(this);

        FontFamily = new FontFamily("Century");
        FontWeight = FontWeights.Bold;
        FontStyle = FontStyles.Normal;
        FontSize = 240;
        Stroke = 4;
        Typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretches.Normal);

        Foreground = Brushes.Black;
        BorderBrush = Brushes.Gold;

        RenderTextAction = () => { RenderText(); };
        Loaded += (o, e) => { QueueRenderText(); };
    }

    private void QueueRenderText()
    {
        if (CurrentDispatcherOperation != null)
            CurrentDispatcherOperation.Abort();

        CurrentDispatcherOperation = Dispatcher.BeginInvoke(RenderTextAction, DispatcherPriority.Render, null);

        CurrentDispatcherOperation.Aborted += (o, e) => { CurrentDispatcherOperation = null; };
        CurrentDispatcherOperation.Completed += (o, e) => { CurrentDispatcherOperation = null; };
    }

    private void RenderText()
    {
        Visuals.Clear();

        DrawingVisual visual = new DrawingVisual();
        using (DrawingContext dc = visual.RenderOpen())
        {
            FormattedText ft = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface, FontSize, Foreground);
            Geometry geometry = ft.BuildGeometry(new Point(0.0, 0.0)); 
            dc.DrawText(ft, new Point(0.0, 0.0));
            dc.DrawGeometry(null, new Pen(BorderBrush, Stroke), geometry);

        }
        Visuals.Add(visual);
    }

    protected override Visual GetVisualChild(int index)
    {
        return Visuals[index];
    }

    protected override int VisualChildrenCount
    {
        get { return Visuals.Count; }
    }
}
...