【问题标题】:Converting Object Properties Into Different View-able Objects将对象属性转换为不同的可视对象
【发布时间】:2015-01-07 06:35:04
【问题描述】:

假设我有一个看起来像这样的对象图(这不是我的真实对象):

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”之类的东西,但这对我来说似乎是一种反模式,它首先完全违背了 IoC 的目的。

有没有其他方法可以让我的子图对象显示或“convert”他们的数据在没有转换器的情况下变成“ImageSource”之类的东西?

【问题讨论】:

  • 拥有一个 ViewModel 版本的 Document-class(或其他类型的 Facade)怎么样?在此类中,您可以有一个属性返回图像的 URI。该属性可以使用注入的 IImageManager。
  • 声明转换器时能否使用x:Arguments在XAML中注入依赖关系?
  • @GazTheDestroyer:你应该把它作为答案。 ServiceLocator 是获取依赖项的最简单方法,但会破坏 SOLID - 在您提到它之前,我不知道 x:Arguments。不错!
  • 完成了,干杯。很高兴它成功了。
  • 我不确定,但如果这是一个问题,您可以随时在代码隐藏中更新它并使用 this.Resources.Add("MyResourceConverter", converter); 将其添加到资源中?

标签: c# wpf mvvm inversion-of-control ivalueconverter


【解决方案1】:

您可以在 XAML 中使用 x:Arguments 通过转换器构造函数注入依赖项。

【讨论】:

    【解决方案2】:

    有点可耻,但我正在做类似于“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
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      相关资源
      最近更新 更多