Skip to content

[API Proposal]: Simplify Grid Column and Row Definitions #9802

Open
@himgoyalmicro

Description

@himgoyalmicro

Background and motivation

Following up on discussion in #5612 and #1739 this proposal is to simplify the definition syntax of RowDefinitions and ColumnDefinitions by:

  • Allowing rows and columns within a Grid to be defined by a collection that is delimited by commas or space.
  • Creating a Typeconvertor for ColumnDefinitionCollection and RowDefinitionCollection so they can process String as its input.

Goal

The goal of this feature is to make Grid markup less verbose, allowing developers to create grids with simpler syntax.

Example

Current Syntax

Defining columns and rows is overly tedious, repetitive and not very productive, as is shown below:

<Grid>
    <Grid.ColumnDefinitions>
          <ColumnDefinition Width="1*" />
          <ColumnDefinition Width="2*" />
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="300" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
          <RowDefinition Height="1*" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="25" />
          <RowDefinition Height= "14" />
          <RowDefinition Height="20" />
    </Grid.RowDefinitions>
</Grid>

Proposed Syntax

The same functionality as above with the proposed succinct syntax is shown below:

<Grid ColumnDefinitions="1*, 2*, Auto, *, 300" RowDefinitions="1*, Auto, 25, 14, 20"> </Grid>
<!-- or -->
<Grid ColumnDefinitions="1* 2* Auto * 300" RowDefinitions="1* Auto 25 14 20"> </Grid>

Scope

Feature Priority
Ability for rows and columns to be defined as a collection or list of values Must
Content properties of RowDefinition and ColumnDefinition are set to Height and Width, respectively Must
Original syntax will still be fully supported and functional Must
Hot Reload will still be fully supported and functional Must
Include support for min/max height/width Won't
Include support for data binding within definitions Won't

API Proposal

Provide new typeconverters for ColumnDefinitionCollection and RowDefinitionCollection.
This will allow us to convert string input into the corresponding collection.

namespace System.Windows.Controls
{

+    internal class ColumnDefinitionCollectionConverter : TypeConverter
+    {
+        ...
+    }

+    internal class RowDefinitionCollectionConverter : TypeConverter
+    {
+       ...
+    }

}

Introduce Setter properties for ColumnDefinitons and RowDefinitions of Grid.

+[TypeConverter(typeof(ColumnDefinitionCollectionConverter))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnDefinitionCollection ColumnDefinitions
{
    get { ... }
+    set { ... }
}

+[TypeConverter(typeof(RowDefinitionCollectionConverter))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RowDefinitionCollection RowDefinitions
{
    get { ... }
+    set { ... }
}

API Usage

<Grid ColumnDefinitions="1*, 2*, Auto, *, 300" RowDefinitions="1*, Auto, 25, 14, 20"> </Grid>
<Grid ColumnDefinitions="1* 2* Auto * 300" RowDefinitions="1* Auto 25 14 20"> </Grid>
<Grid RowDefinitions="1*, Auto, 25, 14, 20">
    <Grid.ColumnDefinitions>
          <ColumnDefinition Width="1*" />
          <ColumnDefinition Width="2*" />
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="300" />
    </Grid.ColumnDefinitions>
</Grid>
<Grid ColumnDefinitions="1*, 2*, Auto, *, 300">
    <Grid.RowDefinitions>
          <RowDefinition Height="1*" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="25" />
          <RowDefinition Height= "14" />
          <RowDefinition Height="20" />
    </Grid.RowDefinitions>
</Grid>

Alternative Designs

Introduce new public dependency properties Columns and Rows that provide a dedicated place to update the row and column definitions.

+public string Columns
+{
+    get { ... }
+    set { ... }
+}

+public string Rows
+{
+    get { ... }
+    set { ... }
+}

+public static readonly DependencyProperty ColumnsProperty =
+    DependencyProperty.Register(
+        nameof(Columns),
+        typeof(string),
+        typeof(Grid),
+        new FrameworkPropertyMetadata(null, OnColumnsChanged));

+public static readonly DependencyProperty RowsProperty =
+    DependencyProperty.Register(
+        nameof(Rows),
+        typeof(string),
+        typeof(Grid),
+        new FrameworkPropertyMetadata(null, OnRowsChanged));

Remarks

However, this leaves us with two similar properties to set the same things, which is not a clean approach.

Risks

No response

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implemented

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions