2
votes

I have a list of objects. Each object has a property named "ext" that represents the file type. (PDF, CSV, etc.) Programmatically before binding the itemsource of the datagrid to the collection of objects, I'm dynamically creating the datagrid columns using datagridtemplatecolumn objects.

I have a DataTemplate resource that is basically an image:

<DataTemplate x:Key="imageThumb">
        <Image x:Name="docImage" Width="25" Height="25" Source="/MyApp;component/images/pdf-icon.png">
            <Image.Effect>
                <DropShadowEffect ShadowDepth="1" BlurRadius="1" Opacity="0.5"/>
            </Image.Effect>
        </Image>
    </DataTemplate>

Then in my code behind while dynamically creating the datagrid template columns:

DataTemplate imageTemplate = (DataTemplate)this.Resources["imageThumb"];

DataGridTemplateColumn docType = new DataGridTemplateColumn();
docType.Header = "Doc Type";
docType.CellTemplate = imageTemplate;
targetDataGrid.Columns.Add(docType);

When I simply set this as the cell template of the datagridtemplate column all is well but obviously every single row has a PDF icon in the column. I'm wanting to dynamically change the source path of this Image" based on the extension property of the object that is bound to the datagrid row.

Is there any way to do this?

2
it would help get better answers if you included one of the other column's template so we can see how you're binding the data, or the code if you're doing it in code.hatchet - done with SOverflow

2 Answers

3
votes

Grab the code for the StringToObjectConverter from this blog Yet another blog about IValueConverter

In your Xaml resources set up your set of known icon images in a StringToObjectConverter like this:

        <local:StringToObjectConverter x:Key="DocTypeToBitmap">
             <ResourceDictionary>
                 <BitmapImage x:Key="pdf" UriSource="/MyApp;component/images/pdf-icon.png" />
                 <!-- Other BitmapImages here -->
                 <BitmapImage x:Key="__default__" UriSource="/MyApp;component/images/unknown-icon.png" /> 
            </ResourceDictionary>
         </local:StringToObjectConverter>

(You could of course fill this list of BitmapImages programmatically if you prefer).

Now you can use this converter with binding in you

<DataTemplate x:Key="imageThumb">
    <Image x:Name="docImage" Width="25" Height="25" Source="{Binding docType, Converter={StaticResource DocTypeToBitmap}}"> 
        <Image.Effect>
            <DropShadowEffect ShadowDepth="1" BlurRadius="1" Opacity="0.5"/>            
        </Image.Effect>
    </Image>
</DataTemplate>

Now the image will track with changes to docType dynamically.

1
votes

If you're binding to a model for the other column values, you can create a partial class for the model class you're using. Write a property with just a 'get' that returns the image you want displayed (based, I'm assuming, on the value of another property of that model such as docType). Then you can bind the thumbnail column like you would the other columns. You'll also need an ImageConverter.

You can skip the need for ImageConverter by having your property return a BitmapImage instead of an Image. Kind of like this:

public BitmapSource ThumbnailBitmapSource {
    get {
        BitmapImage img = new BitmapImage(someUriYouGetBasedOnDocType);
        return img;
    }
}

To get the image to update automatically when the docType changes, you'll need to also implement the following in your partial class

partial void OnDocTypeChanged() {
    this.RaiseDataMemberChanged("ThumbnailBitmapSource");
}