Search code examples
wpfbindingelementname

Bind the Height of the Listbox inside the StackPanel to StackPanel`s height


I want to bind the Height of the ListBox to the Height of the StackPanel so the ListBox stretches itself Vertically so the green area is not visible anymore.

When there is no item in the listbox its hidden. When there is item > 1 the ListBox must be stretching itself to the add/del buttons so the add/del buttons are always at the bottom of the stackpanel(dont want to use dockpanel for that)

How can I do that? I get no binding erros?

<StackPanel x:Name="stack" Background="Green" DataContext="{Binding DocumentViewModelList/}" Orientation="Vertical" >
    <ListBox SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="False"
        SelectedItem="{Binding SelectedDocumentViewModel,Mode=TwoWay}"
        Height="{Binding ElementName=stack,Path=Height}"                                               
        Width="Auto"
        Focusable="True"
        ScrollViewer.HorizontalScrollBarVisibility="Auto" 
        ScrollViewer.VerticalScrollBarVisibility="Auto" 
        Grid.Row="1" 
        Name="documentListBox"
        BorderThickness="1"                                                
        ItemsSource="{Binding DocumentList}"
        Visibility="{Binding ElementName=documentListBox,Path=HasItems, Converter={StaticResource boolToVisibilityConverter}}">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Id}" />
                    <TextBlock Text="{Binding Path=Name}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>

        <!--<ListBox.ItemContainerStyle>                                                  
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" />                                                      
        </Style>      
        </ListBox.ItemContainerStyle>-->                                        
    </ListBox>                                                                                      
</StackPanel>

alt text


Solution

  • Simply use a Grid instead of a StackPanel:

    <Grid x:Name="grid" 
          Background="Green" 
          DataContext="{Binding DocumentViewModelList}">
    
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <ListBox Grid.Row="0"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch"  ..... />
    
        <UniformGrid Grid.Row="1"
                     Rows="1"
                     HorizontalAlignment="Center"
                     VerticalAlignment="Bottom">
            <Button Content="Delete" />
            <Button Content="Add" />
            <Button Content="Open" />
        </UniformGrid>
    
    </Grid>
    

    The ListBox simply takes up the entire space of the first row, while the UniformGrid takes up the bottom row with only the space it needs (and makes the buttons all the same size as a bonus).

    No need for hard-coded width/height values (or any bindings for height/width), and no value converters needed.