Recently I received an enquiry asking if I can provide documentation and support for DockPanel Suite similar as provided for WPF Docking, which he is willing to pay more for that. Well I love to get paid (who else not?), but after consideration I had to reply with the answer “no”. One main reason is the DockPanel Suite design is limited by Windows Forms architecture and has little room to improve. This will make support very difficult or even impossible. I can’t fail customer satisfaction. This post discusses the comparison between WPF and Windows Forms, from control authoring perspective.
Custom Control Authoring in General
Control authoring is all about code reuse. Composition and inheritance are two techniques for code reuse in object-oriented systems. For those who don’t know composition and inheritance design pattern, Here is a “composition vs. inheritance” search result page returned by google. In general, object composition should be favored over inheritance.
The biggest advantage of WPF over Windows Forms, from my point of view, is that you can use composition to implement your custom control, resulting in multiple smaller, loosely coupled classes. Please note we’re talking about custom control instead of user control composition, as user control composition is more about consuming the existing controls than authoring new controls.
In general, we can abstract custom control authoring as following:
- Design PMEs(properties/methods/events);
- Providing the graphic user interface;
- Handling the mouse/keyboard input from the user interface.
WPF provides attached property/event, template and routed event, so that you can implement these separately, in a loosely coupled manner (composition). In Windows Forms world it’s just not possible.
Attached Property/Event – Designs Smaller Type
Attached properties/events are a way to extend types with properties/events that are provided by other types. This is the best part from my point of view – you can design each of your type with much fewer PME, but it’s still extensible through other class. In Windows Forms, you’re limited to use inheritance to extend existing control, resulting in either complex inheritance hierarchy or limited functionality. A great example is to look at the .Net Framework itself: Windows Forms Control class supports canvas layout (absolute position) through the Left and Top properties, and docking layout through Dock property. If you want to have another layout support, you have to either modify the Control class, or inherit a new type from Control class, to implement the new properties. In WPF, the Control class defines no property for layout at all, the layout is handled by its containing panels, through the attached properties: Canvas.Left, Canvas.Top for canvas layout, DockPanel.Dock for dock layout, etc.
System.Windows.Controls.Control class defines much fewer PME than
System.Windows.Forms.Control class, but still keeps far better extensibility. The same holds true for
DevZest.Windows.Docking.DockControl class and
Template – Separates User Interface
WPF Template can transform any object into graphic user interface, declaratively. Here is a great blog posted by Josh Smith may help you understand templates in WPF. This has two major advantages:
- You can design smaller, loosely coupled types because the user interface is separated into templates.
- The control is fully customizable. You can apply another totally different user interface to your control without changing any of existing code.
Let’s take WPF Docking as an example. The types for window hierarchy (FloatingWindow, DockTree, DockPaneSplit and DockPane class) are not even UI element derived. The implementation of these types, has absolutely nothing to do with the user interface - clean implementation and fully customizable!
Routed Event – Handles the Input
A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event. In WPF, all input are implemented as routed event. As control author, you have more freedom to decide which type to implement the input handling, results in smaller, loosely coupled types, again.
For example, the SplitContainer class needs to handle the mouse and keyboard input to resize the child panels. In Windows Forms, only the splitter can raise these events. In order to handle these input events, the splitter class must be tightly coupled with the SplitContainer class. In the WPF SplitContainer implementation, the events are listened and handled at SplitContainer class, no matter how the splitter will be implemented (by template), because the events will always be bubbled through the element tree up to the SplitContainer class.
The Other Side of the Coin
Unlike Windows Forms, in many ways forces you to implement your custom control in a flat, tightly coupled manner, WPF allows you to implement smaller, loosely coupled types and composite these types together. But it comes with a price: the complexity of WPF itself. This leads to the following two main constraints:
- A significant learning curve is required to ensure everything properly implemented in a WPF way, as it’s really a mindset shift especially when you comes with a Windows Forms background. I’m a quick learner (seriously), I spent 6 months to design and develop WPF Docking, after I spent years on DockPanel Suite, a very similar control.
- The designer support. Designer support in Windows Forms is much simpler, because controls are implemented in a flat manner. In WPF, this can get very complex, because there are virtually unlimited possibilities. To develop WPF application/component, you have to be comfortable with programming XAML language manually. I guess this is the main reason why many Windows Forms developers are being reluctant switching to WPF – the intuitive, simple to use, and love at the first sight designer, is gone.
WPF is a great platform to develop applications/components utilizing composition code reuse, not just for applications simply require “eye candy”, as the most common and frustrating misperception. However, switching from Windows Forms to WPF requires a significant learning curve.
Back to DockPanel Suite support. The implementation of DockPanel Suite is tightly coupled each other, due to the limitation of Windows Forms. A common support request will result in code change, which could mess up the whole thing because they are tied up together.