Search code examples
c#wpfmvvmitemscontrol

Populating ItemsControl Using Uniform Grid as ItemsPanel Column First


I have an ObservableCollection of 24 Things.

   private ObservableCollection<Thing> things;
        public ObservableCollection<Thing> Things
        {
            get => things;
            set
            {
                things= value;
                RaisePropertyChanged();
            }
        }

I also have a selected Thing

   private Thing selectedThing;
        public Thing SelectedThing
        {
            get => selectedThing;
            set
            {
                selectedThing= value;
                RaisePropertyChanged();
            }
        }

I need to display these items in a grid. I am creating a grid of buttons, each with a command and a command parameter that allows me to set selected Thing from the collection.

I need to populate this grid COLUMNS first. I.E:

enter image description here

Is there a way to do this in WPF Using an ItemsControl and a Uniform grid?

   <ItemsControl ItemsSource="{Binding Things}" HorizontalAlignment="Center" Margin="20">

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                   <UniformGrid Columns="3" Rows="8"  />




                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate>



                    <Button Content="{Binding ThingPosition}" 
                        Height="30"
                        Width="80"
                            Margin="3"
                        FontSize="8"
                        Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.SelectThingCommand}" 
                        CommandParameter="{Binding Path=.}"/>



                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

Solution

  • In case a simple reordering of the elements in the ItemsSource collection is not possible, the following LayoutTransforms should do the job:

    <ItemsControl ...>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="3">
                    <UniformGrid.LayoutTransform>
                        <TransformGroup>
                            <RotateTransform Angle="-90"/>
                            <ScaleTransform ScaleY="-1"/>
                        </TransformGroup>
                    </UniformGrid.LayoutTransform>
                </UniformGrid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="LayoutTransform">
                    <Setter.Value>
                        <TransformGroup>
                            <ScaleTransform ScaleY="-1"/>
                            <RotateTransform Angle="90"/>
                        </TransformGroup>
                    </Setter.Value>
                </Setter>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            ...
        </ItemsControl.ItemTemplate>
    </ItemsControl>