WPF Grid Expander Listview vertical scrollbar missing - wpf

I have the following UI element tree:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid>
<Expander>
<ListView/>
</Expander>
<Expander>
<ListView/>
</Expander>
</Grid>
I have set ScrollViewer.CanContentScroll="True", ScrollViewer.HorizontalScrollBarVisibility="Auto", ScrollViewer.VerticalScrollBarVisibility="Auto". However, the content of the ListView extends beyond the widow size without showing any vertical scroll bar at all. Any advice and insight is appreciated.

Auto will fit to the content (that's why it stretches). So you need to change Height to * to be able to take any available space.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

Related

How do I make a WPF layout Grid fill all available vertical space?

I have a form with two Grid elements in a vertical StackPanel. I would have imagined the bottom Grid would automatically fill all available space, as I wish it to, but I have set heights on the Grid rows:
<RowDefinition Height="20" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
The short rows at the top and bottom are for labels and buttons, respectively. I have tried setting the grid's VerticallAllignment to Stretch, to no avail.
How do I anchor the bottom of the bottom grid to the bottom of the form, regardless of the form's height?
Essentially you can't use StackPanel to fill all available vertical space.
But you may use a DockPanel:
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Top"/>
<Grid />
</DockPanel>
You may also use a Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"/>
<Grid Grid.Row="1"/>
</Grid>

Grid in a Grid with RowDefinition Height="auto" suppresses Height="*" of child Grid's RowDefinitions

I have the following code:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" TextBlock.Foreground="Blue" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="test" Grid.Row="0" />
<TextBlock Text="test" Grid.Row="2" />
</Grid>
<Grid Grid.Row="1" TextBlock.Foreground="Red" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="test" Grid.Row="0"/>
<TextBlock Text="test" Grid.Row="2"/>
</Grid>
</Grid>
It's simply two equal grids with three rows, all three which should be of equal size (each in its own grid, that is).
The bottom grid, contained in the parent row with a height of "*" behaves as expected. Each row is of equal size, regardless of what is put into it.
But the top grid, contained in a row with height Auto, seems to discard the Height="*", and behave as if they had Height="Auto". The first and third row gets exactly the height they ask for, and the second, the empty row, is just given a height of 0. Is this normal behaviour? And if so, why is it the way it is?
This is how it appears:
And this is how I would expect it to work:
This behaviour is expected. Height="*" means that all rows will share evenly available space
The value is expressed as a weighted proportion of available space
When you set parent row height to auto it means that child Grid is not stretched vertically any more so there is no free space to share so rows will take only as much space as they need to. It's like you would set VerticalAlignment="Top" for example.
You can achieve what you want by using SharedSizeGroup on the top Grid. In this scenario all rows belong to the same group and all will share same height
<Grid Grid.Row="0" IsSharedSizeScope="True" TextBlock.Foreground="Blue" ShowGridLines="True" >
<Grid.RowDefinitions>
<RowDefinition SharedSizeGroup="CommonRow"/>
<RowDefinition SharedSizeGroup="CommonRow"/>
<RowDefinition SharedSizeGroup="CommonRow"/>
</Grid.RowDefinitions>
<TextBlock Text="test" Grid.Row="0" />
<TextBlock Text="test" Grid.Row="2" />
</Grid>
it behaves is normally.
when you set Height="*" that means fill the rest of space, while Height="Auto" means fit to all inner controls. so the first row is fitting all the controls that you have which they are only two, and because there is no Height property set to first inner grid or TextBlocks it takes only the height that equal yourFirstTextBlock.Height + yourSecondTextBlock.Height.

WPF Layout - Fill Height, Auto Scrollbar

The Grid at the bottom contains a ListBox. It stretches vertically, but the scrollbar does not appear when it reaches the bottom.
Layout --
<RibbonWindow ResizeMode="CanResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel>
<Ribbon ... />
<ListBox
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
/>
</StackPanel>
</Grid>
</RibbonWindow>
I have heard that StackPanels can cause this behavior, but replacing it with a Grid causes its own set of issues.
EDIT --
This Layout works -
<RibbonWindow ResizeMode="CanResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Ribbon Grid.Row="0" />
<ListBox Grid.Row="1"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
/>
</Grid>
</RibbonWindow>
Turns out I needed the Grid.Row="x" tags, and then I could remove the StackPanel, and everything worked.

Border background image will not span entire border

I am writing a WPF application. In the application I have a grid that has two columns. The one column has a border tag that, when the application runs, spans the height of the main window with no issues.
The problem that I am running into is that I want a background image to also span the height of the application and be contained within the border. When I run the application, however, it only takes up enough space to provide background for the controls that exist on the page. This means that more than half of that grid column remains white. I have tried stretching the image (set the stretch to fill) and I know that the image is large enough.
Please, how can I achieve what I am looking for?
Here is the important XAML:
<Border>
<Border.Background>
<ImageBrush ImageSource="../Assets/control bg.png" Stretch="Fill" />
</Border.Background>
<Grid Margin="10,10,10,0">
<Grid.Background>
<ImageBrush />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock TextWrapping="Wrap" Text="Owner Information" Margin="5,0,0,0" FontSize="21.333" Foreground="#FF2B2B2B" FontFamily="Verdana"/>
</Border>
<Grid Margin="10,10,5,5" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
The grid does contain some controls which I have left out. They are just textboxes and combos.
Snowbear is right your XAML would be very helpful but here are some things to start off with:
By default, rows and columns in Grids take up the least amount of space necessary to accommodate the largest content within any cell contained in a given row or column. For example, if a column has one cell with a long word like "hippopotamus" contained within it but all the other cells in the column have smaller words like "dog", the width of the column will be the width of the largest word (hippopotamus). "http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.aspx"
So, if your border doesn't have an explicit height and width assigned to it then it will exist just around the content you provided in the column. Binding to a set value would work as well.
<Grid Height="50" Width="50">

WPF Grid layout

Is it possible to design something like this using Grid in WPF? Design columns is easy, but what about rows? Or is there any better solution, like another container? Imagine each rectangle as module (GroupBox).
Make an outer Grid with two columns. Within this grid, place two other grids, one per column. This will lead to the desired layout.
Here an example of how to do. Please note that I have placed some stars for the heights. Change them accordingly to your needs.
<Grid>
<Grid.ColumnDefinitions>
<Grid.ColumnDefinition Width="*" />
<Grid.ColumnDefinition Width="*" />
<Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Here content elements of the first column -->
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Here content elements of the second column -->
</Grid>
</Grid>
Define your columns and rows.
Put each Groupbox on the desired row and column, and set its rowspan in order to define on how many rows it stretches.

Resources