In my WPF application, I have a collection to which I would like to bind a grid of controls. An example of the desired layout (TL;DR I want this from an ItemsSource):
Desired layout http://imagebin.ca/img/27UTke
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0">FileUploader</Label>
<ComboBox Grid.Row="0" Grid.Column="1" />
<Button Grid.Row="0" Grid.Column="2">Edit</Button>
<Label Grid.Row="1" Grid.Column="0">TextUploader</Label>
<ComboBox Grid.Row="1" Grid.Column="1" />
<Button Grid.Row="1" Grid.Column="2">Edit</Button>
<Label Grid.Row="2" Grid.Column="0">UrlShortener</Label>
<ComboBox Grid.Row="2" Grid.Column="1" />
<Button Grid.Row="2" Grid.Column="2">Edit</Button>
<Label Grid.Row="3" Grid.Column="0">ImageUploader</Label>
<ComboBox Grid.Row="3" Grid.Column="1" />
<Button Grid.Row="3" Grid.Column="2">Edit</Button>
</Grid>
This example is has hardcoded values; I want to bind the collection dynamically, like using a ListView. However, using a ListView with a GridView isn't what I want; I don't need selection, headers, sorting, etc. To the user, the layout is a neatly organized set of options, not a data set in a grid.
I haven't been able to do this binding properly. I've tried using an ItemsControl with a Grid on the outside, but the Grid is ignored:
Failed attempt 1 http://imagebin.ca/img/kTUordk
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding MyData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<Label Grid.Column="0">Text here</Label>
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
I've also used an ItemsControl with a Grid in the panel, but this creates one Grid per item, which is ugly:
Failed attempt 2 http://imagebin.ca/img/xHo__-JD
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Label Grid.Column="0" Content="{Binding Features}" />
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
After some research, I discovered the SharedSizeGroup property of column and row grid definitions. I have tried this with the previous attempt; however, the middle column (with width *
) does not seem to resize itself to fill the full width of the window:
Failed attempt 3 http://imagebin.ca/img/nEoMJmy
<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="*" SharedSizeGroup="B" />
<ColumnDefinition Width="Auto" SharedSizeGroup="C" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Label Grid.Column="0" Content="{Binding Features}" />
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What is the best way to accomplish the first layout?