【问题标题】:How to build dynamic data entry forms in a WPF application?如何在 WPF 应用程序中构建动态数据输入表单?
【发布时间】:2009-04-24 13:46:37
【问题描述】:

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

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

我打算这样做:在客户数据输入视图中,我将设置数据上下文:

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

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

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

然后在我的 ModelView 中我不想有静态属性,但我想以这种方式将 XAML 构建为 ASP.NET 中的一个内置 HTML 控件:

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

并以这种方式基于 ViewModel 从 Model 获取的数据(名字、姓氏)和元数据(字段标签、字段名称、字段帮助文本、字段显示顺序等)的集合构建 Grid。

  • 是否有人构建了可以以这种方式创建动态表单的 WPF 应用程序?
  • 您使用过 MVVM 模式吗?
  • 是否可以以这种方式使用 MVVM 模式,或者 MVVM 模式是否预先假定 View Model 中的静态字段直接绑定到 View 中的静态元素?

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    您必须为各种字段数据类型编写数据模板,以便 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 示例:Dynamic Data Entry with WPF and LINQ

    【讨论】:

    • 对,但我想包含自定义类型,例如电子邮件、URL、持续时间、客户,因此每个类型都必须有自己的验证。我在想象一个名为“CustomType”的基础,所有这些类型都继承了它,并且每个都构建了自己的方法,例如IsValid() 和 displayAsXaml() 等
    • 把东西放在 XAML 中给我的感觉是静态的。我记得在 ASP.NET 应用程序中,几乎在每个项目中,您最终都会有一个很小的 ​​Default.aspx,其中包含几个控件,这些控件都是动态创建的。否则,您将创建一次性的静态应用程序,这些应用程序不能很容易地更改。我想要从 WPF 中获得这种动态特性,您还将拥有一个很小的 ​​Window1.xaml,然后以相同的方式动态创建所有内容。
    • 这篇文章似乎很旧。但我想在 WPF 4.0 中做类似的事情。 WPF 动态 UI 示例的链接似乎已损坏。有人知道另一个例子吗?
    【解决方案2】:

    您需要为每个字段类型(例如 Date、String、Bool)设置一个 DataTemplate。这将决定每个字段的显示方式。

    然后,您可以使用数据库查询的列来生成对象列表并将它们放入 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 控件的更改来更新数据对象。然后,您可以在用户保存时将更改应用到数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2013-04-11
      • 2012-02-23
      • 2019-04-19
      相关资源
      最近更新 更多