I'm having a weird problem with Gridsplitters that I've been trying to solve all day, but neither the documentation nor Google has really been able to help me with this problem.
The issue is that I have a grid with multiple gridsplitters, where some of the rows have different height units. Three of the rows have concrete height values and one row have 1 star to let it "soak" up all the left over space.
Unfortunately this sets off some weird gridsplitter behavior. Basically, trying to set the height of GridRow 4 and 6 by manipulating the gridsplitter in Row 5, will not affect the height of row 6, the bottom row. Instead, it manipulates row 4 and row 2 and overlaps the gridsplitter in row 3.
Were I to set all the row heights to a specific pixel height, the gridsplitters all work fine, but this lets the Grid grow beyond the edge of the screen, which is not what is intended.
I've made a small sample project to illustrate the problem.
<Window x:Class="GridSplitterTest.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:GridSplitterTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" >TextBlock01</TextBlock>
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Black" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"></GridSplitter>
<TextBlock Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" >TextBlock02</TextBlock>
<GridSplitter Grid.Row="3" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Black" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"></GridSplitter>
<TextBlock Grid.Row="4" HorizontalAlignment="Center" VerticalAlignment="Center" >TextBlock03</TextBlock>
<GridSplitter Grid.Row="5" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Black" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"></GridSplitter>
<TextBlock Grid.Row="6" HorizontalAlignment="Center" VerticalAlignment="Center" >TextBlock04</TextBlock>
</Grid>
Anyone with a good idea of what is wrong and if there's any way to solve this?
I don't think anything is actually wrong here. You have all rows but one set to be fixed size. So adjusting any of the row heights only allows the grid to readjust that one row (row#2) to compensate because the other remaining rows (rows #0 & 6) are also a fixed size.
I think the only way to solve this would be to make all the textblock rows proportional. For example:
<Grid.RowDefinitions>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
Related
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.
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>
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.
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>
So, I just wanted to understand why this was happening in my WPF app as it seems to be adding a "space" or faint line without me wanting it...
I have the following XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication3.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="LayoutRoot" ShowGridLines="False" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" CornerRadius="10,10,0,0" Height="10" Background="Black"/>
<Border Grid.Row="1" Background="Black">
</Border>
<Border Grid.Row="2" CornerRadius="0,0,10,10" Height="10" Background="Black"/>
</Grid>
<StackPanel Grid.Row="1">
<Button>Some Button</Button>
</StackPanel>
</Grid>
Which renders the following window...
The problem is if you look closely at the last row connector you will see a faint gray line...
If however I replace the <RowDefinition Height="*"/> on the inner grid with a fix pixel size (i.e. <RowDefinition Height="300"/>) the line goes away. Why exactly when I am using the * value does it seem to be adding this "grey line" / "space"?
I think the problem is Anti-Aliasing
Your effect
SnapsToDevicePixels="True"
UseLayoutRounding="False"
RenderOptions.EdgeMode="Aliased"
It looks like layout rounding problem to me. If you are using WPF 4, try setting UseLayoutRounding="true" on your outer grid. Else, take a look at SnapToDevicePixels.
http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.uselayoutrounding.aspx
http://www.wpftutorial.net/DrawOnPhysicalDevicePixels.html