Technical details on the rendering engine

All rendering in the DocktorUI framework is done through the DockRender class, which is a default implementation of the IDockRender interface. By extending this class it is possible to fully customize the appearance of all UI elements within the framework.

The drawing code throughout the entire framework always tries to calculate layout and spacing logic for complicated layouts in order to reduce to the minimum level possible the basic visual blocks that compose into the final UI. Then, only this basic construction blocks are handed over to the rendering class as to minimize the amount of work for the renderer so that custom implementations can rely on and re-use internal framework code and simplify drawing customizations.

Although it's possible to implement the IDockRender interface from scratch it is hardly desired to do so as rewriting the entire renderer would take a lot of time. Instead, all is necessary to customize any component's UI within the framework is to inherit from the DockRender class and overwrite one of its methods or properties. The following is an example of such customizations (taken from the StylesApplication demo) where the docking panel buttons are redrawn in different styles from the default ones.

Code Example:

public class MyRender : DockRender
{
    protected override void DrawButton(Graphics g, WindowStatus status, DockType dockType, Rectangle buttonRectangle, ButtonType buttonType, WindowStatus buttonStatus, Pen pen)
    {
        switch (buttonType)
        {
            case ButtonType.Close:
                {
                    LinearGradientBrush br = new LinearGradientBrush(buttonRectangle, Color.Black, Color.White, 0.0f);
                    br.SetBlendTriangularShape(1f, 0.5f);

                    buttonRectangle.Inflate(-3, -3);

                    g.FillEllipse(br, buttonRectangle);

                    return;
                }
            case ButtonType.DockType:
                {
                    DrawStar(g, 6, buttonRectangle.X + 7, buttonRectangle.Y + 7);

                    return;
                }
            case ButtonType.AutoHide:
                {
                    buttonRectangle.Inflate(-3, -3);

                    g.FillEllipse(Brushes.Red, buttonRectangle);

                    return;
                }
            default:
                break;
        }
        
        base.DrawButton(g, status, dockType, buttonRectangle, buttonType, buttonStatus, pen);
    }

    private void DrawStar(Graphics g, float r, float xc, float yc)
    {
    	// code removed to ease clarity
    	
    	[...]
    }
}

The code snippet above will simply define the class, in order to have it actually used by the framework you have to create a new instance of the class MyRender and assign it to the component you want to customize the drawing of. Alternatively you can have the instance be used globally as the default renderer for every control or visual element by assigning it to the DockManager default renderer, like shown in the snippet below.

Code Example:

// MyRender class defined above
// put this into your form constructor code

DockManager.DefaultDockRender = new MyRender();