I have a structure of items like this for example:
<FixedDocument Grid.IsSharedSizeScope="True">
<PageContent>
<FixedPage>
<Grid Width="500" Height="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" SharedSizeGroup="A"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</FixedPage>
</PageContent>
<PageContent>
<FixedPage>
<Grid Width="500" Height="200">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</FixedPage>
</PageContent>
</FixedDocument>
Why doesn't width of first column of grids have a same value on different fixed pages?
Related
This question already has answers here:
Sharing Column Widths Between Multiple WPF Controls
(3 answers)
Closed 3 years ago.
In my WPF app I have 2 grids inside a parent grid:
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="col1 width"/>
<ColumnDefinition Width="col2 width"/>
<Grid.ColumnDefinitions>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="col1"/>
<ColumnDefinition Width="Auto" x:Name="col2"/>
<Grid.ColumnDefinitions>
</Grid>
</Grid>
How can I bind the width of the column definitions in the first grid to the other grid?
You can do this
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=col1, Path=Width}"/>
<ColumnDefinition Width="{Binding ElementName=col2, Path=Width}"/>
<Grid.ColumnDefinitions>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="col1"/>
<ColumnDefinition Width="Auto" x:Name="col2"/>
<Grid.ColumnDefinitions>
</Grid>
</Grid>
I tested the below code and it works well.
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=col1, Path=ActualWidth}"/>
<ColumnDefinition Width="{Binding ElementName=col2, Path=ActualWidth}"/>
</Grid.ColumnDefinitions>
</Grid>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" x:Name="col1"/>
<ColumnDefinition Width="150" x:Name="col2"/>
</Grid.ColumnDefinitions>
</Grid>
This question already has answers here:
How to create reusable WPF grid layout
(6 answers)
Closed 3 years ago.
In my application I have a lot of grids like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- ... -->
</Grid>
They have 4 columns and 3 rows and column widths are set to some value.
Can I create style or some other kind of template to simplify my window that uses 20 grids like this?
I know, that I can create styles for column definitions one by one to avoid Width="10" everywhere, but is it possible to do something like this?
<Grid Style="{StaticResource GridWith4ColumnsAnd3Rows}">
<!-- ... -->
</Grid>
You can't set the RowDefinitions or ColumnDefinitions properties in a Style because they are not dependency properties.
But you could create a custom class that inherits from Grid and adds the ColumnDefinitions and RowDefinition in the constructor:
public class CustomGrid : Grid
{
public CustomGrid()
{
ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(10) });
//...
ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
}
}
Usage:
<local:CustomGrid>...</local:CustomGrid>
Alternatively, you could define an attached behaviour that creates the RowDefinitions and ColumnDefinitions.
Nice answer is here:
How to create reusable WPF grid layout
I have used <ItemsPanel> control with Grid inside.
Style (in my App.xaml):
<Style x:Key="SchedulerFieldGridStyle1" TargetType="ItemsControl" >
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid Background="LightSteelBlue" Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
Part of MainWindow.xaml before:
<Grid Background="LightSteelBlue" Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.ColumnSpan="4" Content="Day of week"/>
<Label Grid.Column="0" Grid.Row="1" Content="From"/>
<ComboBox Grid.Column="1" Grid.Row="1" />
<Label Grid.Column="2" Grid.Row="1" Content="To"/>
<ComboBox Grid.Column="3" Grid.Row="1" />
</Grid>
Part of MainWindow.xaml after:
<ItemsControl Style="{StaticResource SchedulerFieldGridStyle1}">
<Label Grid.ColumnSpan="4" Content="Day of week"/>
<Label Grid.Column="0" Grid.Row="1" Content="From"/>
<ComboBox Grid.Column="1" Grid.Row="1"/>
<Label Grid.Column="2" Grid.Row="1" Content="To"/>
<ComboBox Grid.Column="3" Grid.Row="1"/>
</ItemsControl>
When I run the project and maximize the window, the design layout covers on the top left portion of the window. How can I fill the entire window with the layout on maximization?
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="50"/>
<RowDefinition Height="320"/>
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="290" />
</Grid.ColumnDefinitions>
<Menu Background="#FFDED9D9" Grid.Row="0" Grid.ColumnSpan="8" />
<Menu Background="#FFDED9D9" Grid.Row="1" Grid.ColumnSpan="8" />
<DataGrid Grid.Row="2" Grid.ColumnSpan="8" />
<StatusBar Grid.Row="3" Background="#FFDED9D9" Grid.ColumnSpan="8" Margin="0,0,0,30" />
</Grid>
Instead of setting Height and Width of all Rows and Columns of LayoutGrid, set Height and Width of any one Column and Row as *
Here, for example your DataGrid row can have Height as * <RowDefinition Height="*"/>. Similarly last ColumnDefinition can be <ColumnDefinition Width="*" />
I have a WPF Grid with two rows.
First row contains 4 columns and each column contains a Button.
Second row contains user control with colspan of 3.
The custom control contains another Grid with two columns.
I would like to set the width of the first column in UserControl's grid to the width of the second column in the MainWindow's grid.
In the example below "nested column 0"'s width should be the same as "Column 1"'s width.
I tried with ElementName but it did not work out.
Any ideas how to do it?
<Window x:Class="TestElementName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:trace="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:local="clr-namespace:TestElementName"
Title="MainWindow" Height="200" Width="600">
<Grid Tag="YeahGrid" Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" Tag="Hallelujah" x:Name="ColDef2"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0">Column 0</Button>
<Button Grid.Column="1" Grid.Row="0" MinWidth="180">Column 1</Button>
<Button Grid.Column="2" Grid.Row="0" MinWidth="115">Column 2</Button>
<Button Grid.Column="3" Grid.Row="0">Column 3</Button>
<local:ucButton Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" BorderBrush="Red" BorderThickness="1" />
</Grid>
</Window>
User control is as follows:
<UserControl x:Class="TestElementName.ucButton"
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"
xmlns:trace="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">nested column 0</Button>
<Button Grid.Column="1">nested column 1</Button>
</Grid>
</UserControl>
Thank you!
You can do this using a SharedSizeGroup. This allows you to link the width of designated columns in multiple Grids. (It also works for row height!)
First you need to define a SharedSizeScope on a control that encompasses all of the columns that will share widths. You can use your YeahGrid for this:
<Grid Tag="YeahGrid" Name="grid" Grid.IsSharedSizeScope="True">
Then set the SharedSizeGroup property on the columns you want to align. In the Window:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" Tag="Hallelujah" x:Name="ColDef2" SharedSizeGroup="HallelujahSSG" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
And in the UserControl:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="HallelujahSSG"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
Now the widths of all Grid columns with the same SharedSizeGroup name are linked, effectively bound to the width of the column that requires the most space (in this case Column 1 in YeahGrid).
In your UserControl Xaml, you mentioned both ColumnDefinition width = "Auto". On that place please add the MinWidth attribute as per your requirements.
For your scenario you can add ---
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="180"/>
<ColumnDefinition Width="Auto" MinWidth="115"/>
</Grid.ColumnDefinitions>
Because you are using in mainwindow like this
<Button Grid.Column="1" Grid.Row="0" MinWidth="180">Column 1</Button>
<Button Grid.Column="2" Grid.Row="0" MinWidth="115">Column 2</Button>
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>