T James
T James

Reputation: 502

WPF bound listBox vertical alignment not working as expected

After reading everything I could find about WPF listbox and stack panel controls, I am still at a loss as to what is causing this behavior. I would like for my listbox to stack the items from the top down without a significant amount of space, however no matter what I do it seems to place a large gap between each one. I have made sure to include the VerticalContentAlignment="Top" property to the listbox and set the vertical alignment of my stack panel so it does not default to stretch. Here is the code:

<Grid>

        <ListBox x:Name="listView" HorizontalAlignment="Stretch" SelectionMode="Multiple" IsHitTestVisible="True" VerticalContentAlignment="Top">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="1"/>
                </ItemsPanelTemplate>

            </ItemsControl.ItemsPanel>

            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="IsSelected" Value="{Binding Content.IsSelected, Mode=TwoWay, RelativeSource={RelativeSource Self}}"/> 
                    <Setter Property="VerticalContentAlignment" Value="Top"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <ContentPresenter/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>


            <ListBox.ItemTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,0,0,10" VerticalAlignment="Top" Background="Black">
                        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},Path=IsSelected}" BorderBrush="#FF242424" VerticalAlignment="Center">
                            <CheckBox.LayoutTransform>
                                <ScaleTransform ScaleX="4" ScaleY="4" />
                            </CheckBox.LayoutTransform>
                        </CheckBox>                      
                        <Image Source="{Binding Image}" HorizontalAlignment="Left"  VerticalAlignment="Top" Stretch="None" />
                        <StackPanel Orientation="Vertical" VerticalAlignment="Top">
                            <TextBlock Text="{Binding Test1}" FontSize="22" Margin="5,0,0,3" FontWeight="UltraLight"></TextBlock>
                            <TextBlock Text="{Binding Test2}" FontSize="11" Foreground="#FF585656" Margin="5,0,0,3" FontWeight="UltraLight"/>
                            <TextBlock Text="{Binding Test3}" FontSize="11" Foreground="#FF585656" Margin="5,0,0,0" FontWeight="UltraLight"/>
                        </StackPanel>

                    </StackPanel>

                </DataTemplate>


            </ListBox.ItemTemplate>

        </ListBox>
    </Grid>

And here is the result:

enter image description here

I added the black background to the stack panel item for troubleshooting purposes to ensure that it is not stretching to the available height.

No matter what I do, it appears to be correctly placing the first list item at the top, but them placing large gaps between all consecutive items. Any ideas?

Upvotes: 0

Views: 1224

Answers (1)

The UniformGrid in your ItemsPanelTemplate divides the available space evenly among the children. Add a Background setter in your ItemContainerStyle, and you'll see that the ListBoxItems are occupying all that white space. Their content is top-aligned, but they themselves are stretched vertically to fill the "cells" their parent, the UniformGrid, gives them.

If your ListBoxItem.VerticalContentAlignment were Stretch, along with the VerticalAlignment of the StackPanel in the DataTemplate, the item content would stretch to fill the ListBoxItems. But that's not what you want.

You can use a vertically oriented StackPanel in your ItemPanelTemplate if you want the items to fill from the top. That's the default that the ListBox creates for itself, so if you just remove the ItemPanelTemplate, that's what you'll get.

Upvotes: 2

Related Questions