0

I have a DataTable that has several columns defined. I then added another columns that should contain an icon based on the data of the table itself, i.e. the data contains the icon ID than in the proper row in the column "Icons" the right icon shall appear.

My data is generated like this:

var cat = ReportTexts.Instance.Sheets.Param;
workSheet = excel.Workbook.Worksheets[cat];
outReport.ParametersDT = workSheet.ToDataTable(true);
outReport.ParametersDT.Columns.Add("Icons", typeof(BitmapImage));
foreach (DataRow row in outReport.ParametersDT.Rows)
    row["Icons"] = this.GetIconImageFromParameterReference(row[ReportTexts.Instance.Headers.Type]);

Then in my xaml file i did this:

<TabControl DockPanel.Dock="Top" TabStripPlacement="Top">
    <TabItem Header="{Binding Path=LoadedReport.Configuration.Title}">
        <DockPanel>
            <TextBlock DockPanel.Dock="Top" Text="TEMP" />
            <DataGrid
                AutoGenerateColumns="True"
                DataContext="{Binding Path=LoadedReport.ParametersDT.DefaultView, Source={StaticResource ResourceKey=VM}}"
                DockPanel.Dock="Top"
                ItemsSource="{Binding Path=LoadedReport.ParametersDT.DefaultView.Table, Source={StaticResource ResourceKey=VM}}"/>
        </DockPanel>
    </TabItem>
</TabControl>

The result is similar to what I am looking to but not quite, as shown in the screenshot:

The created DataGrid

After looking around here in SO i found that the good idea would be to define a DataGidCellTemplate and then filetr it by header, so I did this:

<TabControl DockPanel.Dock="Top" TabStripPlacement="Top">
    <TabItem Header="{Binding Path=LoadedReport.Configuration.Title}">
        <DockPanel>
            <TextBlock DockPanel.Dock="Top" Text="TEMP" />
            <DataGrid
                AutoGenerateColumns="True"
                DataContext="{Binding Path=LoadedReport.ParametersDT.DefaultView, Source={StaticResource ResourceKey=VM}}"
                DockPanel.Dock="Top"
                ItemsSource="{Binding Path=LoadedReport.ParametersDT.DefaultView.Table, Source={StaticResource ResourceKey=VM}}">
                <DataGridTemplateColumn Header="Icons">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image  
                                Width="50"
                                Height="25"
                                Source="{Binding UriSource}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid>
        </DockPanel>
    </TabItem>
</TabControl>

Sadly, this compiles but then throws a System.InvalidOperationException stating that the elements' collection must be empty before using ItemsSource. (my native language is italian, so the translation might be a little off, here is the VS one: 'La raccolta di elementi deve essere vuota prima di poter utilizzare ItemsSource.')

I am a bit stuck here, what am I doing wrong?

EDIT and ANSWERS:

I was pointed to 2 solutions, one entirely base on xaml and one that relies on code behind.

the first one simply consists in inserting the whole DataGridTemplateColumn node inside a DataGrid.Columns node, like this:

                 <DataGrid.Columns>
                        <DataGridTemplateColumn CellTemplate="{StaticResource ResourceKey=IconColumn}" Header="NewColumnHeader" />
                    </DataGrid.Columns>

Since I need to do the exact addition to several tables i declared the template as StaticResource and bound the data with a Converter that manages the various cases. The main issue with this approach is that instead of changing the template of the existing column I am adding a new one, hence the header "NewColumnHeader".

The second solution is the one linked by @ASh, where you manage the automatic column generation event in the code behind to change the existing column to your desire. This solution let me do what I intended in the first place, but more importantly let me work even deeper in the column structure. this is the question link: Answer to the question about images in datagrid by @ASh

  • 1
    https://stackoverflow.com/questions/40358111/datagrid-shows-path-of-image-instead-of-image-itself – ASh Apr 26 '21 at 14:51
  • Thank you! I wanted to do everything on xaml, but this will also help me with the next problem (adding an a priori unknown number of columns, based on available data)! – Marcomattia Mocellin Apr 27 '21 at 06:54

0 Answers0