Search code examples
c#wpfxamlcode-behind

How to create DataTemplate with ItemsControl from code behind WPF


I have a custom ListView with some constant GridViewColumns, that I create in XAML like this

<GridViewColumn Header="Name" Width="150">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding ListOfSubObjects}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical"></StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding SubObjectName}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

ItemSource for the ListView itself is a list of objects that themselve contain a list of subobjects (ListOfSubObjects) to properties of which I want to bind the displayed text.

I want to dynamically add GridViewColumns with the same structure from code behind, but I can't find a way to add ItemTemplate with ItemSource to DataTemplate. How can I do it?


Solution

  • You could use the XamlReader.Parse method to create an elements from a XAML string dynamically:

    const string Xaml = "<ItemsControl ItemsSource=\"{Binding ListOfSubObjects}\">" +
    "                <ItemsControl.ItemsPanel>" +
    "                    <ItemsPanelTemplate>" +
    "                        <StackPanel Orientation=\"Vertical\"></StackPanel>" +
    "                    </ItemsPanelTemplate>" +
    "                </ItemsControl.ItemsPanel>" +
    "                <ItemsControl.ItemTemplate>" +
    "                    <DataTemplate>" +
    "                        <TextBlock Text=\"{Binding SubObjectName}\"/>" +
    "                    </DataTemplate>" +
    "                </ItemsControl.ItemTemplate>" +
    "            </ItemsControl>";
    
    ParserContext parserContext = new ParserContext();
    parserContext.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    parserContext.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
    
    ItemsControl itemsControl = XamlReader.Parse(Xaml, parserContext) as ItemsControl;