Forum Xamarin.Forms

Setting Icon File Names as Resources

KarenCateKarenCate USMember ✭✭

I was trying to get all of my icon file definitions in one place so that it would be easy to swap icon sets in the future. Since I use XAML for my page definitions, I thought I'd make a ResourceDictionary with all of my icons. Just trying to get it to work, I put one in my App.xaml file:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MyApp"
    x:Class="MyApp.App">

    <Application.Resources>
        <ResourceDictionary>       
            <x:String x:Key="SettingsIcon">"outline_settings_white_48.png"</x:String>
            <!-- rest of file deleted for brevity -->
        </ResourceDictionary>
    </Application.Resources>
</Application>

Then in my xaml, I access it like this:

<ImageButton
    x:Name="SettingsButton"
    Source="{StaticResource SettingsIcon}"
    Clicked="GoSettings"/>

This generates a run-time error (in the application output window):

Could not load image named: {0}: "outline_settings_white_48.png"
FileImageSourceHandler: Could not find image or image file was invalid: File: "outline_settings_white_48.png"

... and of course the icon is not displayed.

If I reference the icon directly, it works just fine:

<ImageButton
    x:Name="SettingsButton"
    Source="outline_settings_white_48.png"
    Clicked="GoSettings"/>

I have tried it without the .png extension, and got the same result.

What am I doing wrong?

Thanks!

P.S. Right now I only need it to work on Android.

Best Answers

  • KarenCateKarenCate US ✭✭
    Accepted Answer

    @AdamMeaney You rock.

    Sorry it took me so long to get back to this, I had a crisis on the PC software side.... Anyway.

    Your project had the answer, and it is mind bogglingly simple and equally unintuitive.

    My code:

    <x:String x:Key="SettingsIcon">"outline_settings_white_48.png"</x:String>
    

    Your code:

    <x:String x:Key="AppSearchIcon">search</x:String>
    

    I removed the quotes and it all works. The .png is optional, it works with or without. But add quotes around your file name, and the image no longer displays.

    ThankyouThankyouThankyouThankyouThankyouThankyou for taking the time to put that little project together for me. It was a HUGE help.

Answers

  • ShantimohanElchuriShantimohanElchuri USMember ✭✭✭✭✭

    @KarenCate In the Resource dictionary you are setting it as a string and the ImageSource is not just string. So use a Binding Converter to convert the string to an ImageSource.

  • KarenCateKarenCate USMember ✭✭

    @ShantimohanElchuri Yeah, I thought that, too. But I get the same error when I put in a converter. The errors is coming from FileImageSourceHandler. The ImageSource can’t open the file. I was wondering if it has something to do with this being an icon in the drawable* directories.

    I can’t be the only one wanting to do this, I’m surprised I couldn’t find ANYthing in a couple of hours of google time.

  • KarenCateKarenCate USMember ✭✭
    edited March 2019

    I misspoke. I could not get the converter to work for anything. This syntax

    <ImageButton x:Name="SettingsButton" Source="{StaticResource SettingsIcon, Converter={StaticResource IconToImageSourceConverter}}"
    

    generates this message:

    Property Converter is not found or does not have an accessible getter
    

    But if I put a property in my view model, this syntax does run (with no change to the converter):

    <ImageButton x:Name="SettingsButton" Source="{Binding SettingsIconName, Converter={StaticResource IconToImageSourceConverter}}">
    

    ... BUT the icon is not displayed. I set a breakpoint in the converter, and it does get the filename from the static resources. but neither ImageSource.FromResource(iconfile) nor ImageSource.FromFile(iconfile) causes my image to be displayed.

    If anyone has any ideas, I'd love to hear them. Or is there a better way to accomplish what I'm trying to do?

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Maybe you have included the files in your project incorrectly. Can you post us a screenshot of your drawable folders, then the properties of one of the image files?

  • KarenCateKarenCate USMember ✭✭

    @AdamMeaney Sadly, not until Monday. The icon does display correctly if I use the file name directly (Source=“SettingsIcon.png”), so I’m pretty sure that’s not the problem. I’m mostly done with this app and am cleaning up the UI... getting all the screens nice and consistent. I don’t like the icons we have, but we’re not going to invest in better ones right now. The app is a companion to our desktop product, so it doesn’t have to be pretty, and what we’ve got isn’t horrible.

    So, anyway, I thought if I had a file with names for all the icons, and the xaml referenced those names, it would be easier to swap them out, it would be a handy list of all the icons we need, and it would provide a place for notes and documentation about them. (Where they came from, free or licensed, etc.)

    I would have guessed this would be a common thing to do, so I’m sure somebody has a solution that works. Danged if I can find it, though. With all the abstraction layers inherent in a forms app, you’d think there’d be a straightforward one for this. What am I missing?

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    I just mean, my images are all resources I use in the App.Xaml to load the string, then reference with {StaticResource keyForResource} just similar to how you do it.

    I figure something else is up if that doesn't work for you, as I have done it in multiple apps.

  • ShantimohanElchuriShantimohanElchuri USMember ✭✭✭✭✭

    @KarenCate Did you try the following syntax?

    <ImageButton x:Name="SettingsButton" Source="{Binding {StaticResource SettingsIconName}, Converter={StaticResource IconToImageSourceConverter}}">
    

    I suppose a StaticResource should be used within {}.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Do not do that. That makes absolutely no sense whatsoever.

    Does that even compile?

    That is just a nonsense line of code. Using a static resource as the path of a binding is just.... no.

  • davefxydavefxy Member ✭✭

    Look at the Xamarin.Forms sample :https://github.com/xamarin/xamarin-forms-samples/tree/master/XAML/MarkupExtensions
    I use this to display embedded image files.

  • KarenCateKarenCate USMember ✭✭

    @davefxy I was not attempting to use embedded image files. I was attempting to use local files from the resources directory. Do I need to provide a markup extension to access a local image file?

    @AdamMeaney Here's your screenshot:

  • davefxydavefxy Member ✭✭

    Sorry what I said is not relevant. I dont know Android all that well but I always insure there is a copy of my image files in the drawable directory in addition to the drawable-xxxx directories.

  • KarenCateKarenCate USMember ✭✭
    Accepted Answer

    @AdamMeaney You rock.

    Sorry it took me so long to get back to this, I had a crisis on the PC software side.... Anyway.

    Your project had the answer, and it is mind bogglingly simple and equally unintuitive.

    My code:

    <x:String x:Key="SettingsIcon">"outline_settings_white_48.png"</x:String>
    

    Your code:

    <x:String x:Key="AppSearchIcon">search</x:String>
    

    I removed the quotes and it all works. The .png is optional, it works with or without. But add quotes around your file name, and the image no longer displays.

    ThankyouThankyouThankyouThankyouThankyouThankyou for taking the time to put that little project together for me. It was a HUGE help.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Glad I could help.

    Figured it was something small, its just usually the small bugs are the hardest to see.

Sign In or Register to comment.