Search code examples
c#wpfxamldata-binding

Nested Binding & Layout in ListView with UniformGrid


I'm new to WPF/XAML and have some decent problems with data-binding und layout. What i try to achieve: a List with a single Row of Grid Cells (just Text and BackgroundColor) and below some Textblocks. My XAML looks like this:

    <Window.Resources>
    <DataTemplate x:Key="GridLayoutTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="0" Grid.Column="0" Fill="{Binding RowData.RowColor}" />
            <TextBlock Text="{Binding RowData.RowText}" />
        </Grid>
    </DataTemplate>


    <DataTemplate x:Key="ListLayoutTemplate">
        <StackPanel VerticalAlignment="Stretch">
            <ItemsControl ItemTemplate="{StaticResource GridLayoutTemplate}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="1" Columns="9"></UniformGrid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl> 
            <Grid Background="Green">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Rectangle Grid.Row="0" Grid.Column="0" Fill="{Binding TileColor}" />
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding TileText}" />
            </Grid>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<ListView ItemTemplate="{StaticResource ListLayoutTemplate}" Name="lvDataBinding">
</ListView>

Code behind:

public Test()
        {
            InitializeComponent();
            List<DataObject> items = new List<DataObject>();
            List<Row> rowItem = new List<Row>();
            rowItem.Add(new Row()
            {
                RowColor = "Red",
                RowText = "Text1"
            });
            rowItem.Add(new Row()
            {
                RowColor = "Blue",
                RowText = "Text2"
            });


            items.Add(new DataObject()
            {
                TileColor = "Black",
                TileText = "Blibb",
                RowData = rowItem
            });

            items.Add(new DataObject() { TileColor = "Yellow", TileText = "Blubb", RowData=rowItem });
            items.Add(new DataObject() { TileColor = "Red", TileText = "Blabb", RowData=rowItem });
            this.lvDataBinding.ItemsSource = items;
        }
    }

    public class DataObject
    {
        public string TileText { get; set; }
        public string TileColor { get; set; }
        public List<Row> RowData { get; set; }
    }

    public class Row
    {
        public string RowText { get; set; }
        public string RowColor { get; set; }
    }

If i run this it only shows the rows for the listview and not the uniformgrid. the binding for the listview item is ok, but i have no idea for the uniformgrid, the layout could also be wrong. confusing over all.


Solution

  • Bind the ItemsSource property of the ItemsControl to RowData and remove "RowData." from the binding paths in the GridLayoutTemplate:

    <DataTemplate x:Key="GridLayoutTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="0" Grid.Column="0" Fill="{Binding RowColor}" />
            <TextBlock Text="{Binding RowText}" />
        </Grid>
    </DataTemplate>
    
    
    <DataTemplate x:Key="ListLayoutTemplate">
        <StackPanel VerticalAlignment="Stretch">
            <ItemsControl ItemsSource="{Binding RowData}" ItemTemplate="{StaticResource GridLayoutTemplate}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="1" Columns="9"></UniformGrid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
            <Grid Background="Green">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Rectangle Grid.Row="0" Grid.Column="0" Fill="{Binding TileColor}" />
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding TileText}" />
            </Grid>
        </StackPanel>
    </DataTemplate>