Alexander Solomenko

How to customize the appearance of advanced task panes and Outlook regions

Starting with version 8.2, Add-in Express began to open its internal infrastructure, which allows developers to customize some areas of advanced Excel, Word and PowerPoint task panes and Outlook regions. In the new release, it becomes possible to customize the header together with its controls as well as splitter and border. You can also modify the appearance of a minimized region, control the header visibility, change padding, get HitTest info and more.

Since the implementation of the Add-in Express for Office and .net infrastructure in the part of embedding forms is identical for all Office applications (the difference is only in class names), let’s take an Excel task pane as an example, examine its main elements, and see how you can customize them to your liking.

For example, take the default design of an advanced Excel task pane:

The default design of the advanced Excel task pane

… and turn it into this one:

The custom design of the advanced Excel task pane

Simply changing the form color, i.e. setting BackColor to green and the UseOfficeThemeForBackGround property to false will not be enough, because this will paint only the form in the desired color, whereas the other parts of the pane will be drawn according to Excel’s color theme, like this:

The form's color is changed, but the other parts of the pane are painted in the Excel theme color.

In order to understand what to do next, I used a graphical editor and outlined the areas that make up the pane, and that will be of interest to us.

The main elements of the pane in the Normal state.

The above screenshot shows the pane in the expanded state, which consists of three main areas: Form, Header and Splitter areas. For better perception, these areas are offset from the edge of the pane at some distance called Padding. The Form area is of no interest to you because it accommodates the content you create at design time. But Header and Splitter together with their contents as well as the Padding area can be changed the way you want.

What is an advanced task pane?

In terms of Add-in Express, the task pane is a specific control (ADXContainerControl) within which your form(s) is located. When several forms are located on the pane, it stores them in a list.

When the task pane is redrawn, first it paints its background in some color, and then draws the header and splitter. The area under the form is not painted. When the user hovers over some button on the header or splitter, the pane is redrawn completely.

How to modify the task pane appearance

Add-in Express implements the basic functionality of the task pane in the AddinExpress.Extensions.ADXContainerControl class. From this class, the following classes are inherited: ADXContainerControlOL, ADXContainerControlXL, ADXContainerControlPP, ADXContainerControlWD, which consider the behavior and drawing specific to Outlook, Excel, Power Point and Word, respectively.

To change the standard design of the task pane, you need to create a new class inherited from one of the above classes, and override the required virtual methods or properties. In this example, we inherit from the ADXContainerControlXL class.

public class MyContainerControl : ADXContainerControlXL
{
 
}

In addition, you need to specify that the new class should be used instead of the default one. For this, override the GetContainerControlType method in the ADXExcelTaskPane class, and return the type of your new class.

protected override Type GetContainerControlType()
{
    return typeof(MyContainerControl);
}

And now, you need to override and implement the properties and methods of your new MyContainerControl class. Here, I will describe only the most essential ones, and you can download the full code of this example, using this link.

To fill the whole drawing area of the task pane with the required color, override the BackColor property:

public override Color BackColor
{
    get { return Color.FromArgb(0x21, 0x73, 0x46); }
}

Additionally, you can override the Padding property to adjust internal spacing of the Header, Splitter and Form areas relative to the pane’s borders, for example:

public override Padding Padding
{
    get
    {
        Padding offsets = base.Padding;
        if (owner.RegionState == AddinExpress.XL.ADXRegionState.Hidden)
            offsets = new Padding(1, 2, 1, 2);
        return offsets;
    }
}

To properly draw the icons on the buttons, you need to know the pane’s layout and position (vertical or horizontal). For this, you can override the OnInitialized method and store these values in internal variables.

This method will be called whenever the pane is initialized, e.g. after showing the pane, changing its layout, or switching to another Office theme.

protected override void OnInitialized()
{
    base.OnInitialized();
    owner = Owner as ExcelTaskPane1;
    layout = owner.Item.Position;
    isVertical = false;
    switch (layout)
    {
        case AddinExpress.XL.ADXExcelTaskPanePosition.Left:
        case AddinExpress.XL.ADXExcelTaskPanePosition.Right:
 
        isVertical = true;
        break;
    }
}

And now, let’s see what methods are directly involved in drawing various pane controls.

Because the background is dark, we are using the white text color:

protected override void OnDrawText(DrawTextArgs e)
{
    e.ForeColor = Color.White;
    base.OnDrawText(e);
}
protected override void OnDrawHeader(DrawArgs e)
{
    //base.OnDrawHeader(e);
    e.DrawControls();
}

Please note that for the OnDrawHeader method, we do not call the base method and draw only child controls (by calling the e.DrawControls () method). Calling the base method isn't required here because of the task chosen: draw child controls on a custom background; if you call the base method, the background can be drawn with a gradient in some Excel versions (e.g. Excel 2010).

The next method that we are going to override is OnDrawControl (DrawControlArgs e). This method is called every time when any controls listed in ADXDrawControlType is rendered.

protected override void OnDrawControl(DrawControlArgs e)
{
    if (e.ControlType == ADXDrawControlType.Separator) // Excel 2010 and below
        return;
 
    // Draw any control except for splitter button
    if (e.ControlType != ADXDrawControlType.Splitter)
    {
        // Determine whether the button is available or not.
        bool disabled = false;
        switch (e.ControlType)
        {
            case ADXDrawControlType.Previous:
                disabled = !IsScrollButtonPresent(false); break;
            case ADXDrawControlType.Next:
                disabled = !IsScrollButtonPresent(true); break;
        }
 
        // If the button is available and has been clicked, or the mouse cursor hovers
        // over it, fill the background color corresponding to the button state.
        if (!disabled && e.State != ADXDrawControlState.Up)
        {
            SolidBrush br = new SolidBrush(e.State == ADXDrawControlState.Focused ?
            btnBackColor : btnPressedColor);
            e.Graphics.FillRectangle(br, e.Bounds);
            br.Dispose();
        }
 
        // Take the button image from the resources
        // and draw it using the DrawImage method.
        Image image = GetSkinImage(e.ControlType);
        if (image != null)
        {
            Size imgSize = image.Size;
            Rectangle destRect = new Rectangle(
                    e.Bounds.Left + (e.Bounds.Width - imgSize.Width) / 2,
                    e.Bounds.Top + (e.Bounds.Height - imgSize.Height) / 2,
                    imgSize.Width, imgSize.Height);
 
            // If the button is disabled, draw it with 50% transparency.
            float alpha = disabled ? 0.5f : 1.0f;
            DrawImage(e.Graphics, image, destRect, new Rectangle(Point.Empty,
                imgSize), alpha);
        }
        e.DrawControls();
    }
    else
        base.OnDrawControl(e);
}

How to customize the appearance of the minimized task pane

In the Minimized state, we need to display all forms located on the pane. The forms reside in the ContainerItems collection. Every element of the collection is a ContainerItem object, which is displayed on the pane as a rectangle with an icon and caption.

Advanced Excel task panes in the Minimized state

To change the appearance of ContainerItems, override the OnDrawContainerItem method. You can draw the icon and text directly in this method, though we recommend using special methods – OnDrawIcon and OnDrawText.

protected override void OnDrawContainerItem(DrawContainerItemArgs e)
{
    if (e.State == ADXDrawControlState.Selected)
    {
        // ContainerItem switches to the Selected state after the item has been clicked
        // and the floating form has appeared.
        SolidBrush br = new SolidBrush(Color.FromArgb(0x0a, 0x63, 0x32));
        e.Graphics.FillRectangle(br, e.Bounds);
        br.Dispose();
    }
    else
    if (e.State != ADXDrawControlState.Up)
    {
        SolidBrush br = new SolidBrush(e.State == ADXDrawControlState.Focused ?
        btnBackColor : btnPressedColor);
        e.Graphics.FillRectangle(br, e.Bounds);
        br.Dispose();
    }
    // Call this method to raise the OnDrawIcon and OnDrawText methods in order
    // to draw the icon and text.
    e.DrawControls();
}

By the way, the ADXExcelTaskPane, ADXWordTaskPane, ADXPowerPointTaskPane and ADXOlForm classes have the OnDrawBorder method which draws the border of a form that appears only in the floating mode. This method is virtual and can also be overridden to render the border in the desired style, for example:

protected override void OnDrawBorder(Graphics graphics, Rectangle bounds)
{
    base.OnDrawBorder(graphics, bounds);
    Pen pen = new Pen(Color.FromArgb(0x0a, 0x63, 0x32));
    Rectangle R = new Rectangle(0, 0, bounds.Width-1, bounds.Height-1);
    graphics.DrawRectangle(pen, R);
    pen.Dispose();
}

In the below screenshot, you can see how the appearance of the minimized panes has changed after our manipulations.

The custom design of the minimized panes

The next screenshot shows the custom design of the floating pane.

The custom design of the floating pane

To better understand the order in which the methods rendering an advanced task pane are called, have a look at the structure below:

Pane in the normal state:

OnDraw()
{
    OnDrawHeader() //draw the header background
    {
        OnDrawControl(); //draw the previous button if it is visible
        OnDrawControl(); //draw the next button if it is visible
        OnDrawControl()  //draw the caption control
        {
            OnDrawIcon(); //draw the icon image if it is visible
            OnDrawText(); //draw the caption
            OnDrawControl(); //draw the menu button
        }
        OnDrawControl(); //draw the close button
        OnDrawControl(); //draw the minimize button
    }
    OnDrawSplitter() //draw the splitter background
    {
        OnDrawControl(); //draw the splitter button
    }
}

Minimized pane:

OnDraw()
{
    OnDrawControl(); //draw the previous scroll button if it is visible
    OnDrawControl(); //draw the next scroll button if it is visible
    OnDrawControl(); //draw the minimize button
 
    OnDrawContainerItem() //draw the container item background
    {
        //draw the container item 1
        OnDrawIcon(); //draw the icon image if it is visible
        OnDrawText(); //draw the form caption
    }
    OnDrawControl(); //draw the separator, supported only in some Office versions
 
    OnDrawContainerItem()//draw the container item background
    {
        //draw the container item 2
        ...
    }
}

Hidden pane:

OnDraw()
{
    OnDrawSplitter()//draw the splitter background
    {
        OnDrawControl(); //draw the splitter button
    }
}

Available downloads:

Custom Excel task pane – C# sample

You may also be interested in:

5 Comments

  • https://secure.gravatar.com/avatar/7bc03fb43e3087d52daa0e4b5eb74808?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Eugene Astafiev says:

    Good beginning!

  • https://secure.gravatar.com/avatar/a804e7750f1c63a86e69a5bcf7cff71d?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G T says:

    Hello, thanks for the article!

    Is there a way that I can easily switch between the standard built-in themes without having to override all these functions and provide color codes and icons?

    For example, lets say the that I am using Excel 2016 with the Dark Gray theme. By default, the Addin-Express CTP will be themed to match Excel 2016 Dark Gray, but what if I wanted it to instead show the Excel 2010 Black theme for the CTP? Can this be achieved using the current API or can the API be updated to have this functionality?

  • https://secure.gravatar.com/avatar/69bd6bba2b952e8cbf78edc257d0c270?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Alexander Solomenko (Add-in Express Team) says:

    Hello,

    Unfortunately, this method is not available for use. The design of our TaskPanes was developed for a specific version of the Office application and its color scheme. Applying these settings to a different color scheme and a different Office version will result in a distorted design or visual artifacts that anyway will have to be fixed by using the same customization as described in this article.

  • https://secure.gravatar.com/avatar/f0c17a62b0f12df55d2f3229e9567a1b?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Shyam Sundar Sah says:

    is it outlook panel or Excel pane ?

  • https://secure.gravatar.com/avatar/6bc7f998904ab2c144a1eea1c77ba918?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Alexander Solomenko (Add-in Express Team) says:

    Hello Shyam,

    This functionality works for Advanced Outlook regions as well as Word, Excel and Power Point Task panes.

Post a comment

Have any questions? Ask us right now!