To add multiple images in a DataGrid's RowDetails template using the MVVM standards.
I have an inspection window with a DataGrid designed to hold a damaged item's description along with the initials of the inspector. What is more, this DataGrid's RowDetailsTemplate needs to hold the pictures that the inspector took of the damaged item (so there might be more than one picture of the damaged item).
I have a DamagedWindow.xaml designed to create my DamagedItem entries. It looks like this:
DataGrid (.XAML)
<DataGrid ItemsSource="{Binding Pictures}" SelectedItem="{Binding SelectedPicture}" AutoGenerateColumns="False" Grid.Column="1" Grid.Row="2" Margin="5" HorizontalAlignment="Stretch" Name="DataGrid1" VerticalAlignment="Stretch" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Titre" Binding="{Binding Name}" Width="*" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Image Height="100" Source="{Binding Path}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
As you can see, my RowDetails template works fine in this DataGrid. I have a class named PicturesList which inherits an ObservableCollection Of my PictureModel(Name
, Description
, Path
).
The text boxes that you see above the DataGrid are properties of my DamagedItemModel (Description
, Initiales
, PicturesList
). So when the user clicks on the Accept (Checkmark) button, the DamagedItem is added to a DamagedItemsList which is then set as the ItemSource of the DataGrid from my MainWindow:
DataGrid (.XAML)
<DataGrid ItemsSource="{Binding Path=DamagedItems}" SelectedItem="{Binding Path=SelectedDamagedItem}" AutoGenerateColumns="False" Name="DataGrid1" Height="250" Margin="3" IsEnabled="True" CanUserAddRows="False" FontSize="16">
<DataGrid.Columns>
<DataGridTextColumn Header="Description" Width="*" Binding="{Binding Description}"/>
<DataGridTextColumn Header="Initiales" Width="70" Binding="{Binding Initiales}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Image Height="100" Source="{Binding Pictures.Path}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Here when I select the row, I get an empty RowDetailsTemplate result ... Even though my object contains my images. See below for more details:
So here's my question, is it possible to add multiple images to a RowDetailsTemplate in a DataGrid while following MVVM standards? If it is, what am I doing wrong?
You can't bind that way. you need to do it like this:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Pictures}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Height="100" Source="{Binding Path}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
The reason your method was not working is that the Binding source is always one object which is set by Binding Path, and your Binding Path was Pictures.Path
which leads to nothing because Pictures
object does not have Path
, it's its Items which have Path
.
In general, Whenever you find yourself dealing with a collection of some kind think of a control which is suitable for showing a collection, like ListBox
, DataGrid
or the best of all ItemsControl
.
Anything that goes inside ItemTemplate
of these controls, have their DataContext
automatically set to the correspondent item, so you don't have to worry about it. All you have to do is to set the ItemsSource
to your collection and set the Binding Paths of things inside to the properties of the Type
of that collection, So that it knows where to look for data for each item.
In this code you can think of it this way, Like you have some StackPanel
s, first one has : Image Source="{Binding Pictures(0).Path}"
, seconds one has Image Source="{Binding Pictures(1).Path}"
and so on. this way all Binding Paths point to an object.
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