放置关联模型的位置 - >查看模型?

时间:2015-06-16 09:34:43

标签: c# wpf mvvm software-design

我基本上有以下代码来实现我的MVVM风格:

public class ElementA : IElement
{}

public class ElementB : IElement
{ }

public class VMElementA : IElementViewModel // for element A
{ }
public class VMElementA2 : IElementViewModel // another option vor element A
{ }
public class VMElementB : IElementViewModel // for element B
{ }


public class ContainerModel
{
    public IElement[] Elements { get; }
    public void AddNewElement(IElement element);
}

public class ContainerVieWModel
{
    private ContainerModel model;

    public IElementViewModel[] Elememnts
    {
        get
        {
            return model.Elements.Select(e => ?).ToArray();

        }
    }

    // is called internally, e.g. activated by a command
    private void AddNewElement(? element)
    {
        model.AddNewElement(?);
    }
}

我有一个包含IElement列表的模型,可供视图模型访问。视图模型需要提供相应的视图模型。

我希望在以下限制下实现这一目标:

  1. 我不希望模型(例如ElementAContainerModel)知道"知道"它的视图模型。有些模型甚至可能有多个可能的视图模型,因此无法进行硬编码。

  2. 我希望元素创建发生在模型代码中,而不是视图模型代码。

  3. 到目前为止我已经考虑过的事情:

    • 我在类似情况下(没有创建)完成的事情是向模型中添加包装元素,包含元素和能够将模型转换为视图模型的委托。

      public interface IExtendedElement
      {
          IElement Model { get; }
          IElementViewModel GetViewModel(); //possibly other arguments
      }
      
      public class ExtendedElement<T> : IExtendedElement where T : IElement
      {
          private readonly T model;
          private readonly Func<T,  IElementViewModel> viewModelGenerator;
      
          public ExtendedElement(T model, Func<T,  IElementViewModel> viewModelGenerator)
          {
              this.model = model;
              this.viewModelGenerator = viewModelGenerator;
          }
      
      
          public IElement Model
          {
              get { return model; }
          }
      
          public IElementViewModel GetViewModel()
          {
              return viewModelGenerator(model);
          }
      }
      
    • 另一种方法是存储映射函数并执行映射模型 - &gt;使用函数集合在视图模型中查看模型。如果没有能够映射某个模型的函数,这可能会产生一些运行时错误。

      public partial class ContainerViewModel
      {
          // the conversion functions have to case the element to the appropriate "real" type
          private IDictionary<Type, Func<IElement, IElementViewModel>> modelToViewModel;
          public IElementViewModel[] Elememnts
          {
              get
              {
                  return model.Elements.Select(e => Map(e)).ToArray();
      
              }
          }
      
          private IElementViewModel Map(IElement element)
          {
              // how can I assure that the conversion function is present?
              return modelToViewModel[element.GetType()](element);
          }
      
      }
      

    这两种方法对我来说都不合适。任何建议将不胜感激。

0 个答案:

没有答案