Modernizing Windows Forms
Written by Mike James   
Thursday, 17 February 2011
Article Index
Modernizing Windows Forms
Filter & Appearance Objects

Windows forms are simple and direct and well known to most .NET programmers. After all it's where is all started. But what about jazzing up the user interface and why not add a few nice features to make your task easier.

Let's get back to Windows forms - there is  sort of relief when you finally decide that you don't need WPF!  Windows forms are simple and direct and well known to most .NET programmers.

After all it's where is all started. But what about jazzing up the user interface and why not add a few nice features to make your task easier? Just because you have decided that WPF isn't for you it doesn't mean you have to punish yourself by restricting what you use to the supplied controls. Of course the downside is that third party control libraries cost money, but if the app is worth it then why not?

This brings me to the Infragistic's .NET Advantage for Windows Forms which has a very wide range of controls. And perhaps more importantly it provides an underlying architecture which extends Forms in the sort of direction it might have gone in had Microsoft not bet the farm on WPF. Even if you are not interested in using this third party control library the details of some of the innovations it contains are worth knowing about if only to influence any extensions you might make.

PLF - Presentation Layer Framework

The key architectural feature is the PLF - Presentation Layer Framework. This can be summed up in a diagram although such diagrams really have a way of not meaning much until you already know what they mean. To find out what each of the ideas is all about just read on.

 

PLF

 

The first innovation is the use of UIElement as the basic building block of a control. Obviously any complex controll will be made up of sub-objects but UIElements also correspond to the renderable areas - that is they form a render tree structure. Complex controls can be rendered by simply asking their child UIElements to draw themselves in. This has all sorts of implementational advantages and allows much of the code used to be shared between controls.From the average programmers point of view however the way that controls are constructed can be ignored - they may be more stable and smaller but you can just use them. There are some surface level advantages however. Two new events, MouseEnterElement and MouseLeaveElement, allow you to write event handlers for interaction with child elements of a control.

For example the WinCalculator is made up of child buttons and a textbox. You can write an event handler for the mouse to enter any child element quite easily:

private void ultraCalculator1_
MouseEnterElement(object sender,
 Infragistics.Win.UIElementEventArgs e)
{
MessageBox.Show( e.Element.GetType().
ToString());
}

The EventArgs tell you which UIElement the event occurred on.

Another big advantage which you don't often have to actually use is the uniform extensibility provided by a range of filters - draw, creation, cursor and selection. The way that this work is very simple. All you have to do is create an object which implements the appropriate Interface - the UIElementDrawFilter for example. Then you simply set the control's DrawFilter property to the object you created. When the control is about to Draw or whatever action you have extended then the methods in the Interface you have implemented are called.

For example, suppose you want to override the drawing of a button then first you need to define a class to do the job:

public class MyDraw : 
Infragistics.Win.IUIElementDrawFilter

{
bool Infragistics.Win.IUIElementDrawFilter.
DrawElement(
Infragistics.Win.DrawPhase drawPhase,
ref Infragistics.Win.
UIElementDrawParams drawParams)
{
MessageBox.Show("Button Draw");
return true;
}

Infragistics.Win.DrawPhase Infragistics.
Win.IUIElementDrawFilter.GetPhasesToFilter(
ref Infragistics.
Win.UIElementDrawParams drawParams)
{
return Infragistics.Win.DrawPhase.
BeforeDrawElement;
}
}

All you have to do here is create the MyDraw class and make it inherit the IUIElementDrawFilter interface.

To do this, right-click on the class definition and get Visual Studio to generate method stubs for the Interface. The first method, GetPhasesToFilter, is called by the control to discover which phases of the drawing action you want to override (i.e. filter)

All you have to do is return the types you want to handle using the predefined enumeration. In this case we want to filter the BeforeDraw action:

Infragistics.Win.DrawPhase Infragistics.
Win.IUIElementDrawFilter.
GetPhasesToFilter(ref Infragistics.
Win.UIElementDrawParams drawParams)
{
return Infragistics.Win.DrawPhase.
BeforeDrawElement;
}

This ensures that the second method will be called just before the control is drawn.

 



Last Updated ( Thursday, 17 February 2011 )