maplemale
maplemale

Reputation: 2036

WPF DataGrid Vertical Scroll Bar Issues with Dynamically Loaded Item Source

The issue: Cannot get the Vertical Scroll bar for the DataGrid to appear unless I set a static height on the grid. I know similar questions have been asked before, however unlike other questions my example is a lot more simple with no Grid Columns. The DataGrid is simply inside a StackPanel inside the control. That's it, and no combination of Auto, "*", etc works except setting a static Height.

Is this simply a lacking feature in WPF framework that it a Observable Collection on the ViewModel bound to a grid, will not notify the View when items are added to the VM Collection? Do I have to code a custom property and bind the DataGrid Height to that?

Here is my XMAL:

<Window x:Class="Monster.Configure"
        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"
        xmlns:viewModels="clr-namespace:Monster.ViewModels"
        xmlns:local="clr-namespace:Monster"
        mc:Ignorable="d"
        Title="Configure" Width="1200">
    <Window.DataContext>
        <viewModels:ViewModelMain/>
    </Window.DataContext>
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="b2v" />
    </Window.Resources>
    <Grid>
        <StackPanel Margin="5">

            <Button Name="button_Refresh" Content="Save / Refresh" HorizontalAlignment="Left" Margin="5" Width="100"
                    Click="button_Refresh_Click"></Button>
            <StackPanel Orientation="Horizontal">
                <!--Buttons and other junk here-->
            </StackPanel>
            <Label></Label>

                <DataGrid Name="dataGrid_PendingCreation" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False"
                        ItemsSource="{Binding URLsForGrid}" 
                        Loaded="dataGrid_PendingCreation_Loaded"
                        CellEditEnding="dataGrid_PendingCreation_CellEditEnding"
                        ScrollViewer.CanContentScroll="True"
                        ScrollViewer.VerticalScrollBarVisibility="Auto"
                        ScrollViewer.HorizontalScrollBarVisibility ="Auto"
                        Width="Auto" Height="Auto">

                    <DataGrid.Columns>

                    <!--Columns and junk here-->

                    </DataGrid.Columns>
                </DataGrid>


        </StackPanel>
    </Grid>
</Window>

As you can see, the user is allowed to add new rows. When doing so, a Vertical Scroll Bar never shows up unless a Static Height is set in the DataGrid.

Upvotes: 2

Views: 1992

Answers (1)

FrankM
FrankM

Reputation: 1107

Your DataGrid is wrapped inside a StackPanel (with vertical orientation). A vertically oriented StackPanel always gives seemingly infinite available height to its children. Since your DataGrid's Height property is set to Auto, it will grow as large as it can; it will never show a vertical scrollbar, because this is done only if the DataGrid's available height (determined by the parent) is less than the actually needed height.

The solution is not to use a StackPanel here. Instead, use a Grid or a DockPanel. I usually prefer the latter, if all I want to achieve is vertical or horizontal stacking of the children and have one child stretch as wide as possible; here is how it would be done:

<Window>
    ...
    <Grid>
        ...
        <DockPanel Margin="5">
            <Button DockPanel.Dock="Top" Name="button_Refresh" ... />
            <StackPanel  DockPanel.Dock="Top" Orientation="Horizontal">
                <!--Buttons and other junk here-->
            </StackPanel>
            <Label DockPanel.Dock="Top"></Label>
            <DataGrid Name="dataGrid_PendingCreation" ... />
        </DockPanel>
        ...
    </Grid>
    ...
</Window>

Make sure that DataGrid is the last child in the DockPanel and that it has no DockPanel.Dock property. This ensures that the DataGrid will be given the available height and width that remains after placing all other controls.

Upvotes: 3

Related Questions