我基本上有以下代码来实现我的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
列表的模型,可供视图模型访问。视图模型需要提供相应的视图模型。
我希望在以下限制下实现这一目标:
我不希望模型(例如ElementA
或ContainerModel
)知道"知道"它的视图模型。有些模型甚至可能有多个可能的视图模型,因此无法进行硬编码。
我希望元素创建发生在模型代码中,而不是视图模型代码。
我在类似情况下(没有创建)完成的事情是向模型中添加包装元素,包含元素和能够将模型转换为视图模型的委托。
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);
}
}
这两种方法对我来说都不合适。任何建议将不胜感激。