For example I could do something like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Width="Auto">
<RowDefinition Width="Auto">
<RowDefinition Width="Auto">
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0">Header 1</TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" MaxLines="1" />
<Button Grid.Row="0" Grid.Column="2">Send</Button>
<Button Grid.Row="0" Grid.Column="3">Save</Button>
<TextBlock Grid.Row="1" Grid.Column="0">Header 2</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" MaxLines="1" />
<Button Grid.Row="1" Grid.Column="2">Send</Button>
<Button Grid.Row="1" Grid.Column="3">Save</Button>
<TextBlock Grid.Row="2" Grid.Column="0">Header 3</TextBlock>
<TextBox Grid.Row="2" Grid.Column="1" MaxLines="1" />
<Button Grid.Row="2" Grid.Column="2">Send</Button>
<Button Grid.Row="2" Grid.Column="3">Save</Button>
</Grid>
Or I could do something like this:
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Header 1</TextBlock>
<TextBox MaxLines="1" />
<Button>Send</Button>
<Button>Save</Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Header 2</TextBlock>
<TextBox MaxLines="1" />
<Button>Send</Button>
<Button>Save</Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Header 3</TextBlock>
<TextBox MaxLines="1" />
<Button>Send</Button>
<Button>Save</Button>
</StackPanel>
<StackPanel>
Except that I want to be able to easily manipulate the rows (add new rows, move rows around, etc.) just like in the StackPanel, while keeping the columns aligned properly just like in the Grid.
You could use many one-row Grids
with size sharing on the columns. It gets verbose when done without any controls, so you could encapsulate some logic (like creating columns and assigning Grid.Column
) in a derivative of ItemsControl
or an attached property for example.
Here's a class I just threw together for approximately the same purpose - essentially I wanted to be able to put a bunch of labels in the left column and values of different types (text box, dropdown, etc) on the right.
It only has two columns, but it could be adapted to different numbers.
public class LabelValueGrid : Grid
{
public LabelValueGrid()
: base()
{
ColumnDefinitions.Add(new ColumnDefinition());
ColumnDefinitions.Add(new ColumnDefinition());
ColumnDefinitions[0].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto);
ColumnDefinitions[1].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star);
}
protected override void OnVisualChildrenChanged(System.Windows.DependencyObject visualAdded, System.Windows.DependencyObject visualRemoved)
{
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
int curRow = -1;
int curCol = 1;
RowDefinitions.Clear();
if (Children != null)
foreach (System.Windows.UIElement curChild in Children)
{
if (curCol == 0)
curCol = 1;
else
{
curCol = 0;
curRow++;
RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto)});
}
Grid.SetRow(curChild, curRow);
Grid.SetColumn(curChild, curCol);
}
RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star)});
}
}
I can use this like a grid, except I just list the controls and then it alternates the columns automatically:
<local:LabelValueGrid>
<TextBlock Text="Label1"/>
<TextBox Name="value1"/>
<TextBlock Text="Label2"/>
<TextBox Name="value2"/>
</local:LabelValueGrid>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With