DataTemplates are a great feature introduced in WPF, it allows to determine how data is presented and how data binding accesses the presented data. Just as we can apply a visual style to a specific UI control, we can do it for a specific data type. There is just one problem here, DataTemplates are good for object types but not for interfaces

Lets take a look at the following code, where ILibrary interface is defined and Library class implicitly implement ILibrary interface:



interface ILibrary 
{ 
    string PropertyA { get; } 
}      

class Library : ILibrary 
{ 
    public string PropertyA 
    { 
        get 
        { 
            return "Dev102"; 
        } 
    } 
}

Here is the XAML code where a data template for the Library object type is defined:

<Window.Resources> 
    <DataTemplate DataType="{x:Type local:Library}"> 
        <TextBlock Text="{Binding PropertyA}" /> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <Canvas> 
        <Button Name="buttonA"> 
        </Button> 
    </Canvas> 
</Grid>

And here we set the button content:

public Window1() 
{ 
    InitializeComponent(); 
    ILibrary lib = new Library(); 
    this.buttonA.Content = lib; 
}

This is how the button looks when running this code, the button contains a text block that is binded to PropertyA which returns an hard coded string: “Dev102″.:

image

What happens if we change the data type of the data template to a non object type (the ILibrary interface), like this:

<DataTemplate DataType="{x:Type local:ILibrary}">

The result is that the data template is ignored:

image

Don’t try to find a bug in my code, after doing some search I understood that  the reason for what happened here is simple: there is no support for interfaces. The WPF data team discussed this issue but could not come up with a good design for it. They had two major problems:

  1. There is multiple inheritance for interfaces. Think about a situation where the data source implement more than one interface and there are data templates for all of those interfaces. What data template shall be picked up?
  2. Reflection shall be used in order to support interfaces and that is not cheap.

As I demonstrated in the code above, although its not elegant, there is away out from this problem – create the data template for the object type (not for the interface). But, in the code above, I implicitly implemented the interface, what would happen if explicit implementation was used (Read about the 4 Key Differences Between Implicit and Explicit Interface Implementation)?

Take a look at the new explicit implementation:

class Library : ILibrary 
{ 
    string ILibrary.PropertyA 
    { 
        get 
        { 
            return "Dev102"; 
        } 
    } 
}

Now, there is no way to do a data template for the Library class too, this is what we get:

image

So, to put thing together, data templates for interfaces is not supported. If the object type implicitly implements that interface then there is a way out. If the object type explicitly implements the interface, there is no way to do a data template for it in WPF.

Tags :

7 Responses to “WPF DataTemplate for Interfaces? Not Supported”


  1. maZZoo

    Said on March 27, 2009 :

    It works for Abstract Classes though :)

  2. Sridhar Nathani

    Said on June 10, 2011 :

  3. clark

    Said on June 17, 2012 :

  4. Tomasz Weso?owski

    Said on July 10, 2012 :

    Another handy workaround is to use a custom DataTemplateSelector.

3 Trackback(s)

  1. Apr 24, 2008: OMG… Data Templates doesn’t support interfaces!!! « Aizikovich Evgeni
  2. Jun 13, 2008: WHY SHOULD YOU USE THE X:KEY ATTRIBUTE IN WPF DATATEMPLATES | Dev102.com
  3. Jul 29, 2008: HOW TO CREATE A WPF TEMPLATE FOR A GENERIC CLASS | Dev102.com

Post a Comment