WPF How to access nested grid? - wpf

How to access a nested grid element with Grid.Column and Grid.Row? Normally, Grid.Column="1" Grid.Row="0" is the way to go. But I dont know how to access a nested one? for example: Column 0, Nested Column 3, Row 1.
I have added a picture of the layout structure:
Grid Layout
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top" Width="87" Height="23" Text="btn" BorderThickness="1,1,0,1" />
Nested grid:
<Grid x:Name="LayoutRoot" Background="#FFA3A3A3" Height="540" Width="952" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140*"/>
<ColumnDefinition Width="346*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="52*"/>
<RowDefinition Height="220.5*"/>
</Grid.RowDefinitions>
</Grid>
</Grid>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="120*"/>
<ColumnDefinition Width="146*"/>
<ColumnDefinition Width="146*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</Grid>
Some code...
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top" Width="87" Height="23" Text="btn" BorderThickness="1,1,0,1" />
</Grid>

you can/need not access a nested grid.
Grid.Column/Row always means the parent grid.
<Grid x:Name="Grid1">
<Grid x:Name="Grid2" Grid.Row="0", Grid.Columns="0">
<TextBlock Grid.Row="0", Grid.Columns="0"> TextBlock in Grid2[0,0]</TextBlock>
</Grid>
<TextBlock Grid.Row="1", Grid.Columns="0"> TextBlock in Grid1[1,0]</TextBlock>
</Grid>
The nested Grid2 is in [0,0] of Grid1

Related

WPF - Change Outer Control Opacity Will Not Change Inner Control Opacity

I have a border1 with full screen and it's Background is #011627. A Grid splits into four part, one of them have border2 and it's Background is #0b192a.
<Border x:Name="border1" Background="#011627"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Text="Test" Foreground="White" FontSize="30"/>
<Border x:Name="border2" Background="#0b192a"/>
</Grid>
Now I want to set Grid's Opacity to 0.1 and influence text's Opacity, and don't influence border2's Background.
But it doesn't meet my expectation.
<Border x:Name="border1" Background="#011627"/>
<Grid Opacity="0.1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Text="Test" Foreground="White" FontSize="30"/>
<Border x:Name="border2" Background="#0b192a"/>
</Grid>
Could it happen? Thanks!
UIElement.Opacity is by definition applied to all child elements of the (sub)tree, where the root is the element that defines the value.
If you want the to set Opacity exclusively to a specific element, you have to set it locally/by Style on this very element:
<Grid>
<TextBlock Opacity="0.1" Text="Test" />
<Border x:Name="border2" />
</Grid>

How to get half of the full window using grid.row in xaml?

I want to get a structure like this:
So i tried this:
<!-- Canvas -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<!--Toolbox & poperties -->
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Button Content="sdf"/>
</StackPanel>
<StackPanel Grid.Row="1">
<Button Content="sdf"/>
</StackPanel>
</Grid>
</Grid>
But I couldn't get the half of the height using grid. What else I could do?
You can try the following markup and use Grid.RowSpan to extend StackPanel into two rows
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0" Content="sdf"/>
<Button Grid.Column="0" Grid.Row="1" Content="sdf"/>
<StackPanel Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"/>
</Grid>

How to avoid WPF window reduces its dimension

I read a few post but I can't fix this problem.
I have a Grid defined as follow:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
...
Where in the first row I want a Border with a TextBlock inside. I need that the Border has always the same size without be influenced from the TextBlock.
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="{DynamicResource StandardBorderColor}" BorderThickness="2" Margin="15,10,15,10"
HorizontalAlignment="Stretch"/>
<TextBlock Grid.Row="0" Name="TextBlock" Margin="20, 15, 20, 20"
TextWrapping="Wrap" Foreground="{DynamicResource StandardForegroundColor}" FontSize="18" FontWeight="Bold"
VerticalAlignment="Center" TextAlignment="Left" Text="{Binding Testo}" HorizontalAlignment="Stretch"/>
</Grid>
Do you have any suggestions? Thanks in advance!
Update:
Solution:
I found this as solution:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GroupBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"
Margin="15, 10, 15, 10" Header="Avvisi">
<TextBox x:Name="TextBlock" FontSize="16"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
TextAlignment="Left" Text="{Binding Testo}" Style="{DynamicResource TxtBoxStyle}" ScrollViewer.VerticalScrollBarVisibility="Visible"
BorderBrush="Transparent" IsReadOnly="True" />
</GroupBox>
...

How to split a Grid row into two columns?

I have the Grid layout with 3 rows.How do i split the 3rd row into 2 columns.
<Grid.RowDefinitions>
<RowDefinition Height="0.75*"/>
<RowDefinition Height="0.25*"/>
<RowDefinition Height="36"/>
</Grid.RowDefinitions>
Two ways you can do it:
Use nested layouts. Put another Grid in the third row, and have two columns in that sub-grid.
<Grid>
<Grid.RowDefinitions> ... </Grid.RowDefinitions>
<ThingInFirstRow Grid.Row="0" />
<ThingInSecondRow Grid.Row="1" />
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ThingInLowerLeft Grid.Column="0" />
<ThingInLowerRight Grid.Column="0" />
</Grid>
</Grid>
Stick with one Grid, give it two columns, and make the things in the first two rows span across both columns using ColumnSpan.
<Grid>
<Grid.RowDefinitions> ... </Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ThingInFirstRow Grid.Row="0" Grid.ColumnSpan="2" />
<ThingInSecondRow Grid.Row="1" Grid.ColumnSpan="2" />
<ThingInLowerLeft Grid.Row="2" Grid.Column="0" />
<ThingInLowerRight Grid.Row="2" Grid.Column="1" />
</Grid>
<Grid>
<Grid.RowDefinitions >
<RowDefinition Height="0.75"/>
<RowDefinition Height="0.25"/>
<RowDefinition Height="36"/>
</Grid.RowDefinitions>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
</Grid>

Grid inside Grid in XAML

I want to have a childGrid in second column of parentGrid (in childGrid I want to have two columns: first for label, second for textbox)
How can I do Something like that? I tried the following code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Height="*"/>
<ColumnDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column=1>
<Grid.ColumnDefinitions>
<ColumnDefinition Height="*"/>
<ColumnDefinition Height="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</Grid>
</Grid>
Based on your code, just fixed up a little:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</Grid>
</Grid>
Note that ColumnDefinition don't have a Height - they have a Width. You also need to define the ColumnDefinitions and RowDefinitions separately - you have them mixed together in your outer grid. I removed the RowDefinitions from the outer grid because you don't appear to be using them. Your inner grid has two columns and four rows.
You might find this useful. Try pasting this into a page using Kaxaml and playing around with the various parameters of the objects in the outer Grid. I find using Kaxaml for prototyping and experimenting with XAML layouts indispensable.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!--
When I'm composing grids in XAML, I group things together by type, not by where
they live in the grid. This turns out to make a lot of maintenance tasks
easier.
Also, since Grid.Row and Grid.Column default to 0, a lot of people (and tools)
omit them if that's their value. Not me. It lets me quickly check to make
sure that content is where I think it is, just by looking at how it's organized
in the XAML.
-->
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="Lavender" Padding="10" HorizontalAlignment="Stretch">Here's the first row of the outer grid.</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Background="Lavender" Padding="10" HorizontalAlignment="Stretch">Here's the third row of the outer grid.</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" Background="AliceBlue" Padding="10">Here's the first column of the second row.</TextBlock>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.ColumnDefinitions>
<!--
This part's pretty important. Setting up the SharedSizeGroups for these
two columns keeps the labels and text boxes neatly arranged irrespective of
their length.
-->
<ColumnDefinition SharedSizeGroup="Label"/>
<ColumnDefinition SharedSizeGroup="TextBox"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0">First label</Label>
<Label Grid.Row="1" Grid.Column="0">Second label</Label>
<Label Grid.Row="2" Grid.Column="0">Third label, containing unusually long content</Label>
<TextBox Grid.Row="0" Grid.Column="1">First text box, containing unusually long content</TextBox>
<TextBox Grid.Row="1" Grid.Column="1">Second text box</TextBox>
<TextBox Grid.Row="2" Grid.Column="1">Third text box</TextBox>
</Grid>
</Grid>
It might come a little confusing how to put controls in sub grids. Here is an example.
We have 3 * 3 cell grid. And then center cell is further divided in 3 rows where each row has a button.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Button1"/>
<Button Grid.Row="1" Content="Button2"/>
<Button Grid.Row="2" Content="Button3"/>
</Grid>
</Grid>
Result:
Phenevo, I've done XAML UI design extensively this year. Try this out, you can easily migrate the code to either a Window or a UserControl. I color-coded the grids and panels so that you could affirm their layout in real time -- blow away the background parameters when you're satisfied.
<UserControl
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"
mc:Ignorable="d"
x:Class="UatControlLibrary.sampleChilGrid"
x:Name="UserControl"
MinWidth="400"
MinHeight="300"
Width="auto"
Height="auto">
<Grid
x:Name="LayoutRoot">
<Grid
x:Name="parentGrid"
Width="auto"
Height="auto"
Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="1*" />
<ColumnDefinition
Width="1*" />
</Grid.ColumnDefinitions>
<Grid
x:Name="chilGrid"
Width="auto"
Height="auto"
Background="Black"
Grid.Column="1"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="1*" />
<ColumnDefinition
Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel
x:Name="stkpnlLabels"
Background="White"
Grid.Column="0"
Grid.Row="0" />
<StackPanel
x:Name="stkpnlTextboxes"
Background="Blue"
Grid.Column="1"
Grid.Row="0" />
</Grid>
</Grid>
</Grid>
</UserControl>

Resources