سؤال

لقد وجدت هذا الرابط: http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtexttext.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));
}
هل كانت مفيدة؟

المحلول

قد لا يكون OnRender للنافذة أمرا جيدا؛ كنت أتوقع أن تكون على ما يرام، وما زلت أفكر في أنه يجب أن يكون هناك شيء يتعلق بمدير التخطيط أو حدود القصاصات، أو أي شيء متعلق، حيث إن إسقاط تتجاوز فئة نافذة تتصل بالتأكيد إلى هذا الرمز. سياق الرسم هو كل التقديم المؤجلة، وأنا أظن أن المرئية الأصل إما لا يستخدم أي من سياق الرسم أو يغطيه باستخدام مربع مبهمة من التصميم.

بغض النظر، إذا قمت بإجراء تحكم مخصص في مشروعك وقدم رمز OnRender في ذلك، وإضافة ذلك إلى الجذر في XAML الخاص بك، فإن مقتطف الكود هذا يعمل بشكل جيد.

نصائح أخرى

لقد كتبت للتو هذا 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; }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top