Resizing WPF Prism Regions - wpf

In a WPF Prism app, I have two separate views in two separate regions, say LeftRegion and RightRegion. I would like to be able to drag the edge of LeftRegion (ie. the view in LeftRegion) like a gridsplitter works. Any ideas on how to accomplish this? Thank you.
EDIT: Here is the ShellView.xaml called by bootstrapper.cs that defines the regions.
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height ="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="215"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column ="0" Height ="500" prism:RegionManager.RegionName="LeftRegion" />
<GridSplitter Grid.Column ="0" Width="5" HorizontalAlignment="Right" VerticalAlignment="Stretch" ResizeBehavior="CurrentAndNext"/>
<ContentControl Grid.Column="1" Height ="400" prism:RegionManager.RegionName="RightRegion" />
</Grid>

Since Prism regions are nothing but UIElements, typically ContentPresenters, you should be able to use a GridSplitter as usual:
<Window x:Class="WpfApp1.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:WpfApp2"
prism:RegionManager.RegionName="LeftRegion"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl prism:RegionManager.RegionName="LeftRegion" />
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<ContentControl Grid.Column="2" prism:RegionManager.RegionName="RightRegion" />
</Grid>
</Window>

Related

Toolbar isn't showing overflow when hosted in UserControl

Hosted in a Window, I have a main UserControl composed of other UserControls.
One of these contains a ToolBar with a few Buttons on it. I place this at the top of my main UserControl by setting it's Grid.Row property to 0. However, when making the Window smaller, the Buttons just disappear and no overflow is shown. I've messed with the overflow properties a bit but no luck.
Here's the UserControl containing the ToolBar.
<UserControl x:Class="TestProj.Views.ToolBarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="706"/>
<ColumnDefinition Width="319"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
<Button Content="Button4" />
<Button Content="Button5" />
<Button Content="Button6" />
</ToolBar>
</Grid>
</UserControl>
Here's my main UserControl which is hosted inside of a Window, and hosts the ToolBar UserControl:
<UserControl x:Class="TestProj.MainControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-TestProj.Views"
mc:Ignorable="d" d:DesignHeight="737.239" d:DesignWidth="1026"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="430*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto">
</RowDefinition>
<RowDefinition Height="608*"/>
<RowDefinition Height="Auto">
</RowDefinition>
</Grid.RowDefinitions>
<views:ToolBarView HorizontalAlignment="Left" x:Name="OnyxToolBar" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" />
</Grid>
</UserControl>
And here's an example .gif of me resizing the Window, just the top where the UserControl containing the ToolBar is:
The problem is your fixed sized columns in your UserControl aka ToolBarView
you can not give to some control (does not matter if it is a ToolBar or not) a fixed size value and expect to have "dynamic size"
in your situation you could do something like this
change this
<Grid.ColumnDefinitions>
<ColumnDefinition Width="706"/>
<ColumnDefinition Width="319"/>
</Grid.ColumnDefinitions>
to this (for example)
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

Why I can't resize the last Column width by GridSplitter?

Here is the XAML:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Background="Red"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5"></GridSplitter>
<Border Background="Green" Grid.Column="1"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5" Grid.Column="1"></GridSplitter>
<Border Background="Blue" Grid.Column="2"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5" Grid.Column="2"></GridSplitter>
</Grid>
</Window>
And I found that I can't resize the last Column width by the last GridSplitter.
In addition, all the other GridSplitter are working well.
Why it turns out to be this? And how can I solve this?
Thank you.
Try adding this to your Grid's RowDefinition as below (add an extra column with * as width to occupy remaining space).
<ColumnDefinition Width="*"></ColumnDefinition>
This is how your final Xaml looks like (only the content portion)
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Background="Red"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5"></GridSplitter>
<Border Background="Green" Grid.Column="1"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5" Grid.Column="1"></GridSplitter>
<Border Background="Blue" Grid.Column="2"></Border>
<GridSplitter HorizontalContentAlignment="Stretch" Width="5" Grid.Column="2"></GridSplitter>
</Grid>
Try and let us know if this is what you are looking for or need some other kind of help.

Why does WrapPanel breaks Grid's ColumDefinitions?

This is a design I use often, a grid with columns of relative sizes (using the asterisk for width) so to mimic relative margins or other similar task.
An example of something similar to what I'm working on right now:
<Window x:Class="WpfApplication1.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:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="1234567890123456789012345678901234567890123456789012345678901234567890" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/>
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Text="AAA" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16" FontWeight="DemiBold"/>
</Grid>
</Grid>
</Window>
And this is its output
which is exactly what I expected.
But, if I just change the root Grid with a WrapPanel, like this:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<WrapPanel>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="1234567890123456789012345678901234567890123456789012345678901234567890" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/>
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Text="AAA" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16" FontWeight="DemiBold"/>
</Grid>
</WrapPanel>
</Window>
then I get this:
Ok, there is obviously some difference in placement due to the WrapPanel layout system, and this is ok to me and even expected, but...what the heck it's happening to the columns?
The relative size of the columns cannot be calculated unless the Grid actually has a Width. I am not sure why you want to use a WrapPanel here but you could specify a fixed Width or MinWidth of the Grid:
<WrapPanel>
<Grid x:Name="grid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="True"
Width="300">

WPF Alignment not working

I use the following code in my WPF app, for a groupbox:
<GroupBox Style="{StaticResource groupBoxStyle}" Header="RB" Margin="0,6,268,249" Name="groupBoxRB" HorizontalAlignment="Right" VerticalAlignment="Stretch" Width="276">
This control is within a grid, that is defined like this:
<TabControl Grid.Row="1" Margin="4,12,0,12" Name="tabControl1" Background="Transparent">
<TabItem Style="{StaticResource tabItemMainStyle}" Header="Main" Name="tabItemMain" >
<Grid Background="Transparent" MinHeight="926" MinWidth="1218">
And that tabcontrol is within the main grid:
<Window x:Class="SRM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:local="clr-namespace:SRM" ResizeMode="CanResize"
Title="SRM"
Width="991" Icon="Resources\Icons\SRM.png"
WindowStartupLocation="CenterScreen" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="1024" Height="774" Visibility="Visible" Foreground="#00000000" Margin="0">
<Grid Style="{StaticResource styleBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2.5" />
</Grid.ColumnDefinitions>
I don't understand why the groupbox i mentioned won't stretch on its vertical axis... any idea?
Thanks.
PS: the staticresources don't define heights/widths/alignments
My problem came from the designers (vs2010's or blend's) that by default put margins if you place controls manually in them... setting the Margin to 0 solved the problem:
<GroupBox Style="{StaticResource groupBoxStyle}" Header="RB" Margin="0" Name="groupBoxRB" HorizontalAlignment="Right" VerticalAlignment="Stretch" Width="276">
I think you're missing something in your styles or something. I just made the following from your code and stretching works fine in standalone app.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2.5" />
</Grid.ColumnDefinitions>
<TabControl Grid.Row="1" Margin="4,12,0,12" Name="tabControl1" Background="Transparent">
<TabItem Header="Main" Name="tabItemMain" >
<Grid Background="Transparent" MinHeight="200" MinWidth="200">
<GroupBox Header="RB" Name="groupBoxRB" HorizontalAlignment="Right" VerticalAlignment="Stretch" Width="276">
<Rectangle Fill="Orange" />
</GroupBox>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>

WPF: Is VerticalAlignment inherited by nested containers?

I'd like to have the nested containers inherit that property, but when I set it in the outermost one I'm not sure if it's working. It either is working but I'm not getting the results I want, or maybe I'd have to set up a property somewhere for it to carry.
Assuming that a) it is possible to do it and b) I'd have to change a property somewhere, would that have any side effects I should be aware of?
EDIT
Ok, here's an example:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Grid.Row="1" Grid.Column="1"></Slider>
<Button Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
What I would like to have, without having to do it manually:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label VerticalAlignment="Center" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox VerticalAlignment="Center" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button VerticalAlignment="Center" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label VerticalAlignment="Center" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider VerticalAlignment="Center" Grid.Row="1" Grid.Column="1"></Slider>
<Button VerticalAlignment="Center" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
Although I'm not really sure there was any difference here. It's not a deal breaker or anything, but I'd like to do it this way.
VisualTree inheritance is not universal. The dependency property specifies that it will inherit down the visual tree when it is declared. In this case, verticalalignment is not.
The only way to get a consistent vertical alignment is to use a style. And you can't use an implicit style across different types of controls. So you need to create a named style, place it in the resources of the container. Add a setter to the style to set the vertical alignment to whichever value you want. Finally reference the style in all the controls to which you want it applied.
Here is your example done with styles...unfortunately you're not saving much typing however if your style did something like Set VerticalAlignment and the FontFamily, then you're saving space...If you think of it like CSS then WPF Styles are easy.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="setVA" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Grid.Resources>
<Label Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="1"></Slider>
<Button Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
There's more information on using styles on MSDN

Resources