Willy
Willy

Reputation: 10638

WPF Setting a Converter's public Image property from xaml

I have a WPF application which uses a converter:

public class MyResultImageConverter : IValueConverter  
{
    public Image OkImage { get; set; }
    public Image FailImage { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || !(value is MyCustomObject))
        {
            return null;
        }

        Image img = null;
        MyCustomObjectdbr = (MyCustomObject)value;
        switch (MyCustomObjectdbr.Code)
        {
            case (int)MyEnum.OK:
                img = this.OkImage;
                break;

            case (int)MyEnum.NOK:
                img  = this.FailImage;
                break;

            default:
                break;
        }

        return img;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Then in window resources I do:

<myConverters:MyResultImageConverter
     OkImage="/My.Tools.Graphics;component/Images/Accept.png" 
     FailImage="/My.Tools.Graphics;component/Images/Cancel.png"
     x:Key="MyResultImageConverter"/>

This converter is later used in a DataGridTemplateColumn:

<dg:DataGridTemplateColumn 
                           Width="SizeToCells"
                           IsReadOnly="True">
    <dg:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Image Source="{Binding Path=MyResult, Converter={StaticResource MyResultImageConverter}}" />
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>

The compiler throws an error when trying to set Image property for the converter:

<myConverters:MyResultImageConverter
     OkImage="/My.Tools.Graphics;component/Images/Accept.png" 
     FailImage="/My.Tools.Graphics;component/Images/Cancel.png"
     x:Key="MyResultImageConverter"/>

More or less, translated it says:

Cannot assign value "/My.Tools.Graphics;component/Images/Accept.png" to OkImage' Property. The 'OkImage' property of type 'Image' cannot be specified as a string.

My.Tools.Graphics is a DLL added to my visual studio solution which contains a folder called Images that contains png images.

Upvotes: 1

Views: 1110

Answers (2)

Clemens
Clemens

Reputation: 128060

Do not use Image (which is a UIElement) as return type of the Convert method. Instead, use ImageSource, which (in contrast to Image) can be assigned to an Image's Source property:

public class MyResultImageConverter : IValueConverter  
{
    public ImageSource OkImage { get; set; }
    public ImageSource FailImage { get; set; }

    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        var customObject = value as MyCustomObject;

        if (customObject == null)
        {
            return null;
        }

        return customObject.Code == MyEnum.OK ? OkImage : FailImage;
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

As an alternative to a Binding Converter you may also use an Image Style with a DataTrigger:

<BitmapImage x:Key="OkImage" UriSource="/My.Tools.Graphics;component/Images/Accept.png"/>
<BitmapImage x:Key="FailImage" UriSource="/My.Tools.Graphics;component/Images/Cancel.png"/>
<Style x:Key="ResultImageStyle" TargetType="Image">
    <Setter Property="Source" Value="{StaticResource FailImage}"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding MyResult}" Value="OK">
            <Setter Property="Source" Value="{StaticResource OkImage}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

...

<DataTemplate>
    <Image Style="{StaticResource ResultImageStyle}"/>
</DataTemplate>

Upvotes: 3

AndrejH
AndrejH

Reputation: 2109

You need to assign the image path to the Source property of Image object and not to the actual image (image path URI is a String and not an Image).

public class MyResultImageConverter : IValueConverter  
{
    public Image OkImage { get; set; }
    public Image FailImage { get; set; }

    public string OkImagePath { get; set{
         OkImage = new Image();
         OkImage.Source = value;
        }
    }

    public string FailImagePath { get; set{
         FailImage = new Image();
         FailImage.Source = value;
        }
    }

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (value == null || !(value is MyCustomObject))
    {
        return null;
    }

    Image img = null;
    MyCustomObjectdbr = (MyCustomObject)value;
    switch (MyCustomObjectdbr.Code)
    {
        case (int)MyEnum.OK:
            img = this.OkImage;
            break;

        case (int)MyEnum.NOK:
            img  = this.FailImage;
            break;

        default:
            break;
    }

    return img;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    throw new NotImplementedException();
}
}

And:

<myConverters:MyResultImageConverter
     OkImagePath="/My.Tools.Graphics;component/Images/Accept.png" 
     FailImagePath="/My.Tools.Graphics;component/Images/Cancel.png"
     x:Key="MyResultImageConverter"/>

Upvotes: -1

Related Questions