kindohm
kindohm

Reputation: 1600

WPF custom control with generics - possible?

I'd like to create a custom WPF control using generics:

public class MyGenericTypeControl<T> : ItemsControl 
{   
   // ...
}

Is this possible to do? In my initial experimentation, I get design-time/compile-time XAML errors as soon as I try to add this control somewhere. This isn't surprising, as construction of my custom control requires additional information that XAML does not provide.

Any ideas?

Upvotes: 10

Views: 8232

Answers (3)

brunnerh
brunnerh

Reputation: 184441

There is limited support using x:TypeArguments

For XAML 2006 usage, and XAML that is used for WPF applications, the following restrictions exist for x:TypeArguments and generic type usages from XAML in general:

  • Only the root element of a XAML file can support a generic XAML usage that references a generic type.
  • The root element must map to a generic type with at least one type argument. An example is PageFunction<T>. The page functions are the primary scenario for XAML generic usage support in WPF.
  • The root element XAML object element for the generic must also declare a partial class using x:Class. This is true even if defining a WPF build action.
  • x:TypeArguments cannot reference nested generic constraints.

Upvotes: 6

unknown6656
unknown6656

Reputation: 2963

You can only do it the other way around (a non-generic control inhering from a generic base class):

public class BaseControl<T> : Control
{
   // base implementation
}


public class MyControl : BaseControl<string>
{
   // ...
}

with the XAML for MyConrtrol looking as follows:

<local:MyControl x:Class="BaseControl"
                 x:TypeArguments="sys:String"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:MyNamespace"
                 xmlns:sys="clr-namespace:System;assembly=System.Runtime">
    ....
<local:MyControl/>

Please note the attribute x:TypeArguments=".....". If your type parameter is itself generic, then you can use e.g. the following:

<local:MyControl x:Class="BaseControl"
                 x:TypeArguments="sys:Tuple(sys:String,sys:Int32)"
                 ...>

The code would be equivalent to:

public class MyControl : BaseControl<Tuple<string, int>>
{
   // ...
}

Upvotes: 3

Dean Chalk
Dean Chalk

Reputation: 20451

XAML doesnt support generics, you'd need to create an empty non-generic class that inherits from your generic control and use that with your XAML

Upvotes: 3

Related Questions