Вы правы: самый простой способ решить эту проблему - использовать конвертер.
Свойство Source принимает ImageSource, поэтому вам нужно загрузить растровое изображение в конвертер самостоятельно.
Преобразователь используется следующим образом:
<Image Source="{Binding Name,
RelativeSource={RelativeSource TemplatedParent},
Converter={x:Static local:ImageSourceLoader.Instance},
ConverterParameter=..\Images\Icons\32x32\Blue\{0}.png}" />
И реализован следующим образом:
public class ImageSourceLoader : IValueConverter
{
public static ImageSourceLoader Instance = new ImageSourceLoader();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var path = string.Format((string)parameter, value.ToString());
return BitmapFrame.Create(new Uri(path, UriKind.RelativeOrAbsolute));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Обратите внимание, что это простое решение не может обрабатывать относительный Uris, поскольку свойство BaseUri объектаИзображение недоступно для конвертера.Если вы хотите использовать относительный Uris, вы можете сделать это, связав присоединенное свойство и используя StringFormat:
<Image local:ImageHelper.SourcePath="{Binding Name,
RelativeSource={RelativeSource TemplatedParent},
StringFormat=..\Images\Icons\32x32\Blue\{0}.png}" />
И PropertyChangedCallback присоединенного свойства обрабатывает изображение после объединения BaseUri с отформатированной строкой Uri:
public class ImageHelper : DependencyObject
{
public static string GetSourcePath(DependencyObject obj) { return (string)obj.GetValue(SourcePathProperty); }
public static void SetSourcePath(DependencyObject obj, string value) { obj.SetValue(SourcePathProperty, value); }
public static readonly DependencyProperty SourcePathProperty = DependencyProperty.RegisterAttached("SourcePath", typeof(string), typeof(ImageHelper), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
((Image)obj).Source =
BitmapFrame.Create(new Uri(((IUriContext)obj).BaseUri, (string)e.NewValue));
}
});
}