Polymorph
Topic Author
Posts: 2
Joined: 01 Mar 2023, 17:00

Don't understand how to set grid column of data collection

24 Apr 2024, 03:15

I'm having trouble trying to set the grid column of the elements of an ObservableCollection. Everything seems to end up the correct size, but all of them occupy column 0. I've only recently figured out how to do data binding, and it's still somewhat confusing to deal with collections and templates so I'm probably doing something wrong. I've cobbled together a xamltoy that replicates my attempt and problem in a stripped down way.

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
  xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions"
  d:DesignWidth="1280" d:DesignHeight="720">

    <Grid.Resources>
      <StackPanel x:Name="dataModel">
        <StackPanel Background="Red"/>
        <StackPanel Background="Green"/>
        <StackPanel Background="Blue"/>
        <StackPanel Background="Yellow"/>
      </StackPanel>
      <DataTemplate x:Key="PartyTemplate">
            
            
            <StackPanel x:Name="panel"/>

            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}" Value="0">
                    <Setter TargetName="panel" Property="Grid.Column" Value="0"/>
                    <Setter TargetName="panel" Property="Margin" Value="0,0,5,0"/>
                    
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}" Value="1">
                    <Setter TargetName="panel" Property="Margin" Value="5,0,5,0"/>
                    <Setter TargetName="panel" Property="Grid.Column" Value="1"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}" Value="2">
                    <Setter TargetName="panel" Property="Margin" Value="5,0,5,0"/>
                    <Setter TargetName="panel" Property="Grid.Column" Value="2"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}" Value="3">
                    <Setter TargetName="panel" Property="Margin" Value="5,0,0,0"/>
                    <Setter TargetName="panel" Property="Grid.Column" Value="3"/>
                </DataTrigger>
            </DataTemplate.Triggers>

            

        </DataTemplate>
    </Grid.Resources>
    
    <ItemsControl DataContext="{StaticResource dataModel}" ItemsSource="{Binding Children}" ItemTemplate="{StaticResource PartyTemplate}" AlternationCount="4">
      <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid Margin="10,0,10,10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>
Last edited by Polymorph on 24 Apr 2024, 04:48, edited 1 time in total.
 
User avatar
sfernandez
Site Admin
Posts: 3005
Joined: 22 Dec 2011, 19:20

Re: Don't understand how to set grid column of data collection

29 Apr 2024, 11:20

Hello,

Each of the items in the collection is wrapped with a "container" when added to the ItemsControl.ItemsPanel. For example, in a ListBox each item will be placed as the content of a ListBoxItem, in a ComboBox inside a ComboBoxItem... and in a plain ItemsControl the container will be a ContentPresenter (unless the item is a UIElement, in that case the item will be the container itself). This is why the ItemsControl exposes an ItemContainerStyle, so you can define any properties you need for that container.

In case you want to specify the Grid.Column of the item you have to set it in the container:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid.Resources>
    <GradientStopCollection x:Key="list">
      <GradientStop Offset="0" Color="Red"/>
      <GradientStop Offset="1" Color="Green"/>
      <GradientStop Offset="2" Color="Blue"/>
    </GradientStopCollection>
  </Grid.Resources>
  <ItemsControl Width="300" Height="300" ItemsSource="{Binding Source={StaticResource list}}" AlternationCount="3">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <Grid Background="Silver">
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
          </Grid.ColumnDefinitions>
        </Grid>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
      <Style TargetType="ContentPresenter">
        <Setter Property="Grid.Column" Value="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}"/>
      </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Rectangle>
          <Rectangle.Fill>
            <SolidColorBrush Color="{Binding Color}"/>
          </Rectangle.Fill>
        </Rectangle>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</Grid>
Please let me know if you need more help with this.

Just another suggestion, perhaps it would be more appropriate here to just use a UniformGrid and let it place the children in the corresponding column.
 
Polymorph
Topic Author
Posts: 2
Joined: 01 Mar 2023, 17:00

Re: Don't understand how to set grid column of data collection

30 Apr 2024, 02:15

Thank you for the knowledge. I agree that UniformGrid is definitely a solution for the problem I was trying to solve, I was just confused that I couldn't intuit what seemed like (and with this new information, is) a simple task. Figured I'd get some kind of insight from asking about it.
 
User avatar
sfernandez
Site Admin
Posts: 3005
Joined: 22 Dec 2011, 19:20

Re: Don't understand how to set grid column of data collection

30 Apr 2024, 21:05

Glad to help, marking this as solved then.

Who is online

Users browsing this forum: No registered users and 3 guests