Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make an ItemsControl stretch to fill all available space?

I have an ItemsControl, with its ItemsSource bound to a list of items. The size of each of the items is as small as they can be, what I need is for the control and the items in the control to stretch to fit all available space.

I tried setting VerticalAlignment to Stretch on both the control, and its items (using a style). I also tried wrapping the ItemsControl in a DockPanel, and docking the ItemsControl to the bottom. How do I have the ItemsControl dynamically resize?

Also some, but not all, of the item's visibilities are set to Collapsed (through the same style). Will that be a factor in how this needs to be done?

<DockPanel HorizontalAlignment="Stretch">
    <ItemsControl DockPanel.Dock="Bottom"
                    ItemsSource="{Binding Owner.LoadPointCharts}"
                    HorizontalAlignment="Stretch"
                    x:Name="ItemsControl">
        <ItemsControl.ItemContainerStyle><!--Height="{Binding Path=Height, RelativeSource={RelativeSource AncestorType={x:Type DockPanel}}}"-->
            <Style TargetType="ContentPresenter">
            <Setter Property="VerticalAlignment"
                    Value="Stretch" />

                <Setter Property="Visibility">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource CompareIndexToVisibilityConverter}">
                        <Binding Path="Index" />
                        <Binding Path="SelectedIndex" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            </Style >
        </ItemsControl.ItemContainerStyle>
        </ItemsControl>
</DockPanel> 
like image 631
kleineg Avatar asked Apr 15 '16 17:04

kleineg


4 Answers

The accepted answer is a little too complex in my opinion. Also setting the positions of your items in a Grid can be annoying. UniformGrid is what you need.

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
like image 172
Florian Lavorel Avatar answered Nov 13 '22 02:11

Florian Lavorel


I had the same problem and found out that ItemsControl by default uses a StackPanel for his children. Replacing this with a Grid solved the problem:

 <ItemsControl>
      <ItemsControl.ItemsPanel>
           <ItemsPanelTemplate>
                <Grid />
           </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
 </ItemsControl>

Edit: This only works for one child element!

like image 37
SpeziFish Avatar answered Nov 13 '22 02:11

SpeziFish


I think this ought to work, depending on what contains the outermost Grid.

By default, a Grid will stretch to fill its container, and it'll cause its contents to stretch to fill itself. If you're putting the ItemsControl in a DockPanel and setting DockPanel.Dock="Bottom" on the ItemsControl, it'll fill the bottom of the DockPanel, so if I understand correctly, that's not what you want.

<Grid>
    <ItemsControl 
        ItemsSource="{Binding Owner.LoadPointCharts}"
        x:Name="ItemsControl"
        >
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="VerticalAlignment" Value="Stretch" />
                <Setter Property="HorizontalAlignment" Value="Stretch" />

                <Setter Property="Visibility">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource CompareIndexToVisibilityConverter}">
                            <Binding Path="Index" />
                            <Binding Path="SelectedIndex" />
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style >
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Grid>

Grid is kind of the Swiss Army boat anchor of XAML layout. Throw 'em around everywhere.

If you want to dock other stuff in a DockPanel, here's a simple DockPanel layout:

<Window xmnls:blah="blah blah etc.">
    <Window.DataContext>
        <local:MyViewModel />
    </Window.DataContext>
    <Grid>
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <!-- Menu Items-->
            </Menu>
            <Grid>
                <!-- 
                This assumes we've got a DataTemplate in a resource dictionary  
                somewhere with DataType="{x:Type local:MyViewModel}" 
                -->
                <ContentControl
                    Content="{Binding}"
                    />
            </Grid>
        </DockPanel>
    </Grid>
</Window>
like image 1
15ee8f99-57ff-4f92-890c-b56153 Avatar answered Nov 13 '22 03:11

15ee8f99-57ff-4f92-890c-b56153


The Grid as Template won't work since items are put over under. Using a DockPanel works fine:

  <ItemsControl>
  <ItemsControl.ItemsPanel>
       <ItemsPanelTemplate>
            <DockPanel/>
       </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

like image 1
deafjeff Avatar answered Nov 13 '22 02:11

deafjeff