如何在基于WPF-MVVM(PRISM)的应用程序中在运行时构建表单。
要求就像用户应该能够在运行时添加文本框,复选框,组合框等控件。 添加crontol后,用户将保存表单,所有配置都将保存在数据库中。 因此,应用程序可以根据存储在数据库中的配置在运行时创建表单。
我们如何实现这一目标?
感谢。
答案 0 :(得分:2)
我做过类似的事情,但不是标准的UI控件。我有一系列代表"控件"我希望显示 - 在我的场景中,这些代表物理设备,如泵,阀门,开关,显示在机器和控制面板上,#34;用户可以配置。这些类继承自基类(称之为" HardwareItem"),它公开了所有控件共有的一些属性,例如:顶部,左侧,宽度,高度,工具提示等。
"设计师"
用户"设计的窗口"表单由以下组件组成: -
A&#34;工具箱&#34;,基本上是绑定到VM List<HardwareItem>
属性的ItemsControl,它暴露可用的HardwareItems(由VM的构造函数创建和填充)
画布,用户可以从工具箱中拖动项目。当发生丢弃时,我实例化相应的HardwareItem对象并将其添加到集合中(用于跟踪已添加的控件)。为了在画布上渲染控件,我创建了一个ContentControl
并设置了它的&#34; Source&#34;属性到HardwareItem对象,然后将其添加到放置位置的画布。使用我为每个HardwareItem类型创建的XAML DataTemplates呈现控件的可视化。
一个PropertyGrid控件(免费的Xceed工具包的一部分)。当用户在画布上选择一个控件时,相应的HardwareItem对象连接到PropertyGrid,允许用户设置其属性值(我使用自定义属性来控制哪些属性应该出现在网格中)。
< / LI>当用户点击&#34; save&#34;时,我基本上只是使用Json.Net将我的HardwareItem对象集合序列化为字符串,然后保存到文件中。
<强>&#34;运行&#34; 强>
为了渲染以前设计的表单,该文件被反序列化为一组HardwareItem对象,并以与上述几乎相同的方式添加到画布中。
使用标准WPF控件执行类似的操作不应该太不相似。您可以创建仅公开您希望用户操作的属性的类,例如: -
// Base class
public class MyControl
{
public double Top {get;set;}
public double Left {get;set;}
public double Width {get;set;}
public double Height {get;set;}
}
// TextBox
public class MyTextBox : MyControl
{
public string Text {get;set;}
}
// Button
public class MyButton : MyControl
{
public string Caption {get;set;}
public ICommand ClickCommand {get;set;}
}
DataTemplates看起来像这样: -
<DataTemplate DataType="{x:Type MyTextBox}">
<TextBox Text="{Binding Text}"
Width={Binding Width}" />
</DataTemplate>
<DataTemplate DataType="{x:Type MyButton}">
<TextBox Content="{Binding Caption}"
Width={Binding Width}"
Height={Binding Height}"
Command={Binding ClickCommand} />
</DataTemplate>
大部分画布操作都是在代码隐藏而不是VM中完成的。它是&nbsp;&#34; UI逻辑&#34;这是一种完全可以接受的方法。
这里根本没有使用Prism(我用它来浏览视图,但它并没有在这个&#34;表单设计器和功能中发挥作用。)