WPF Rendering – #1

WPF offers distinctly different techniques for rendering graphical elements. The top level is adding shape elements such as Rectangle, Ellipse, and Path to a Panel element. This is what we see in the multitude of XAML based samples. Below I explore another technique involving implementing OnRender on a class derived from UIElement.

Rendering within UIElement::OnRender()

Implementing within UIElement is accomplished by implementing OnRender. OnRender is provide with DrawingContext. This context offers methods for drawing text and geometry.

class UIElmentOnRenderDemo : UIElement {
    protected override void OnRender(DrawingContext drawingContext)   { … }

When the parent of the UIElement detects that the size has changed, OnRender is called. Within OnRender we can generate render geometries and make calls to the drawing context to render them.

Rect rect = new Rect(new Point(5, 10), new Size(100, 20)));

Geometry outline = new RectangleGeometry(rect);

drawingContext.DrawGeometry( brush, pen, outline);

Note that the rectangle was intended to be rendered with a single pixel line and is showed at thicker with sfoter edges. The is result of "anti-aliasing" in order to soften the images on eh screen. Here is a close-up.

RenderOptions.SetEdgeMode can be used to turn off antialiasing for all non-text render output within the UIElement. Setting Edge mode for individual geometry has no effect. EdgeMode has no effect on text rendering.

RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);

With EdeMode set on UIElement the rectangle is rendered crisply. 

Note: I’ll be invesigating rendering in more depth in upcoming blog entries.  Problems arise when rendering on 120 DPI displays.  I’ll also delve into more complex geometries and the use of guidelines.

This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to WPF Rendering – #1

  1. James says:

    Hi There,
    We are also having problems when redering on 120 DPI displays.
    IE the four edges of a group box appear to have different thicknesses (due to AA)
    Do you know what the correct way to address this problem is?
    James Miles
    ESS Australia

  2. Alexander says:

    I have a problem with WPF too, maybe you could help me a little bit. I tried to draw on my window using your method with the OnRender method, but nothing appears on my screen.
    This is the method I wrote to draw a simple rectangle:

    protected override void OnRender ( DrawingContext drawingContext )
    base.OnRender ( drawingContext );
    Rect myRect = new Rect ( 10.0, 10.0, 100.0, 100.0 );
    Geometry geo = new RectangleGeometry ( myRect );
    drawingContext.DrawGeometry ( Brushes.Black, new Pen ( Brushes.Black, 10.0 ), geo );
    //StreamGeometry sg = new StreamGeometry ( );
    //using ( StreamGeometryContext sgc = sg.Open ( ) )
    // sgc.BeginFigure ( new Point ( 0.0, 0.0 ), true, true );
    // sgc.LineTo ( new Point ( 100.0, 100.0 ), true, true );
    // //sgc.ArcTo ( new Point ( 5.0, 5.0 ), new Size ( 10.0, 10.0 ), 0.0, false, SweepDirection.Clockwise, false, true );
    //drawingContext.DrawGeometry ( Brushes.Black, new Pen ( Brushes.Black, 10.0 ), sg );
    Maybe you see a error in my code :)
    Thank you very much.

  3. Christian says:

    Hi together,
    The reason is the anti-aliasing system that spreads the lines over multiple pixels if they don’t excatly align with physical pixels. But disabling the anti aliasing is not the best reason. I wrote an article that explains the problem why the drawn lines appear blurry. Have a look at it here: How to draw exactly on physical device pixels

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s