WPF在窗口上绘制文本

时间:2010-01-05 15:38:49

标签: wpf text draw

我找到了这个链接:http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext.aspx

这是一个如何通过覆盖OnRender方法来绘制文本的示例。

我使用以下代码覆盖了OnRender的{​​{1}}方法,但文本不可见。我做错了什么?

Window

2 个答案:

答案 0 :(得分:1)

覆盖OnRender窗口可能不是一件好事;我本来期望它没关系,我仍然认为它必须与布局管理器,剪切边界或相关的东西有关,因为将该覆盖放入Window类中肯定会调用该代码。绘图上下文都是延迟渲染,我怀疑父视觉要么没有使用任何绘图上下文,要么用布局中的不透明框覆盖它。

无论如何,如果您在项目中进行自定义控制并在其中填充OnRender代码,并将其添加到xaml中的根目录,则此代码段工作正常。

答案 1 :(得分:0)

我刚刚编写了这个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; }
    }
}