Multiple Parallel GridSplitter in WPF - wpf

I have divided my entire screen into 3 rows and 2 grid splitters. Currently, my middle row is changing its height when I move my first/second grid splitter.
Expected behaviour:
Basically, the middle row's height should remain the same but should only move as per the change in height of the top/bottom row.
If I move my first grid splitter then my other row should follow it. It means the middle row should move and the last row should increase in height. Similarly, if I move my second grid splitter then middle row should not change its height but should move. Whereas the first row should increase in height.
To understand better, please check my following code.
Can someone please help me, how can I achieve this.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
<RowDefinition Height="100"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="FirstRow">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="5"/>
<ColumnDefinition />
<ColumnDefinition Width="5"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TreeView Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" Background="Red"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent"/>
<TreeView Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" Background="Green"/>
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent" />
<TreeView Grid.Column="4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" Background="Blue"/>
</Grid>
<GridSplitter x:Name="gridSplitter1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Transparent" Height="5" />
<TextBlock x:Name="SecondRow" Grid.Row="2" Text="SecondRow" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"/>
<GridSplitter x:Name="gridSplitter2" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Transparent" Height="5" />
<DataGrid Grid.Row="4" x:Name="ThirdRow">
<DataGrid.Columns>
<DataGridTextColumn Header="Col A" />
<DataGridTextColumn Header="Col B" />
<DataGridTextColumn Header="Col C" />
</DataGrid.Columns>
</DataGrid>
</Grid>
<Button Grid.Row="1" HorizontalAlignment="Left" Content="Delete" Margin="10"/>
<Button Grid.Row="1" HorizontalAlignment="Right" Content="Close" Margin="10"/>
</Grid>

Related

Can we use multi xaml layout on a window?

I think that we can use multi layout on a windows with XAML.
So I try to create a window like this:
I want to create an ListView in left and it can be resized. The Grid and Textbox at the left side will be fit to the right grid.
I have tried to use other layouts, StackPanel, DockPanel.
How can I create a resizable grid
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ToolBar Name="toolBar" Grid.Row="0">
<Button Name="btnLoad" Width="Auto" Height="25" ToolTip= Click="btnLoad_Click" VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/reload.png" Width="16" Height="16" HorizontalAlignment="Left" Margin="0 0 5 0"/>
<TextBlock>Load/Reload</TextBlock>
</StackPanel>
</Button>
<Button Name="btnSave" Width="Auto" Height="25" Click="btnSave_Click">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/save.png" Width="16" Height="16" HorizontalAlignment="Left" Margin="0 0 5 0"/>
<TextBlock>Save</TextBlock>
</StackPanel>
</Button>
</ToolBar>
<ComboBox Name="cbTypeOfShop" Grid.Row="1" Margin="5 5 5 5"/>
<Grid Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<GridSplitter Grid.Column="1" Grid.RowSpan="3" HorizontalAlignment="Left" VerticalAlignment="Stretch" Background="Black" ShowsPreview="true" Width="5"/>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid Name="dtgListItem" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</DataGrid>
<TextBox Grid.Row="1" Height="100" TextWrapping="Wrap" AcceptsReturn="True" Text="1231231231 22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221231231231231231123123123123123123123123123123123123123123123123123" />
</Grid>
</Grid>
<StatusBar Grid.Row="3" Height="25" HorizontalAlignment="Stretch">
<TextBlock Name="abc">abc</TextBlock>
</StatusBar>
</Grid>
But when I resize the left side.
try this
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Left side</TextBlock>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<TextBlock Grid.Column="2" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Right side</TextBlock>
</Grid>
As you can see, I've simply created a Grid with two equally wide columns, with a 5 pixel column in the middle.

wpf can't find control coordinates info

I have a Group Box that contain a Stack Panel that contains a Combo Box (A) and a Text Box. And I have another Stack Panel (B) that contains a combo Box and a Label.
I would place the Combo Box B on the same level as Combo Box A (same y) using xaml code.
Please note that the GroupBox and and the Stack Panel(B) are placed in a grid in the same row, different columns.
I'm trying to bind the y coordinate of the Combo Box (B) to the y coordinate of the Combo Box (A).
Where I can find the coordinates info of wpf controls in the Visual Studio properties window ?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GroupBox Name="AGroupBox" Grid.Row="1" Grid.Column="0" >
<GroupBox.Header>
<Label Content="GroupBox" FontWeight="Bold" />
</GroupBox.Header>
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal">
<ComboBox x:Name="ComboBoxA" Width="100" Height="25" VerticalAlignment="Center"/>
<TextBlock x:Name="TextBlockA" Width="150" VerticalAlignment="Center" Margin="10,0,0,0" Text="This a Test" />
</StackPanel>
</GroupBox>
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left">
<Label x:Name="LabelB" Content="LabelB" />
<ComboBox x:Name="ComboBoxB" Width="150" Height="25"/>
</StackPanel>
</Grid>
a close equivalent of using y-coordinate would be using Margin property ... but it is going to break after the first resize attempt.
i think, it is possible to update Margin on resizes, but i would start with a more complex layout, like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--additional Grid used to position comboBoxes on the same height-->
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!--group box is used as cover for the 1st column-->
<GroupBox Name="AGroupBox"
Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" >
<GroupBox.Header>
<Label Content="GroupBox" FontWeight="Bold" />
</GroupBox.Header>
</GroupBox>
<!--stack panel with ComboBoxA is centered vertically in the 1st column-->
<StackPanel Grid.Row="1" Grid.Column="0"
Margin="5,0"
Orientation="Horizontal">
<ComboBox x:Name="ComboBoxA" Width="100" Height="25" VerticalAlignment="Center"/>
<TextBlock x:Name="TextBlockA" Width="150" VerticalAlignment="Center" Margin="10,0,0,0" Text="This a Test" />
</StackPanel>
<!--ComboBoxB is centered vertically in the 2nd column-->
<ComboBox x:Name="ComboBoxB"
Grid.Row="1" Grid.Column="1"
VerticalAlignment="Top" HorizontalAlignment="Left"
Width="150" Height="25"/>
<!--Label attached on top of ComboBoxB-->
<Label x:Name="LabelB" Content="LabelB"
Grid.Row="0" Grid.Column="1" VerticalAlignment="Bottom"/>
</Grid>
</Grid>

Inner grid present in listview item is not stretching

In my List view I use a grid to arrange the controls of list view item
here is the code
<ListView.ItemTemplate>
<DataTemplate>
<Border>
<!--<Label Width="Auto" HorizontalAlignment="Stretch" Height="3" Background="LightGray"></Label>-->
<Grid HorizontalAlignment="Stretch" MinWidth="220" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65*"/>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontWeight="Bold" Text="{Binding Path=Name}"/>
<TextBlock Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" Text="{Binding PlanDate.DateValue,StringFormat=d}"></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Text="{Binding Owner}"></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right" Text="{Binding ForecastDate.DateValue,StringFormat=d}"></TextBlock>
</Grid>
<!--<Label Width="Auto" HorizontalAlignment="Stretch" Height="3" Background="LightGray"></Label>-->
</Border>
</DataTemplate>
</ListView.ItemTemplate>
Here the text blocks in grid coloumn 2 horizontal alignment is set to right .. still the texblocks are not been placed at the right . Am i doing some mistake here? Please advise
Try adding HorizontalContentAlignment="Stretch" to your ListView (the default value is Left and that's why you see it's not stretched).
You can remove HorizontalAlignment="Stretch" MinWidth="220" in your inner Grid.

Last Grid Column Not Auto Resizing With Grid

I'm having a problem with my TextBoxs not "Auto" resizing. I'm trying to create a form that behaves and looks like the Properties Editor in Visual Studio. What appears to be happening is that the third column is not expanding to fill all of the available remaining space in the grid. Image below is how my form looks on startup.
The width of the textboxs is determined by the MinWidth setting on the third ColumnDefinition statement. Also, the Width is set to "*". With any other setting, the resizing done with the GridSplitter doesn't work correctly.
<StackPanel Orientation="Vertical" VerticalAlignment="Top" x:Name="Stacker" Grid.IsSharedSizeScope="True">
<Expander x:Name="Expand" IsExpanded="True" Header="This is a test of a Second Panel" Width="{Binding Width, ElementName=Stacker}">
<Grid x:Name="EditGrid1" Margin="3" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="50" SharedSizeGroup="SharedSize1" />
<ColumnDefinition Width="Auto" SharedSizeGroup="SharedSize2" />
<ColumnDefinition Width="*" MinWidth="50" x:Name="ValueCol" />
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" x:Name="ToolBoxSplitter1" Grid.Row="1" Grid.RowSpan="6" Panel.ZIndex="1" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Width="3"/>
<TextBlock MaxHeight="40" Grid.Column="0" Grid.Row="1" Text="{x:Static lex:DoSomeThingView.Name}" />
<TextBlock MaxHeight="40" Grid.Column="0" Grid.Row="2" Text="{x:Static lex:DoSomeThingView.Address}" />
<TextBlock MaxHeight="40" Grid.Column="0" Grid.Row="3" Text="{x:Static lex:DoSomeThingView.Zip}" />
<TextBlock MaxHeight="40" Grid.Column="0" Grid.Row="4" Text="{x:Static lex:DoSomeThingView.NumberOfDoors}" TextTrimming="CharacterEllipsis" Grid.IsSharedSizeScope="True" />
<TextBlock MaxHeight="40" Grid.Column="0" Grid.Row="5" Text="{x:Static lex:DoSomeThingView.DoubleNumber}" />
<TextBox Grid.Column="2" Grid.Row="1" x:Name="UserName1" MaxHeight="50" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" SpellCheck.IsEnabled="True" />
<TextBox Grid.Column="2" Grid.Row="2" x:Name="Address1" />
<TextBox Grid.Column="2" Grid.Row="3" x:Name="Zip1" />
<TextBox Grid.Column="2" Grid.Row="4" x:Name="NumberOfDoors1" />
<TextBox Grid.Column="2" Grid.Row="5" x:Name="DoubleNumber1" />
</Grid>
</Expander>
</StackPanel>
Any suggestions on how to correct this?
Have a check once again of any style being set globally because your layout worked perfectly fine with me.
try overriding your textbox style by a local resource
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}"/>
</StackPanel.Resources>

Grid Splitter problem in WPF

I want a layout like VS 2008. In which I want two columns and second columns is again split into two.
I done that in the xaml mentioned below, but the GridSplitter is not visible vertically ( which split two columns).
I want both the GridSplitters to be resizable. One GridSplitter resizes the Left Hand Pane and Right Hand Pane and another GridSplitter resizes the subgrid's top pane and right pane..
The Second GridSplitter is working through this XAML but I am not able to produce XAML code that Splits the Right hand Pane and Left hand pane..
Pleas Help!!
<Window x:Class="AlarmUI_2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Background="Aqua" Grid.Column="0" >
<TextBlock FontSize="35" Foreground="#58290A"
TextWrapping="Wrap">Left Hand Side</TextBlock>
</StackPanel>
<GridSplitter Grid.Column="0" ResizeDirection="Auto"
Grid.RowSpan="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Background="Red">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
<GridSplitter Grid.Row="1" Height="5" Background="Gray"
VerticalAlignment="Top" HorizontalAlignment="Stretch" />
<ListBox Grid.Row="1" Background="Violet" Margin="0,5,0,0">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
</Grid>
</Grid>
</Window>
Change your vertical Splitter to
<GridSplitter Grid.Column="0" Width="5" ResizeDirection="Auto"
Grid.RowSpan="1"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"/>
This will be much better way to use GridSplitter
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Background="Aqua" Grid.Column="0" >
<TextBlock FontSize="35" Foreground="#58290A"
TextWrapping="Wrap">Left Hand Side</TextBlock>
</StackPanel>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="5" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Background="Red">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
<GridSplitter Grid.Row="1" Background="Gray" HorizontalAlignment="Stretch"/>
<ListBox Grid.Row="2" Background="Violet">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
</Grid>
</Grid>
The GridSplitters should probably be on their own row/column in the grid, not sharing a cell with the other controls.
Your gridsplitter is behind the other controls that's why you can't see it. You can either move it to the bottom in your XAML file (so it is added last) or use the Panel.ZIndex attached property. Additionally you have to set the width for the splitter correctly correctly:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Background="Aqua" Grid.Column="0" >
<TextBlock FontSize="35" Foreground="#58290A"
TextWrapping="Wrap">Left Hand Side</TextBlock>
</StackPanel>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Background="Red">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
<GridSplitter Grid.Row="1" Height="5" Background="Gray"
VerticalAlignment="Top" HorizontalAlignment="Stretch" />
<ListBox Grid.Row="1" Background="Violet" Margin="0,5,0,0">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
</Grid>
<GridSplitter Grid.Column="0" ResizeDirection="Columns"
Grid.RowSpan="1" Width="5"
HorizontalAlignment="Right"/>
</Grid>
I have acheived the functionality, the XAML is mentioned below:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Background="Aqua" Grid.Column="0" >
<TextBlock FontSize="35" Foreground="#58290A"
TextWrapping="Wrap">Left Hand Side</TextBlock>
</StackPanel>
<GridSplitter HorizontalAlignment="Right" ResizeDirection="Columns" Width="5" />
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Background="Red">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
<GridSplitter Grid.Row="1" Height="5" Background="Gray"
VerticalAlignment="Top" HorizontalAlignment="Stretch" />
<ListBox Grid.Row="1" Background="Violet" Margin="0,5,0,0">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>World</ListBoxItem>
</ListBox>
</Grid>
</Grid>

Resources