Search code examples
silverlightxamlenums

How to display different Enum icons using XAML only?


I want to show a different icon/image depending on an enum value. For example, if I had the following enum:

  public enum UploadStatus
  {
      Unknown = 0,
      WaitingToUpload = 10,
      Uploading = 20,
      Uploaded = 30,
      UploadFailed = 40
  }

I'd like to write XAML that looks something like this:

...

<EnumImage Value="{Binding Path=CurrentStatus}">
  <EnumImageItem Value="Unknown"         Image="/images/unknown.png" />
  <EnumImageItem Value="WaitingToUpload" Image="/images/clock.png" />
  <EnumImageItem Value="Uploading"       Image="/images/upload.png" />
  <EnumImageItem Value="Uploaded"        Image="/images/tick.png" />
  <EnumImageItem Value="UploadFailed"    Image="/images/error.png" />
</EnumImage>

...

I've found many posts suggesting custom IValueConverters, but those solutions don't fit the XAML paradigm.

Any pointers or suggestions?


Solution

  • Here is a Value converter which maintains the "XAML paradigm" that is the relationship between enum values and images is maintained in XAML.

    [ContentProperty("Items")]
    public class EnumToObjectConverter : IValueConverter
    {
        public ResourceDictionary Items { get; set; }
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string key = Enum.GetName(value.GetType(), value);
            return Items[key];
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException("This converter only works for one way binding");
        }
    }
    

    Note that this is very generic it actually maps values of any enum type to any arbitary object. This is what its usage looks like in Xaml:-

    <Grid.Resources>
      <local:EnumToObjectConverter x:Key="Icons">
        <ResourceDictionary>
     <BitmapImage x:Key="Unknown" UriSource="/images/unknown.png" />
          <BitmapImage x:Key="WaitingToUpload" UriSource="/images/clock.png" />        
          <BitmapImage x:Key="Uploading"       UriSource="/images/upload.png" />        
          <BitmapImage x:Key="Uploaded"        UriSource="/images/tick.png" />        
          <BitmapImage x:Key="UploadFailed"    UriSource="/images/error.png" />        
        </ResourceDictionary>
      </local:EnumToObjectConverter>
    </Grid.Resources>
    

    This converter can be used when binding property of the enum type:-

     <Image Source="{Binding Status, Converter={StaticResource Icons}}" />