Grid RowDefinintion fixed Height ignored - wpf

I have a simple Grid with two rows, the first having a fixed height. Inside, I have an element with RowSpan="2", and on top another element which should reside only in the first row:
<Grid Background="Lime">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.RowSpan="2" Height="50" Fill="Blue"/>
<TextBlock Grid.Row="0" Text="Foo" VerticalAlignment="Center" Background="Red"/>
</Grid>
However, the actualheigth of the first row simply ignores the Height setting, beeing much larger than expected.
Is this a bug in the Grid? How can I workaround this?

I think you want something like this:
<Grid Background="Lime">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.RowSpan="2" Height="50" VerticalAlignment="Center" Fill="Blue"/>
<TextBlock Grid.Row="0" Text="Foo" VerticalAlignment="Center" Background="Red"/>
</Grid>
I'm not sure if having a RowSpan that covers a RowDefinition with Height="*" would work out.

i also tried this a few times, but it won't work. I think it's by design. Can't you just put the rectangle as a parent of the grid in the xaml?

It does not seem to work this way
Instead, I simply used the VerticalAlignment property to move the TextBlock to the top, and completely removed the RowDefinitions:
<Grid Background="Lime">
<Rectangle Height="50" Fill="Blue"/>
<TextBlock Grid.Row="0" Text="Foo" VerticalAlignment="Top" Background="Red" Height="20"/>
</Grid>

In this case you must use VerticalAlignment to stretch in order to fill your RowDefinition's Height.
<Grid Background="Lime">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.RowSpan="2" Height="50" Fill="Blue"/>
<TextBlock Name="texto" Grid.Row="0" Text="Foo" VerticalAlignment="Stretch" Background="Red"/>
</Grid>
On this way you will see your TextBox stretched to the Row height.

Related

WPF GridSplitter with multiple siblings not doen't work as expected

I searched around and didn't find similar question on the forum. I have the following WPF code.
<Window x:Class="WpfApp5.MainWindow"
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:local="clr-namespace:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="238.788" Width="406.407">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox TextWrapping="Wrap" Text="TextBox1 should be resized while moving the GridSplitter"/>
<GridSplitter HorizontalAlignment="Stretch" Height="5" Grid.Row="1" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Background="Black">
<TextBlock Padding="5" Text="I want this black section have fixed height while moving the GridSplitter" Foreground="Aqua" VerticalAlignment="Center" />
</StackPanel>
<TextBox Grid.Row="3" TextWrapping="Wrap" Text="TextBox2 should be resized while moving the GridSplitter"/>
</Grid>
</Window>
When the user drags the grid splitter, only the two textbox should be resized. But what I got is like this:
How can I fix this?
Move the StackPanel and the second TextBox into a single Panel:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox TextWrapping="Wrap" Text="TextBox1 should be resized while moving the GridSplitter"/>
<GridSplitter HorizontalAlignment="Stretch" Height="5" Grid.Row="1" />
<DockPanel Grid.Row="2">
<StackPanel Orientation="Horizontal" Background="Black" DockPanel.Dock="Top">
<TextBlock Padding="5" Text="I want this black section have fixed height while moving the GridSplitter" Foreground="Aqua" VerticalAlignment="Center" />
</StackPanel>
<TextBox TextWrapping="Wrap" Text="TextBox2 should be resized while moving the GridSplitter"/>
</DockPanel>
</Grid>
It's easy, set VerticalAlignment="Center" by the ´StackPanel´
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox TextWrapping="Wrap" Text="TextBox1 should be resized while moving the GridSplitter"/>
<GridSplitter HorizontalAlignment="Stretch" Height="5" Grid.Row="1" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Background="Black" VerticalAlignment="Center">
<TextBlock Padding="5" Text="I want this black section have fixed height while moving the GridSplitter" Foreground="Aqua" VerticalAlignment="Center" />
</StackPanel>
<TextBox Grid.Row="3" TextWrapping="Wrap" Text="TextBox2 should be resized while moving the GridSplitter"/>
</Grid>
I found that the problem is not because GridSplitter can only split two before and after siblings, it's the wrong RowDefinition! In the code snippet of the question, the first and forth RowDefinition are set to Height="*", which force them to split the additional space evenly. That's why when you drag the splitter and the first and forth row always keep the same height. If I change them according to the following setting, it just works as expected.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="5" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox TextWrapping="Wrap" Text="TextBox1 should be resized while moving the GridSplitter" />
<GridSplitter HorizontalAlignment="Stretch" Height="5" Grid.Row="1" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Background="Black">
<TextBlock Padding="5" Text="I want this black section have fixed height while moving the GridSplitter"
Foreground="Aqua" VerticalAlignment="Center" />
</StackPanel>
<TextBox Grid.Row="3" TextWrapping="Wrap" Text="TextBox2 should be resized while moving the GridSplitter" />
</Grid>
So no need to nest any more.

TextBlock wrapping on Grid (UWP)

Have been making a bit of research on this but haven't been able to solve it:
I have a GridView, here is all the code for it:
<GridView Name="NewsGrid" IsItemClickEnabled="True" ItemClick="NewsGrid_ItemClick">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:News">
<Grid Height="Auto" Margin="0" Width="440">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Source="{x:Bind Image}"
HorizontalAlignment="Center"
Stretch="UniformToFill"
Margin="5"
Height="247"
Width="440"/>
<TextBlock Text="{x:Bind Body}"
Foreground="SteelBlue"
Grid.Row="1"
Height="Auto"
HorizontalAlignment="Stretch"
Width="440"
Margin="5 0 5 0"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
What I am trying to accomplish is for the TextBlock to wrap if the length of the text goes over 440 pixels. The code above does not accomplish that. To give you some visuals, here is the result from the code above:
So that last word is "Pass" and ask you can see it just keeps going. I just want it to break into a new line underneath. How can I achieve this? I have also tried to swap my Grid for a StackPanel but the result is the same.
Update 1
Added TextWrapping="Wrap" to my TextBlock, visual result is this:
The last word doesn't show up anymore, not even in the same line.
Add TextWrapping="Wrap" to your TextBlock.
Also!
For the definitions of rows this has to happen:
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

How to make GridView wrap its contents in XAML?

As the title of the post, I want to make a GridView which can wrap all of it's contents inside, it means if I have 3 items, each of them has 50px of height, so how to make a GridView contains these item that has 50*3=150px of height.
How to do that, please help me!
P/s: I want to do it by configuring XAML code, not in C# code, thanks!
I found out the answer! Just set the height of the GridView to Auto by make it inside a Grid row.
<Grid Grid.Row="0"
Margin="12,24">
<Grid.RowDefinitions>
<RowDefinition Height="64" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Opacity=".8"
Background="White"
Height="64">
<Grid Margin="8">
<TextBlock Text="Students"
VerticalAlignment="Center"
FontSize="24" />
</Grid>
<Grid Height="2"
VerticalAlignment="Bottom"
Background="#B0BEC5" />
</Grid>
<GridView Background="White"
Name="grvMatchGA"
Grid.Row="1"
ItemTemplate="{ThemeResource groupItemTemplate}"
Opacity=".8"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
VerticalAlignment="Stretch">
</GridView>
</Grid>
If you don't provide height for gridview but it's children, it automatically takes the height equivalent to sum of children's height.
For example, you can do something like this-
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"/>
<TextBox Grid.Row="1"/>
<Button Grid.Row="2"/>
</Grid>

WPF: Inner content wont scroll

I have a Window with a Grid inside:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<DockPanel Grid.Row="1" Visibility="{Binding SearchResultViewVisibility}">
<GridSplitter DockPanel.Dock="Top" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False"/>
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
<UserControls:GradientBackgroundControl Grid.Row="2" Height="25">
<Validators:FocusSummaryControl x:Name="FocusSummary" ValidateOnlyFocusedElement="False" />
</UserControls:GradientBackgroundControl>
</Grid>
The ContentControl gets a UserControl with this Grid set:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="0" Grid.ColumnSpan="4">
<StackPanel>
...
</StackPanel>
</ScrollViewer>
The problem now is, that the ScrollViewer in the UserControl doesn't scroll. The content of the UserControl set to the ContentControl is heigher and the overflow ist just hidden.
If I am not wrong, StackPanel requires a Height to be set for scroll functionality to work because StackPanel, by design, grows in one direction (based on Orientation).
To confirm whether this is the cause of your problem, please test by setting the height of StackPanel to a fixed height. Alternately, you may want to replace the StackPanel with say DockPanel and see the behaviour. Also there is a ScrollViewer.CanContentScroll property that you may want to fiddle with.
Let us know the result of this test.
I think you need to rearrange things a little bit. My suggestions (I'm sure there are infinite variations that would work):
First, add a new row to your grid (Height="Auto") and set the height of your top row (with your ContentControl in it) to "*"
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="70" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
Second, move your GridSplitter out of the DockPanel. Put the splitter in row 1 and the dockpanel in row 2.
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<GridSplitter Grid.Row="1" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False" ResizeBehavior="PreviousAndNext"/>
<DockPanel Grid.Row="2" Visibility="{Binding SearchResultViewVisibility}">
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
Note that you'll probably also have to set the ResizeBehavior for your GridSplitter as shown above. I hope this will get you close to what you want.

Resizing another grid row size in WPF

I am wondering is there any way to solve this by changing XAML code?
Please look at this sample picture:
What I wants to do is when user dragging GridSeparater No.1, I want to resize thr 3rd row of grid.
This is because in this application, the first and third rows are variable size, but second one is fixed size.
Is that possible?
This is possible with ResizeBehaviour="PreviousAndNext" (Link to MSDN). This enables you to specify which rows should be affected relative to the GridSplitter.
<Grid Width="300" Height="200" Background="Yellow" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Row="1"
ResizeDirection="Rows"
ResizeBehavior="PreviousAndNext"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="Black"
ShowsPreview="True"
Height="5"
/>
</Grid>
You could try setting both MinHeight and MaxHeight to the same value on the center row which would force recalculation of the bottom section when resizing the top. Something like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50" MaxHeight="50" MinHeight="50"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
... other content
<GridSplitter Height="3" Grid.Row="1" HorizontalAlignment="Stretch"/>
<GridSplitter Height="3" Grid.Row="3" HorizontalAlignment="Stretch"/>
</Grid>

Resources