2016-08-10 47 views
0

我有一个应用程序需要为每个类的属性显示输入表单。事情是,我不知道我在编译时正在处理哪个类,所以它需要是动态的。现在,我曾经在之前做到这一点的代码隐藏,如:使用MVVM模式创建UI元素

foreach (var P in TheType.GetProperties()){ 

    this.ControlStackPanel.Children.Add(/.../) 
// and so on 

} 

但是这一次我试图这样做纯MVVM模式,所以我不能使用代码隐藏。我的想法是通过构造函数将我的窗口实例注入ViewModel,但我被告知完全破坏了MVVM模式。

那么,关于如何做到这一点的任何想法?

+0

听起来像你正在重新发明'PropertyGrid'。但我不明白这个问题。为什么它必须是“动态”的? ViewModel应该**不知道任何关于视图。 ViewModel **可以**准备一个视图用来生成子项的列表。纯MVVM - 将代码移入行为/转换器/等,但请不要将其移动到ViewModel中。 – Sinatr

+0

“ViewModel可以准备一些东西将被视图用来生成儿童的列表。” 好的,我该怎么做?我是否准备了UIElements列表或仅列出了属性?该视图如何知道如何处理它?我该如何绑定到该列表? –

+0

您不准备UI元素列表。但它可以是一个ViewModels列表 - ObservableCollection ',其中'Item'包含所有必要的属性('Icon','Text',无论你需要什么)。该视图可以检查'Loaded'中的'DataContext'以获取ViewModel实例。然后,您可以将该集合绑定到“ItemsControl.ItemsSource”,并使用数据模板或模板选择器可视化这些(在数据模板中,您可以定义绑定到ViewModel的具体属性)。或者,如果您不介意非纯MVVM(我不这样做),请在视图中像您已经这样做,但使用该集合。 – Sinatr

回答

0

创建一个视图模型,并通过setter或property(或稍后未更改的构造函数)为其指定对象的类型。然后将这些属性作为List属性与公共getter和private setter一起发布。您可以在属性的getter中构建子元素,但在将类型赋予给视图模型时,这样做效率会更高,因此只需执行一次。然后通过XAML绑定到列表。您需要为每种支持的类型创建一个新类。这也将帮助您了解输入内容。然后在xaml一侧,您需要使用模板选择器来获取给定类的正确形式。

这将是实现的视图模型。

public class TheViewModel 
{ 
    public void SetTheType(Type theType) 
    { 
     Inputs.Clear(); 
     foreach (var prop in theType.GetProperties()) 
     { 
      if (prop.PropertyType == typeof(DateTime) 
      { 
       Inputs.Add(new DateTimeInput...); // create the descriptors here 
      } 
      // other known types here 
     } 
    } 

    public IList<InputBase> Inputs{get; private set;} 

} 

public class InputBase 
{ 
} 

public class DateTimeInput : InputBase 
{ 
    DateTime Value {get;set} 
} 
2

我想这样做纯MVVM模式,所以我不能使用代码隐藏。

不,不。编号

MVVM的设计模式是关于将代码归入。查看代码不属于属于查看模型。我已经详细了解了这个here

我不知道我在编译时处理哪个类,所以它需要动态。

在这种情况下,您可能可以使用DataTemplate为您需要的每个类类型。请参阅documentation。这将允许您的视图根据您处理的类类型进行动态更改。

+1

我也不明白*纯MVVM *的想法(除非你正在与设计师合作,并且你的代码会给他带来麻烦,我猜)。将代码放入'Window.xaml.cs'就完全没问题。查看**可以**了解ViewModel。我从来没有必须重复使用与多个ViewModel相同的View,但是如果我愿意的话,一个简单的基类/接口将解决所有问题。 – Sinatr

+0

我同意,我也从来没有用不同的视图模型使用相同的观点。你很可能会*,但这不太可能。 –