Search code examples
c#wpfdatatemplateitemscontrol

ItemsControl with DataTemplate in code behind only displays one item


I'm trying to create a DataTemplate from the code behind but using it in an ItemsControl, only one item is displayed ...

If I describe the DataTemplate in XAML, i have all the items.

I use the code described here to create my DataTemplate: https://stackoverflow.com/a/25428280/9725495

In full XAML:

<ItemsControl ItemsSource="{Binding Radios}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Height="40">
                    <TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis" Margin="6" HorizontalAlignment="Left" VerticalAlignment="Center" />
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Result full xaml

This is my code behind :

        var grid = new Grid();
        grid.Height = 40;

        var textblock = new TextBlock();
        textblock.SetBinding(TextBlock.TextProperty, "Name");
        textblock.Margin = new Thickness(6);
        textblock.TextTrimming = TextTrimming.CharacterEllipsis;
        textblock.HorizontalAlignment = HorizontalAlignment.Left;
        textblock.VerticalAlignment = VerticalAlignment.Center;

        grid.Children.Add(textblock);

        RadioDataTemplate = TemplateGenerator.CreateDataTemplate(() => grid);

  <ItemsControl ItemsSource="{Binding Radios}" ItemTemplate="{Binding RadioDataTemplate}" />

Result code behind

EDIT :

Problem with SharedSizeGroup

RadioDataTemplate = TemplateGenerator.CreateDataTemplate(() =>
        {
            var grid = new Grid();
            grid.Height = 40;

            for (int i = 1; i <= 2; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });

                if (i < 2)
                    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto), SharedSizeGroup = "A" });
            }

            var image = new Image();
            image.SetBinding(Image.SourceProperty, "Image");
            image.Stretch = System.Windows.Media.Stretch.Uniform;
            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality);
            image.HorizontalAlignment = HorizontalAlignment.Center;
            image.VerticalAlignment = VerticalAlignment.Center;

            grid.Children.Add(image);
            Grid.SetColumn(image, 0);

            var gridsplitter = new GridSplitter();
            gridsplitter.HorizontalAlignment = HorizontalAlignment.Stretch;
            gridsplitter.Width = 5;
            gridsplitter.Background = new SolidColorBrush(Colors.Red);

            grid.Children.Add(gridsplitter);
            Grid.SetColumn(gridsplitter, 1);

            var textblock = new TextBlock();
            textblock.SetBinding(TextBlock.TextProperty, "Name");
            textblock.Margin = new Thickness(6);
            textblock.TextTrimming = TextTrimming.CharacterEllipsis;
            textblock.HorizontalAlignment = HorizontalAlignment.Left;
            textblock.VerticalAlignment = VerticalAlignment.Center;

            grid.Children.Add(textblock);
            Grid.SetColumn(textblock, 2);

            return grid;
        });

Result SharedSizeGroup


Solution

  • It's unclear why you want to do that at all, at least it is totally unusual to create a DataTemplate in code behind. Anyway,

    () => grid
    

    returns always only the same single Grid instance that you created before.

    However, you have to create a new one in each call:

    RadioDataTemplate = TemplateGenerator.CreateDataTemplate(() =>
    {
        var grid = new Grid();
        grid.Height = 40;
    
        var textblock = new TextBlock();
        textblock.SetBinding(TextBlock.TextProperty, "Name");
        textblock.Margin = new Thickness(6);
        textblock.TextTrimming = TextTrimming.CharacterEllipsis;
        textblock.HorizontalAlignment = HorizontalAlignment.Left;
        textblock.VerticalAlignment = VerticalAlignment.Center;
    
        grid.Children.Add(textblock);
        return grid;
    });