如何在WPF应用程序中构建动态数据输入表单?

9

我正在计划一个WPF应用程序,它将:

  • 能够创建动态数据输入表单(这意味着表单从数据库中获取要显示的字段、它们的顺序等信息,而不是从XAML中获取)
  • 尽可能使用MVVM模式

这是我的计划方式:在客户数据输入视图中,我会设置数据上下文:

<UserControl.DataContext>
    <vm:DynamicFormViewModel/>
</UserControl.DataContext>

然后在我的XAML中包含一个元素作为表单的占位符:

<UserControl.Content>
    <view:DynamicFormView x:Name="CustomerEntry"/>
</UserControl.Content>

在我的ModelView中,我希望不要有静态属性,而是像在ASP.NET中构建HTML控件一样构建XAML,如下所示:

View view = new View();
view.Children.Add(...)

通过收集数据(名字,姓氏)和元数据(字段标签、字段名称、字段帮助文本、字段显示顺序等),ViewModel从Model获取这些信息并构建基于网格的形式。

  • 是否有人已经构建了一个WPF应用程序,可以以这种方式创建动态表单?
  • 您是否使用了MVVM模式?
  • 在MVVM模式中是否可以像这样使用,或者MVVM模式是否预设了在View Model中直接绑定到View中的静态元素的静态字段?
2个回答

9

您需要为各种字段数据类型编写数据模板,以便WPF根据其类型选择如何显示数据。格式如下:

注意:这不是WPF,仅为伪代码

<DataTemplate DataType="{x:Type DateTime}">
  <DatePicker Value="{Binding}"/>
</DataTemplate>  
<DataTemplate DataType="{x:Type String}">
  <TextBox Text="{Binding}"/>
</DataTemplate>

它不一定是一个原始类型。它可以是一个EmailDateApproved甚至是一个Url类类型。例如:

class Customer  
{
   public Email Email{get;set;}
   public DateTime DateApproved{get;set;}
   public URI Url{get;set;}
}

public class Email 
{
   public string Type{get;set;}
   public string Value{get;set;} 
} 

更新

在MSDN上查看这个WPF动态UI示例:使用WPF和LINQ进行动态数据输入


没错,但我想要包括自定义类型,例如电子邮件、URL、持续时间和客户等,因此每个类型都必须有自己的验证。我想象一个名为“CustomType”的基类,所有这些类型都继承它,并且每个类型都构建自己的方法,例如IsValid()和displayAsXaml()等。 - Edward Tanguay
将东西放在XAML中对我来说感觉太静态了。我记得在ASP.NET应用程序中,几乎每个项目都会有一个小小的Default.aspx,其中包含一些动态创建的控件。否则,您将创建一次性的静态应用程序,很难进行更改。我想为了从WPF中获得这种动态性,您也将只有一个小小的Window1.xaml,然后以同样的方式动态创建所有内容。 - Edward Tanguay
这篇文章似乎有些陈旧了。但我想在WPF 4.0中做类似的事情。WPF动态UI示例的链接似乎已经失效了。有人知道其他的示例吗? - Shakti Prakash Singh

1

你需要为每种字段类型(例如日期、字符串、布尔值)设置一个数据模板,以确定每个字段的显示方式。

然后,你可以使用数据库查询的列来生成对象列表,并将它们放入一个ItemsControl中。

ObservableCollection<ColumnDef> columns = new ObservableCollection<ColumnDef>();

// Add columns from DB
columns.Add(new StringColumnDef{Object=..., Field=..., Label=..., Value=...});
columns.Add(new DateColumnDef{Object=..., Field=..., Label=..., Value=...});

items.ItemsSource = columns; // items is an ItemsControl

每个项目控件将根据该类型的DataTemplate显示。
在ColumnDef内部,您可以使用反射来更新数据对象,以便从UI控件中进行更改。然后,当用户保存时,您可以将更改应用于数据库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接