Programmatically setting the width of a grid column with * in WPF
I want to programmatically configure a wpf grid.
I want to be able to set a grid with 2 columns, the first taking up 20% of available space, the second taking up 80%. In xaml I would use the * operator but I cant work out how to do this programmatically.
In Xaml I would do:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition width="20*" />
<ColumnDefinition width="80*" />
</Grid>
In code I want to do:
Grid grid = new Grid();
grid.ColumnDefinitions.Add( new ColumnDefinition(20*) );
grid.ColumnDefinitions.Add( new ColumnDefinition(80*) );
Please could someone advise.
Grid grid = new Grid();
ColumnDefinition c1 = new ColumnDefinition();
c1.Width = new GridLength(20, GridUnitType.Star);
ColumnDefinition c2 = new ColumnDefinition();
c2.Width = new GridLength(80, GridUnitType.Star);
grid.ColumnDefinitions.Add(c1);
grid.ColumnDefinitions.Add(c2);
Suppose you have some buttons (aligned horizontally) in a page and need to hide / show certain ones depending on some status.
<Grid HorizontalAlignment="Center" Grid.Column="1" Width="340" VerticalAlignment="Center" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" x:Name="colOne"></ColumnDefinition>
<ColumnDefinition Width="0" x:Name="colTwo"></ColumnDefinition>
<ColumnDefinition Width="0" x:Name="colThree"></ColumnDefinition>
<ColumnDefinition Width="0" x:Name="colFour"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button x:Name="btnOne" Grid.Column="0" Height="50" Width="50" Content="One" Cursor="Hand" />
<Button x:Name="btnTwo" Grid.Column="1" Height="50" Width="50" Content="Two" Cursor="Hand" />
<Button x:Name="btnThree" Grid.Column="2" Height="50" Width="50" Content="Thre" Cursor="Hand" />
<Button x:Name="btnFour" Grid.Column="3" Height="50" Width="50" Content="Four" Cursor="Hand" />
</Grid>
Here btnOne will be visible in the page when executed. btnOne will also be aligned in the center. Now if we want Three and Four to be displayed and One to be hidden when clicked on One, we can use this code:
private void btnOne_Click(object sender, RoutedEventArgs e)
{
SetGridColWidth(colOne, false);
SetGridColWidth(colThree, true);
SetGridColWidth(colFour, true);
}
private void SetGridColWidth(ColumnDefinition column, bool show)
{
if (show)
column.Width = new GridLength(2, GridUnitType.Star);
else
column.Width = new GridLength(0);
}
You can toggle between visibility of any button at runtime.
Hope this helps someone!
MVVM Approach
View (XAML)
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding FirstColumn}"/>
<ColumnDefinition Width="{Binding SecondColumn}"/>
</Grid.ColumnDefinitions>
</Grid>
ViewModel (C#)
public class MyViewModel : BindableBase
{
private GridLength _firstColumn;
private GridLength _secondColumn;
public MyViewModel()
{
_firstColumn = new GridLength(75, GridUnitType.Star);
_secondColumn = new GridLength(25, GridUnitType.Star);
}
public GridLength FirstColumn
{
get { return _firstColumn; }
set { SetProperty(ref _firstColumn, value); }
}
public GridLength SecondColumn
{
get { return _secondColumn; }
set { SetProperty(ref _secondColumn, value); }
}
private void NotifyToggleFullScreen(bool isToggleExpansion)
{
if (isToggleExpansion)
{
FirstColumn = new GridLength(0, GridUnitType.Auto);
SecondColumn = new GridLength(100, GridUnitType.Star);
}
else
{
FirstColumn = new GridLength(75, GridUnitType.Star);
SecondColumn = new GridLength(25, GridUnitType.Star);
}
}
}
You can use auto:
var c1 = new ColumnDefinition() { Width = GridLength.Auto };