2015-01-07 2 views
1

что у меня есть объект график, который выглядит следующим образом (это не мой реальный объект):Преобразование свойств объекта в различных показах состояния объектов

CaseFile 
- Sections (collection) 
    - Documents (collection of type:Document) 
- Other Node 
    - Other Children (collection) 
    - More children (collection) 

И я хочу, чтобы представить эти данные в «TreeView ». Я использую HierarchicalDataTemplate для управления отображением каждого дочернего объекта, это отлично работает.

<HierarchicalDataTemplate DataType="x:Type local:Document"> 
    <StackPanel Orientation="Horizontal"> 
    <Image Source="{Binding FileName, Converter="MyResourceConverter"}" /> 
    <TextBlock Foreground="Red" Text="{Binding Name}" /> 
    </StackPanel> 
</HierarchicalDataTemplate> 

Я хочу отображать специальные значки для разных объектов. Здесь он становится толстым: я могу отображать статические изображения для определенных классов или типов, я даже могу отображать значки на основе метаданных экземпляра класса. Я использую 'IValueConverter' для этого, и он отлично работает.

class MyResourseConverter : IValueConverter 
{ 
    private static readonly IImageManager _imageManager = 
    new CachedImageManager(new SystemImageManager()); 


    public MyResourceConverter() // place where I'd like to inject this IImageManager 
    { 
    } 
    //... IValueConverter Properties 
    //... That uses the _imageManger 
} 

Моих «IValueConverter» имел зависимостей, и я не могу понять, как вводить эту зависимость и я искал повсюду, чтобы увидеть, как это исправить. Самое близкое, что я видел, чтобы исправить это, - это использовать что-то вроде «ServiceLocator» inline в классе, но это похоже на анти-шаблон для меня, это в первую очередь побеждает цель IoC.

Есть ли другой способ получить объекты моего подграфа для отображения или 'convert' их данные в такие вещи, как 'ImageSource' без конвертора?

+1

Как насчет с ViewModel-версией Document-класса (или некоторым другим видом фасада для класса)? В этом классе у вас может быть свойство, возвращающее URI для изображения. Это свойство может использовать введенный IImageManager. –

+2

Не могли бы вы использовать [x: Аргументы] (http://msdn.microsoft.com/en-us/library/ee795382.aspx) для ввода зависимостей в XAML при объявлении конвертера? – GazTheDestroyer

+0

@GazTheDestroyer: Вы должны сказать это как ответ. 'ServiceLocator' - самый простой способ получить зависимость, но ломает SOLID - я не знал о' x: Аргументы', прежде чем вы упомянули об этом. Хороший! – toadflakz

ответ

0

Вы можете использовать x:Arguments в XAML для ввода зависимостей через ваш конструктор преобразователя.

0

несколько позорным, но я делаю что-то похожее на 'ServiceLocator' просто катиться вперед:

в App.xaml.cx

using System.Windows; 
using SimpleInjector; 

public partial class App : Application 
{ 
    private static Container container; 

    [System.Diagnostics.DebuggerStepThrough] 
    public static TService GetInstance<TService>() where TService : class { 
     return container.GetInstance<TService>(); 
    } 

    protected override void OnStartup(StartupEventArgs e) { 
     base.OnStartup(e); 
     Bootstrap(); 
    } 

    private static void Bootstrap() { 
     // Create the container as usual. 
     var container = new Container(); 

     // Register your types, for instance: 
     container.RegisterSingle<IImageManager>(() => new CachedImageManager(new SystemImageManager());); 

     // Optionally verify the container. 
     container.Verify(); 

     // Store the container for use by the application. 
     App.container = container; 
    } 
} 

В преобразователе

class MyResourseConverter : IValueConverter 
{ 
    private static readonly IImageManager _imageManager = 
    new CachedImageManager(new SystemImageManager()); 

    public MyResourceConverter() 
    { 
    _imageManager = App.GetInstance<IImageManager>(); 
    } 

    //... IValueConverter Properties 
    //... That uses the _imageManger 
} 
Смежные вопросы