10

I am working on a C# WPF application, using .resx files for resource management. Now, I'm trying to add icons (.ico) to the project but I'm running into some problems.

<Image Name="imgMin" Grid.Column="0"
       Stretch="UniformToFill"
       Cursor="Hand" 
       MouseDown="imgMin_MouseDown">
    <Image.Style>
        <Style TargetType="{x:Type Image}">
            <Setter Property="Source" Value="\Images\minimize_glow.ico"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Source" Value="\Images\minimize_glow.ico"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

This works fine, but when I move the icon into AppResources.resx I run into problems with referencing it in the xaml code. What should I be using instead of the Setter Property=... lines above? This:

<Setter Property="Source" Value="{x:Static res:AppResources.minimize}"/>

doesn't work, I think I probably need to use a different Property than "Source" because Value isn't a string pointing to the icon but the icon itself now. I can't figure out which one to use though - some help, please?

H.B.
  • 166,899
  • 29
  • 327
  • 400
Swooper
  • 359
  • 4
  • 13

1 Answers1

3

The Source property does not "want" a string, it just converts it when it gets one. If you add an icon to the resources it will be of the type System.Drawing.Icon. You will need to convert it to an ImageSource via converter.

You can do a static access to resources but it needs to comply with the expected syntax of x:Static.

e.g.

xmlns:prop="clr-namespace:Test.Properties"
<Image MaxHeight="100" MaxWidth="100">
    <Image.Source>
        <Binding Source="{x:Static prop:Resources.icon}">
            <Binding.Converter>
                <vc:IconToImageSourceConverter/>
            </Binding.Converter>
        </Binding>
    </Image.Source>
</Image>
public class IconToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var icon = value as System.Drawing.Icon;
        var bitmap = icon.ToBitmap();

        //http://stackoverflow.com/questions/94456/load-a-wpf-bitmapimage-from-a-system-drawing-bitmap/1069509#1069509
        MemoryStream ms = new MemoryStream();
        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Position = 0;
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();

        return bi;
    }

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

Notes:

  • The resource access modifier must be public
  • If the image is added as "Image" you end up with a Bitmap instead of an Icon, which requires a different converter
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • Very useful... I think. I'm now getting an error that says: Unknown build error, 'Key cannot be null. Parameter name: key Line 131 Position 34.' Pointing to Binding Source="{x:Static res:AppResources.minimize}" – Swooper Apr 26 '11 at 14:05
  • One thing that is important is that the resource access modifier is public as opposed to internal, but that throws another exception that the one you have. – H.B. Apr 26 '11 at 14:16
  • I'm using .NET 3.5 rather than 4.0 for backwards compatibility reasons - I don't suppose that could be an issue here? – Swooper Apr 26 '11 at 14:19
  • Nope, i just went ahead and tested it in a new .NET 3.5 project, it worked. – H.B. Apr 26 '11 at 14:25
  • Mmm, didn't think that'd be it. However, I'm also getting the strangest error now: _The type 'Helpers:IconToImageSourceConverter' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built._ I've got the right `using` line in the code-behind, `xmlns:Helpers` is pointing to the correct namespace... What the hell? – Swooper Apr 26 '11 at 14:47
  • Code behind does not matter, only the `xmlns` is important. Of course the class should be public too. – H.B. Apr 26 '11 at 15:47
  • It is. When I type `Helpers:` VS gives me a dropdown with the other three classes in the Converters namespace, but doesn't seem to recognize IconToImageSourceConverter... I tried creating another converter class in case I somehow did something wrong the first time, same issue. – Swooper Apr 26 '11 at 16:18
  • Still getting the "Key cannot be null" error as well, btw. Maybe they're somehow connected... – Swooper Apr 26 '11 at 16:29
  • Found the error, finally! While modifying the code snippet you posted to match the style of my project, I changed `prop` to `res` in the code but neglected to fix `xmlns:prop` as well... My bad! – Swooper Apr 27 '11 at 14:17