I want to have main window split in three parts like the one on the picture. there's supposed to be a line (red one) or left border of the rectangle number 2, that, when it's dragged with mouse, it resizes both rectangle 1 and 2. it's like the behaviour of playlist in windows media player. any ideas on how to obtain this? Also, it would be great if someone proposes a solution to how this playlist make collapsed if the red line is dragged to the right.
Define a <Grid> with columns and rows like so:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="600"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
...
and then the gridsplitter (still inside the grid):
<GridSplitter Grid.Row="0" Grid.Column="1" ResizeDirection="Columns" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
Note that the gridsplitter will need it's own column.
It is a GridSplitter, here is how to use one:
<GridSplitter Grid.Row="1"
Height="5"
Width="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Gray"
ResizeDirection="Rows" />
You need to assign a Row or Column to it from your Grid, and specify its ResizeDirection. This one is horizontal, but you get the idea for a vertical one.
HTH,
Bab.
Related
In WPF XAML I cannot seem to get the grid columns to take up the remaining space before a GridSplitter element. It's strange as the vertical one is working and seems to have the exact same set up. I have tried a number of things including using Width="*" and HorizontalAlignment="Stretch" on the column definitions and the left panel Grid itself, but nothing seems to allow it to stretch to the first GridSplitter.
Here is an example of what is happening when using the GridSplitter elements to manually resize:
And here is my XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="200"></ColumnDefinition>
<ColumnDefinition Width="4"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Left Panel -->
<Grid Grid.Column="0" Background="LightSlateGray">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="4"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<!-- Left Panel | Top -->
<Grid Grid.Row="0">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Padding="10 10 10 10">Test</TextBlock>
</Grid>
<!-- Left Panel Grid Splitter -->
<GridSplitter Grid.Row="1" Height="4" HorizontalAlignment="Stretch" Background="LightGray" ></GridSplitter>
<!-- Left Panel | Bottom -->
<Grid Grid.Row="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Test</TextBlock>
</Grid>
</Grid>
<!-- Horizontal Grid Splitter -->
<GridSplitter Grid.Column="1" Height="Auto" Width="4" VerticalAlignment="Stretch" Background="LightGray" ></GridSplitter>
<!-- Right Panel -->
<Grid Grid.Column="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Test</TextBlock>
</Grid>
</Grid>
All I really want is for the first Grid.Column that holds the left panel to resize itself and it's content to cover the remaining space between the left of the window, and the GridSplitter.
Any help would be really appreciated!
Thanks
Your "Horizontal Grid Splitter" needs HorizontalAlignment="Center". Actually any value other than Right - which appears to be the default for GridSplitter - works fine.
You would have the same issue in your inner (vertical) splitter if you set VerticalAlignment to Bottom, but this apparently is not the default value.
WPF layout never ceases to keep us on our toes.
I have a grid that has a header, content and a footer:
<Grid.RowDefinitions>
<RowDefinition Height="55"/> <!--HEADER-->
<RowDefinition Height="*"/> <!--CONTENT-->
<RowDefinition Height="55"/> <!--FOOTER-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.ColumnSpan="3"></Rectangle>
<ScrollViewer Grid.Row="1" Grid.Column="1" >
<Grid>
...
</Grid>
</ScrollViewer>
<Rectangle Grid.Row="3" Grid.ColumnSpan="3"></Rectangle>
</Grid>
I want to have it so that the header and footer are fixed and the content is scrollable. Within the second nested grid there is a lot of content, hence the scroll view. When I run the application, the scrollviewer still scrolls with the header and footer! I can't figure out what I'm doing wrong, is there a better layout I should be using?
Please let me know! I'd rather not use C#.
Thanks!
Unless you are doing something strange either around the XAML you have posted or inside the nested Grid object, your XAML works as you intended.
I very slightly modified your XAML, just to visibly show your header and footer, and to add some content to your inner grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="55"/><!--HEADER-->
<RowDefinition Height="*"/><!--CONTENT-->
<RowDefinition Height="55"/><!--FOOTER-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.ColumnSpan="3" Height="55" Fill="Red"/>
<ScrollViewer Grid.Row="1" Grid.Column="1" >
<Grid >
<ListBox ItemsSource="{Binding Path=myItems, FallbackValue='123456789abcdefghijklmno'}"/>
</Grid>
</ScrollViewer>
<Rectangle Grid.Row="3" Grid.ColumnSpan="3" Height="55" Fill="Blue"/>
</Grid>
Shown below is the result. Your ScrollViewer scrolls just fine while leaving the header and footer in place.
I'm not sure what else you have going on in your window, but this is the only XAML in the window I used for testing, and it works perfectly. As a note, I limited the height of the window to '400' so the inner grid did not continue to grow since it's height was set to *. You can achieve the same result by setting a maximum height on your outer Grid.
I am trying to get something like an image with adjustable margins done. The image itself is actually a path and resides in a StackPanel, stretching vertically. The StackPanel's width can be adjusted, and I want to keep the image's ratio and the ratio of path size to margin.
<StackPanel>
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="0.25*"/>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.25*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.25*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.25*"/>
</Grid.ColumnDefintions>
<Path Grid.Row="1"
Grid.Column="1"
Data="...blabla..."
Fill="#FF0072C6"
Stretch="UniformToFill"/>
</Grid>
</StackPanel>
Now, the problem is, even though the path object gets drawn in the grid, the first and third rows are always of zero height, instead of getting set based on the height of the 2nd row. I know this happens because the Grid resides in a StackPanel, which ignores automatic height settings and doesn't even let the Grid stretch vertically (or horizontally depending on orientation). It does work if I set a fixed height to the grid but that would ruin the aspect ratio of the image when resizing. How can I get this to work?
This is what I have:
This is what I want:
EDIT:
It seems there is confusion concerning my question. So to hopefully clarify, here's the desired result after resizing the StackPanel:
As you can see, the whole grid is supposed to resize like it was an actual image. The Grid should keep its aspect ratio. This is not about the Path inside the Grid.
If i have correctly understood the problem, a simple solution could be fixing sizes and using a viewbox:
<StackPanel>
<!--The other rows-->
<Viewbox>
<Grid Width="100" Height="100">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="50"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Path Grid.Row="1" Grid.Column="1" Data="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z" Fill="Blue" Stretch="Uniform" />
</Grid>
</Viewbox>
</StackPanel>
I have the following Grid with a TextBox in it:
<UserControl ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30px"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1px"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Grid.RowSpan="3" AcceptsReturn="True"
TextWrapping="Wrap" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<!-- content in other cells of the Grid's first column -->
</Grid>
</UserControl>
I want the TextBox to fill all space that is available on the control (width and height-wise) and should the user enter more text than fits into it I want its vertical scrollbar to become active, without resizing the TextBox. What happens instead is that the size of the TextBox changes to accomodate the content and the whole grid grows with it.
How do I achieve what I need?
Edit: Here's an illustration of what happens.
The above screenshot is of the situation when the content fits comfortably into the TextBox. The below screenshot is of the situation when there is not enough room to fit all content - the TextBox is then resized to fit it and this resizes also the grid that it is placed in, making it look broken.
Edit 2: The project that demonstrates this behavior is here.
I have managed to solve this by adding an invisible Border in the same cells of the Grid as the TextBox, then setting TextBox' Width and Height to ActualWidth and ActualHeight of that Border respectively:
<Border x:Name="b" Grid.Column="1" Grid.RowSpan="3"
HorizontalAlignment="Stretch"/>
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Grid.Column="1"
Grid.RowSpan="3" Width="{Binding ActualWidth, ElementName=b}"
Height="{Binding ActualHeight, ElementName=b}"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
This then caused the TextBox to stay of fixed Height regardless of its content, but there was another problem with its Width: it grew when the interface was expanded, but didn't shrink afterwards, because of the underlying ScrollViewer. The trick was to set that ScrollViewer's HorizontalScrollBarVisibility to Disabled, instead of Hidden as I had done previously.
I pushed changes of the example project to GitHub, so the solution is now available here.
The TextBox doesn't fill the Grid. You can confirm this yourself by specifying a Background for the Grid:
<UserControl>
<Grid Background="Yellow">
...
This is because the height of the Grid is 30 px + whatever the height of the TextBox is + 1 px. For the contents of the row 2 or 3 to fill the Grid, you need to change the Height of at least one of the RowDefinitions to *:
<UserControl>
<Grid Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="30px"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1px"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Grid.RowSpan="3" AcceptsReturn="True"
TextWrapping="Wrap" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</UserControl>
I have a WPF Line of business application. Most of it is hosted in user controls in tabs.
I'm having an issue finding out how to layout this so it would fit any resolution (with scrolling if necessary).
Here's the issue described in code because i really can't figure out how to put this to text, if it's not clear please let me know i'll try to draw something up.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition> <!--What i actually want to say here isn't "take all remaining space" but "take all remaining space without scrolling,
and then scroll based on everything as if this was auto and no longer *-->
<ColumnDefinition Width="Auto"></ColumnDefinition><!--But what happens for now is that since this is auto , it will not scroll at all untill the * column has fully scrolled-->
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label></Label>
<TextBox></TextBox>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1">
<StackPanel Orientation="Horizontal">
<button> <!-- I want the button's container to be in an auto column , don't
want it to take size away from the fields unless needed but don't
want it to stay visible at the expense of the fields either -->
</StackPanel>
</StackPanel>
<TelerikGrid:RadGridView Grid.Row="1" Grid.ColumnSpan="2">
<TelerikGrid:RadGridView.Columns>
<TelerikGrid:GridViewDataColumn Width="*"/> <!-- This makes my grid take a bajillon kilometers because it itself is in a Grid's column of * size itself in a scrollviewer -->
</TelerikGrid:RadGridView.Columns>
</TelerikGrid:RadGridView>
</Grid>
Hard to tell given I cannot load your GridView control in a Window.
I recommend nesting a layout manager Grid for your controls inside your Grid to create a separation between your controls and the GridView. You also should consider combining all the controls in one StackPanel or other layout manager.
Regardless, this layout gives you separation between the controls and the GridView regardless of your choice of layout manager with no need to specify a column span.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- Place a layout Grid inside your Grid to deal with controls -->
<Grid Grid.Column="0" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Removed your nested stack panel -->
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Horizontal">
<Label></Label>
<TextBox></TextBox>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal">
<Button />
</StackPanel>
</Grid>
<!-- Add a spilter bar here -->
<!-- No need to span 2 columns anymore... -->
<TelerikGrid:RadGridView Grid.Column="0" Grid.Row="1" >
<TelerikGrid:RadGridView.Columns>
<TelerikGrid:GridViewDataColumn Width="*"/>
</TelerikGrid:RadGridView.Columns>
</TelerikGrid:RadGridView>
<!-- Add a status bar here -->
</Grid>