WPF Control Inheritance With Generics

Working in WPF is quite exciting - there's a lot of new possibilities, especially with easy control composition, much improved binding and Expression Blend to make sexy interfaces. One of the things you're likely to want to do though, when writing anything more than a toy application, is to have a base class for your UserControls or Windows, to share common functionality. It is also quite likely you will want to use generics in conjunction with control inheritance. With both the code behind, and the XAML, it's not immediately obvious how to do generic inheritance. It is a bit fiddly to get going, and sometimes the errors are not helpful. Here's a simple example that outlines how to bring it together.

The base control

namespace WpfGenericsDemo
{
    public class BaseUserControl<T> : UserControl where T : IPresenter
    {
        public BaseUserControl()
        {
            ... various configurations ...
        }

         ... Awesome functionality to share ...
    }
}

The child control code-behind

namespace WpfGenericsDemo
{
    public partial class ChildUserControl : BaseUserControl<ChildPresenter>
    {
        public ChildUserControl()
        {
            InitializeComponent();
        }

         ... More code ...
    }
}

The child control XAML

<WpfGenericsDemo:BaseUserControl x:Class="WpfGenericsDemo.ChildUserControl"
    x:TypeArguments="WpfGenericsDemo:ChildPresenter"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfGenericsDemo="clr-namespace:WpfGenericsDemo">
    
    ... The rest of your awesome XAML ...

</WpfGenericsDemo:BaseUserControl>

Notes

  • Your top level node is the parent class of the control you want to create (eg, BaseUserControl). You specify the control class you want to create with 'x:class' (eg, ChildUserControl)
  • 'x:TypeArguments' is the way you specify the generic type (eg, ChildPresenter)
  • You need to namespace your classes - eg, with 'xmlns:WpfGenericsDemo' which uses a clr-namespace style reference
  • Only your top level node can be genericised in XAML

Actions

Information

11 responses to “WPF Control Inheritance With Generics”

13 09 2008
Todd Beaulieu (06:23:44) :

I've found little on this topic. Thanks for the post. I must be thick, but I just can't get this going. using VS 2008/3.5.

I have a ViewModel that I need to pass into a user control. No luck so far.

For starters, as soon as I add the generic construct, the InitializeComponent method disappears.

Assuming I can get this working, I was going to place an instance of each control, bound to various entities, on seperate PAGE objects that I am showing in a frame. It looks like I'd need to put them as root elements, though. I wonder if I can have a xaml file with just an instance of this UC with the x:TypeArguments specified and point a frame to it?

1 01 2009
Dan (01:10:37) :

You rock dude! Thats exactly what I was looking for. Thank you so much 😉

15 01 2009
Dave (01:38:54) :

Very good, straight to the point, article about how to use inheritance and generics with WPF.

After a few years web programming I'm back on desktop programming and a lot of things have changed. This post was very helpful starting with WPF on enterprise level.

4 03 2009
Tracy (03:52:53) :

Can I send you a quick sample that I am having troubles with? I have followed this model...but when I change the signature on the BaseUserControl
from :
public partial class BaseUserControl : UserControl

TO

public partial class BaseUserControl : UserControl where T : IPresenter

I receive the following error:

The name 'InitializeComponent' does not exist in the current context

C:\_SOURCE_\NewGenericsTWO\BaseUserControl.xaml.cs

It is probably something very simple... Can you help?

4 03 2009
Tracy (04:32:19) :

OOPS! I mean to say when I change from

public partial class BaseUserControl : UserControl

TO
public partial class BaseUserControl : UserControl where T : IPresenter

I receive an error. I fiddled with removing partial but still get errors.

Any help is welcome.

Any help would be wildly appreciated.

9 03 2009
M. Jahedbozorgan (01:18:44) :

Hi,
In your example, can the base control be a partial class? (I want the second part be a .xaml file)

8 12 2009
Patrice BIRROCHON (18:56:49) :

hello, very interesting example.
in my case, I have somes baseclass generic like this:

public class BaseClass: UserControl
{...}

public class BaseEditClass: BaseClass where T:
WCFService.EntityObj, new()
{...}

public class SomethingEdit : BaseEditClass
{...}

how can i declare my UserControl XAML ? Do you have an idea on this ? or is it impossible to declare a xaml like this:

Thanks in advance for your answer.
Patrice

8 12 2009
Patrice BIRROCHON (19:00:35) :

I refined my question. (some code disapear in my comment when i 've posted on your site ??)

is it possible to make an EntityObjet from a WCF Service to a "x:TypeArgument" in the xaml ?

to read you,
Patrice

9 12 2009
James (09:15:36) :

Hi Patrice, if the EntityObject is just a plain .net object, even if it has been generated, and it has properties, it should work OK. However, you won't have change events or similar, so won't be able to reflect changes in the object's data after initial bind. Rather than using the WCF service objects, you may want to introduce a domain layer that you control, and mapping in between. Your domain layer could then include change event notification for example, and decouple (somewhat) from changes in the services.
James

5 02 2010
Patrice (19:07:50) :

hello James,

I'm not sure to understand correctly your answer.

Here what I done:
My Application is already running with 3-layer for ASP.NET 3.5 and AJAX (UI, BLL, DAL).
To use my BLL with Silverlight, apparently, I must use a layer in addition: service web layer (I do it via WCF) so I write a WCF Service between my UISilverlight and my existing BLL.

I put attribute [DataMember] on all the properties of my entityobjects in my BLL.
So the WCF Service let me (in the UI) accessed to my entity objects.
Then, I decided to use this entityobject as object for my generic class (see mail above).

I write the inheritance code (see the mail above), no compilation problem.
I write simultaneously the xaml with special xmlns for my WCF object and the "x:TypeArgument"...
If I had a good understanding of the process, this tag is use to specify the generic class object.

Apparently the hidden file "xxxx.g.cs" isn't created with the generic inheritance but only with my baseClass without generic.

So a conflit appears in the partial xaml code because my partial class in codebehind declare a generic class ans the same partial class in the"xxxxx.g.cs" file declare only the class without inheritance.

Now that I presented my problem. What is for you, the best solution to resolve this ?
About the "change events" that you tell in your mail, how such a thing can be done with my project ? What do I need to change ?

To read you.
Patrice

3 03 2010
Soumow (19:32:56) :

Hello
I tried it with Visual Studio 2008 SP1 and Visual Studio 2010 RC and it doesn't work.
plz i need help.