具有多个图像的 WPF DataGrid RowDetailsTemplate (MVVM)

Posted

技术标签:

【中文标题】具有多个图像的 WPF DataGrid RowDetailsTemplate (MVVM)【英文标题】:WPF DataGrid RowDetailsTemplate with Multiple Images (MVVM) 【发布时间】:2013-11-20 20:29:26 【问题描述】:

目标

使用 MVVM 标准在 DataGrid 的 RowDetails 模板中添加多个图像。

背景

我有一个带有 DataGrid 的检查窗口,用于保存损坏项目的描述以及检查员的姓名首字母。更重要的是,这个DataGrid的RowDetailsTemplate需要保存检查员拍摄的损坏物品的照片(因此损坏物品的照片可能不止一张)。

问题

我有一个 DamagedWindow.xaml,旨在创建我的 DamagedItem 条目。它看起来像这样:

数据网格 (.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>

如您所见,我的 RowDetails 模板在此 DataGrid 中运行良好。我有一个名为 PicturesList 的类,它继承了我的 PictureModel(Name, Description, Path) 的 ObservableCollection。


您在 DataGrid 上方看到的文本框是我的 DamagedItemModel 的属性(DescriptionInitialesPicturesList)。因此,当用户单击接受(复选标记)按钮时,DamagedItem 将添加到 DamagedItemsList,然后从我的 MainWindow 将其设置为 DataGrid 的 ItemSource:

数据网格 (.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>

在这里,当我选择行时,我得到一个空的 RowDetailsTemplate 结果......即使我的对象包含我的图像。详情见下文:

所以这是我的问题,是否可以在遵循 MVVM 标准的同时将多个图像添加到 DataGrid 中的 RowDetailsTemplate?如果是,我做错了什么?

【问题讨论】:

【参考方案1】:

你不能那样绑定。你需要这样做:

        <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>

您的方法不起作用的原因是 绑定源 始终是一个由 绑定路径 设置的对象,而您的 绑定路径Pictures.Path,因为Pictures 对象没有Path,所以它的项目没有Path

一般来说,每当您发现自己在处理某种集合时,请考虑一个适合显示集合的控件,例如 ListBoxDataGrid 或最好的 ItemsControl

这些控件的ItemTemplate 中的任何内容都会将其DataContext 自动设置为相应的项目,因此您不必担心。您所要做的就是将ItemsSource 设置为您的集合,并将内部事物的绑定路径设置为该集合的Type 的属性,以便它知道在哪里寻找每个项目的数据。

在这段代码中你可以这样想,比如你有一些StackPanels,第一个有:Image Source="Binding Pictures(0).Path",第二个有Image Source="Binding Pictures(1).Path"等等。这样所有绑定路径都指向一个对象。

【讨论】:

做到了。你能解释一下你的答案吗?我不确定为什么我需要 ItemsControl 或为什么我的方法完全关闭..

以上是关于具有多个图像的 WPF DataGrid RowDetailsTemplate (MVVM)的主要内容,如果未能解决你的问题,请参考以下文章

Wpf DataGrid RowStyle 如何使用图像或画笔作为背景

合并标题列datagrid wpf

当 Datagrid 失去焦点时,WPF DataGridRow 自定义样式被解除

WPF Datagrid对具有空元素的列进行排序

具有循环虚拟化功能的C#WPF Datagrid

如何使 WPF DataGrid 显示具有绑定和 DataTemplate 的 ViewModel 集合