Столкнулся с интересной задачей. Есть некоторая коллекция данных, которую надо отобразить в ItemsControl. У элементов данных есть два свойства: первое просто текст, а второе имя ресурса с картинкой которую необходимо показать. Т.е. в зависимости от данных в модели должен подгружаться тот или иной ресурс. Поискав решение быстро наткнулся на применение конвертора который ищет ресурс по имени следующим способом:

return Application.Current.FindResource(resourceName) as BitmapImage;


Но это не работает, если ресурсы подгружены не в приложение, а например, в окно или контрол. Под катом интересный метод, который позволяет получить доступ к ресурсу где бы он не находился, главное, чтобы был доступен контролу.


В рамках примера, я буду использовать простой класс с двумя свойствами:

public class Model
{
    public string Title { getset; }

    public string ResourceName { getset; }
}

Вот разметка формы:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication4"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BitmapImage x:Key="plus" UriSource="plus.png" />
        <BitmapImage x:Key="delete" UriSource="delete.png" />
        <local:NameToStyleConverter x:Key="NameToStyleConverter" />
    </Window.Resources>
    <Grid>
        <ItemsControl x:Name="icDemo">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Style="{Binding ResourceName,Converter={StaticResource NameToStyleConverter}}" />
                        <TextBlock Text="{Binding Title}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

А вот заполнение данными списка при загрузке:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        List<Model> items = new List<Model>();
        items.Add(new Model() { Title = "Один", ResourceName = "plus" });
        items.Add(new Model() { Title = "Два", ResourceName = "plus" });
        items.Add(new Model() { Title = "Три", ResourceName = "delete" });
        items.Add(new Model() { Title = "Четыре", ResourceName = "plus" });
        items.Add(new Model() { Title = "Пять", ResourceName = "delete" });
        icDemo.ItemsSource = items;
    }
}

Как можно видеть из разметки, у контрола Image свойство Source не присваивается, а присваивается… Стиль! Ну а дальше все просто, получая имя ресурсы, мы конвертором создаем динамически стиль, в котором свойству Source присваиваем DynamicResource. Вот так:

public class NameToStyleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Style result = null;
        var name = value?.ToString();
        if (!string.IsNullOrWhiteSpace(name))
        {
            result = new Style(typeof(Image));

            var dynamicResource = new DynamicResourceExtension(name);

            var setter = new Setter()
            {
                Property = Image.SourceProperty,
                Value = dynamicResource
            };
            result.Setters.Add(setter);

        }
        return result;
    }

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

Ну и вот так это выглядит:

Как я уже сказал, таким образом надо поступать, если в конверторе нельзя просто извлечь ресурсы из Application. Так, кстати, можно и другие свойства задавать, необязательно привязку к ресурсам.