基于模式为XML文件创建WPF编辑器
这是场景。 我们为我们的某个服务器产品使用大型XML配置文件。 此文件布局合理,并针对XSD文件进行validation。
现在是时候构建一个用于维护此文件的配置GUI,我想深入研究WPF来实现它。 我可以为每个配置部分布置一个单独的表单,每次我们在配置文件中添加一个选项时重构和重新分发,但我希望有一个更聪明的方法来做到这一点。
由于我已经有一个强类型的xml / xsd组合,我希望有一种优雅的方法来构建一个UI来轻松编辑它。 我知道我可以编写一个xml-> xaml转换,但希望有一些东西可以帮我完成繁重的工作吗?
提前致谢..
我怎么做的:
我首先构建一个包含XmlElement
的简单视图模型类,并将其作为配置选项公开。 这个类可以非常简单,例如:
public class OptionView { private XmlElement XmlElement; public OptionView(XmlElement xmlElement) { XmlElement = xmlElement; } public string Name { get { return XmlElement.Name; } } public string Value { get { return XmlElement.InnerText; } set { XmlElement.InnerText = value; } } }
现在我可以从XmlDocument
填充ElementView
对象的集合, ElementView
集合添加到窗口的ResourceDictionary
,并使用简单的DataTemplate
格式化对象,例如:
...
(注意:稍后,您可以获得幻想,并根据例如底层XmlElement
的数据类型定义OptionView
的子类。然后您可以为每个子类定义DataTemplate
,并且只要每个子项呈现两个项目- 使用该SharedSizeGroup
列网格,第二列可以包含日期选择器,或单选按钮,或适合子类的任何内容,并且它们都将在运行时整齐地布局。)
一旦我完成了工作,这将花费很长时间,我将开始扩展OptionView
类。 例如,如果你的模式为xs:annotation
元素中的元素存储了一个人类可读的标签(如果不存在,为什么不呢?),我会让Name
属性从XmlElement
提取出来。 SchemaInfo
属性,而不是公开底层元素名称。
显然我想添加validation,所以我添加了一个validation方法来检查XmlElement
的SchemaInfo
属性并解释它。 (假设你要validation的元素是简单的内容,那应该不会很难。)有关于如何在WPF应用程序中实现validation的百万篇教程,所以我不会在这里详细介绍。
如果有大量的配置选项并且你有一些智能的方法将它们分组到类别中,我将构建一个更高级别的类,它暴露(至少)两个属性 – 一个字符串CategoryName
属性和一个OptionsViews
集合 – 从XML填充它将文档添加到窗口的ResourceDictionary
。 在窗口中,我将它绑定到TabControl
,例如:
或者某个项目控件,其项目容器模板创建一个Expander
。 或者其他的东西。 (所有代码都保证未经测试!但大多数代码都是从工作项目中复制出来的。)
如果您以前没有对WPF做过任何事情,那么这是一个非常好的项目。 它将向您展示数据绑定和项目控制和validation的基础知识,最终结果将是有用的,可能看起来很不错。
您会注意到,虽然创建模板所涉及的标记非常详细,但只有两个模板。 应用程序中唯一的代码(到目前为止)是将XmlElement
公开给UI的代码。
在这里,我们根据您的要求创建了一个。 通过记住WPF完全创建此工具。
不是WPF,而是非常有启发性 – 由Marc Clifton创建的动态生成的XML数据编辑器
一篇包含windows表单源代码的文章,关于创建用于编辑基于XSD的XML的GUI。
一直在寻找类似的东西。
要呈现简单的xml配置(如果不需要值的自定义编辑器),可以使用HierarchicalDataTemplate直接将XElement绑定到视图。
XAML:
查看模型:
class ConfigViewModel:INotifyPropertyChanged { public XElement Xml { get; private set;} //example of persistence infrastructure public event PropertyChangedEventHandler PropertyChanged = delegate { }; public void Load(string fileName) { Xml = XElement.Load(fileName); PropertyChanged(this, new PropertyChangedEventArgs("Xml")); } public void Save(string fileName) { Xml.Save(fileName); } }
反向bool到可见性转换器有一些很好的例子。