Can a DataTemplate be tied to a nested class?
Asked Answered
K

1

16

Can a DataTemplate in XAML be associated with a nested class?

I am working on a MVVM application, and I have run into a data template problem. I have a view model providing a collection of other view models for an items control. These items are part of a hierarchy defined as nested classes in the outer view model. I have been unable so far to create a mapping in XAML to reference the inner nested class.

Here is the class hierarchy (simplified for brevity):

public class MainViewModel
{
    public class A
    {
    }

    public class B : A
    {
    }

    public class C : A
    {
    }

    public ObservableCollection<A> Items
    {
        get;
        set;
    }
}

In XAML, I'm trying to map a DataTemplate to types B and C, but I cannot fully qualify the nested class name.

<ItemsControl ItemsSource="{Binding Path=Items}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type ns:BracingViewModel.B}">
            <Grid>
            ....
            </Grid>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ns:BracingViewModel.C}">
            <Grid>
            ....
            </Grid>
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>

The problem : the references to the nested classes show up as a build error in the XAML. I get the following:

Error   5   Cannot find the type 'ns:B'. Note that type names are case sensitive. Line...

Error   5   Cannot find the type 'ns:C'. Note that type names are case sensitive. Line...

If I move the A,B,C class hierarchy outside the MainViewModel class (i.e. to the namespace level), this works fine.

As a general habit, I try to keep classes relevant to the view model defined as nested classes within it, but that leads me to this issue.

So, my question : is it even possible to associate a DataTemplate with a nested class? If so, how is that done in the XAML portion?

Thanks in advance... Joe

Koloski answered 9/10, 2012 at 18:46 Comment(0)
G
44

This works for me:

 <ItemsControl ItemsSource="{Binding Path=Items}">
        <ItemsControl.Resources>
            <DataTemplate DataType="{x:Type ns:MainViewModel+B}">
                <Grid Background="Blue"
                      Width="30"
                      Height="30">

                </Grid>
            </DataTemplate>
            <DataTemplate DataType="{x:Type ns:MainViewModel+C}">
                <Grid Background="Chartreuse" Width="30" Height="30">

                </Grid>
            </DataTemplate>
        </ItemsControl.Resources>
    </ItemsControl>

In other words, just change the . to + in the x:Type markup extension

credit to: this thread

Germane answered 9/10, 2012 at 19:36 Comment(4)
Works like a charm, though I immediately encountered the VS2010 issue with the WPF designer not being able to display the form when this is used. But, the binding did work fine.Koloski
How on god's earth is anyone expected to figure out this syntax? There should be a law banning Microsoft from designing and implementing APIs.Patterson
@ATL_DEV: strongly agree!Concertize
Great. It also works in Xamarin.Forms.Pourparler

© 2022 - 2024 — McMap. All rights reserved.