I was playing with MAUI recently and one thing I really like is the shorthand for defining a grid's row and column definitions. For example, in WPF you see stuff like this.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="400"/>
</Grid.ColumnDefinitions>
</Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="400"/>
</Grid.ColumnDefinitions>
</Grid>
<Grid RowDefinitions="10,10,*,auto" ColumnDefinitions="*,2*,400">
</Grid>
</Grid>
Start a new Visual Studio .Net Framework project using C# and call it SimpleGridDemo.
Add a class called SimpleGrid. It inherits from Grid and overrides the RowDefinitions and ColumnDefinitions dependency properties. When these properties change, it regenerates the row or column definition collections in the base Grid class. It uses the GridLengthConverter class to parse the string grid lengths.
using System;
using
System.Collections.Generic;
using System.Linq;
using
System.Windows;
using
System.Windows.Controls;
namespace SimpleGrid
{
internal class SimpleGrid : Grid
{
private List<GridLength> RowList = new List<GridLength>();
private List<GridLength> ColumnList
= new List<GridLength>();
public static readonly DependencyProperty
RowDefinitionsProperty = DependencyProperty.Register(nameof(RowDefinitions), typeof(string), typeof(SimpleGrid),
new PropertyMetadata("", new
PropertyChangedCallback(OnRowsChanged)));
public new String
RowDefinitions
{
get { return (String)GetValue(RowDefinitionsProperty); }
set { SetValue(RowDefinitionsProperty, value); }
}
private static void OnRowsChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
SimpleGrid grid = (SimpleGrid)d;
grid.RowsChanged(e.NewValue.ToString(), e.OldValue.ToString());
}
private void
RowsChanged(String NewRows, string OldRows)
{
if (ParseDefinitions(NewRows, out RowList))
{
while (base.RowDefinitions.Count() > 0) { base.RowDefinitions.RemoveAt(0); }
foreach (GridLength gridLength in RowList)
base.RowDefinitions.Add(new RowDefinition() { Height =
gridLength });
}
}
public static readonly DependencyProperty
ColumnDefinitionsProperty =
DependencyProperty.Register(nameof(ColumnDefinitions), typeof(string), typeof(SimpleGrid),
new PropertyMetadata("", new
PropertyChangedCallback(OnColumnsChanged)));
public new String
ColumnDefinitions
{
get { return (String)GetValue(ColumnDefinitionsProperty); }
set { SetValue(ColumnDefinitionsProperty, value); }
}
private static void OnColumnsChanged(DependencyObject
d, DependencyPropertyChangedEventArgs e)
{
SimpleGrid grid = (SimpleGrid)d;
grid.ColumnsChanged(e.NewValue.ToString(), e.OldValue.ToString());
}
private void
ColumnsChanged(String NewColumns, string OldColumns)
{
if (ParseDefinitions(NewColumns, out ColumnList))
{
while (base.ColumnDefinitions.Count() > 0) { base.ColumnDefinitions.RemoveAt(0); }
foreach (GridLength gridLength in ColumnList)
base.ColumnDefinitions.Add(new ColumnDefinition() { Width =
gridLength });
}
}
private bool
ParseDefinitions(String Definition, out List<GridLength> gridLengths)
{
List<String> parts = Definition.Split(',').ToList();
GridLength gridLength;
gridLengths = new List<GridLength>();
foreach (String part in parts)
{
if (!ParseDefinition(part.Trim(), out gridLength)) return false;
gridLengths.Add(gridLength);
}
return true;
}
private bool
ParseDefinition(String part, out GridLength gridLength)
{
GridLengthConverter gridLengthConverter = new GridLengthConverter();
gridLength = new GridLength();
try
{
gridLength = (GridLength)gridLengthConverter.ConvertFromString(part);
return true;
}
catch { return false; }
}
}
}
internal class SimpleGrid : Grid
private List<GridLength> RowList = new List<GridLength>();
get { return (String)GetValue(RowDefinitionsProperty); }
SimpleGrid grid = (SimpleGrid)d;
grid.RowsChanged(e.NewValue.ToString(), e.OldValue.ToString());
}
if (ParseDefinitions(NewRows, out RowList))
while (base.RowDefinitions.Count() > 0) { base.RowDefinitions.RemoveAt(0); }
}
get { return (String)GetValue(ColumnDefinitionsProperty); }
SimpleGrid grid = (SimpleGrid)d;
grid.ColumnsChanged(e.NewValue.ToString(), e.OldValue.ToString());
}
if (ParseDefinitions(NewColumns, out ColumnList))
while (base.ColumnDefinitions.Count() > 0) { base.ColumnDefinitions.RemoveAt(0); }
}
List<String> parts = Definition.Split(',').ToList();
if (!ParseDefinition(part.Trim(), out gridLength)) return false;
}
return true;
GridLengthConverter gridLengthConverter = new GridLengthConverter();
{
gridLength = (GridLength)gridLengthConverter.ConvertFromString(part);
return true;
catch { return false; }
}
}
Change the MainWindow.xaml and MainWindow.xaml.cs classes to look like this
<Window x:Class="SimpleGridDemo.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:SimpleGrid"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<local:SimpleGrid RowDefinitions="10,10,*,auto" ColumnDefinitions="*,2*,400" MouseLeftButtonDown="Grid_Click">
<TextBlock Grid.Row="0" Grid.Column="0" Background="AliceBlue"/>
<TextBlock Grid.Row="0" Grid.Column="1" Background="Beige"/>
<TextBlock Grid.Row="0" Grid.Column="2" Background="CadetBlue"/>
<TextBlock Grid.Row="1" Grid.Column="0" Background="DarkBlue"/>
<TextBlock Grid.Row="1" Grid.Column="1" Background="Firebrick"/>
<TextBlock Grid.Row="1" Grid.Column="2" Background="Gainsboro"/>
<TextBlock Grid.Row="2" Grid.Column="0" Background="Honeydew"/>
<TextBlock Grid.Row="2" Grid.Column="1" Background="IndianRed"/>
<TextBlock Grid.Row="2" Grid.Column="2" Background="Khaki"/>
<TextBlock Grid.Row="3" Grid.Column="0" Background="Lavender"/>
<TextBlock Grid.Row="3" Grid.Column="1" Background="Magenta"/>
<TextBlock Grid.Row="3" Grid.Column="2" Background="NavajoWhite"/>
</local:SimpleGrid>
</Window>
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:SimpleGrid"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<local:SimpleGrid RowDefinitions="10,10,*,auto" ColumnDefinitions="*,2*,400" MouseLeftButtonDown="Grid_Click">
<TextBlock Grid.Row="0" Grid.Column="0" Background="AliceBlue"/>
<TextBlock Grid.Row="0" Grid.Column="1" Background="Beige"/>
<TextBlock Grid.Row="0" Grid.Column="2" Background="CadetBlue"/>
<TextBlock Grid.Row="1" Grid.Column="0" Background="DarkBlue"/>
<TextBlock Grid.Row="1" Grid.Column="1" Background="Firebrick"/>
<TextBlock Grid.Row="1" Grid.Column="2" Background="Gainsboro"/>
<TextBlock Grid.Row="2" Grid.Column="0" Background="Honeydew"/>
<TextBlock Grid.Row="2" Grid.Column="1" Background="IndianRed"/>
<TextBlock Grid.Row="2" Grid.Column="2" Background="Khaki"/>
<TextBlock Grid.Row="3" Grid.Column="0" Background="Lavender"/>
<TextBlock Grid.Row="3" Grid.Column="1" Background="Magenta"/>
<TextBlock Grid.Row="3" Grid.Column="2" Background="NavajoWhite"/>
</local:SimpleGrid>
</Window>
using
System.Windows;
namespace SimpleGridDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void
Grid_Click(object sender,
System.Windows.Input.MouseButtonEventArgs e)
{
SimpleGrid.SimpleGrid grid = (SimpleGrid.SimpleGrid)sender;
grid.RowDefinitions = "50,*,*,50";
grid.ColumnDefinitions = "100,*,100";
}
}
}
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
}
SimpleGrid.SimpleGrid grid = (SimpleGrid.SimpleGrid)sender;
grid.RowDefinitions = "50,*,*,50";
}
}
When you first run the program you see the rows and columns have been created as expected. When you click anywhere in the grid, the row and column definitions are changed but the content is preserved.
<Click>