基于模式为XML文件创建WPF编辑器

Fer*_*ran 10 c# xml wpf xaml xsd

这是场景.我们为我们的某个服务器产品使用大型XML配置文件.此文件布局相当好,并根据XSD文件进行验证.

现在是时候构建一个用于维护此文件的配置GUI,我想深入研究WPF来实现它.我可以为每个配置部分布置一个单独的表单,每次我们在配置文件中添加一个选项时重构和重新分发,但我希望有一个更聪明的方法来做到这一点.

由于我已经有一个强类型的xml/xsd组合,我希望有一种优雅的方法来构建一个UI来轻松编辑它.我知道我可以编写一个xml-> xaml转换,但希望有一些东西可以帮我完成繁重的工作吗?

提前致谢..

Rob*_*ney 12

我怎么做的:

我首先构建一个简单的视图模型类,它包装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; }
   }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以填充一个ElementView对象的集合XmlDocument,将该集合添加到窗口ResourceDictionary,并使用一个简单的格式化对象DataTemplate,例如:

<DataTemplate x:Key="OptionViewTemplate" DataType={x:Type local:OptionView}>
   <Grid>
       <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="Name"/>
          <ColumnDefinition SharedSizeGroup="Value"/>
       </Grid.ColumnDefinitions>
       <Label Content="{Binding Name}" Grid.Column="0"/>
       <TextBox Text="{Binding Value}" Grid.Column="1"/>
   </Grid>
</DataTemplate>
...
<ItemsControl Grid.IsSharedSizeScope="True"
    ItemsSource="{DynamicResource OptionCollection}"/>
Run Code Online (Sandbox Code Playgroud)

(注意:稍后,您可以获得花哨,并OptionView根据例如底层的数据类型定义子类XmlElement.然后您可以DataTemplate为每个子类定义s,并且只要每个子项在两列网格中呈现使用它SharedSizeGroup,第二列可以包含日期选择器,或单选按钮,或适合子类的任何内容,并且它们将在运行时整齐地布局.)

一旦我开始工作,这不会花费很长时间,我会开始扩展OptionView课程.例如,如果你的模式为元素中的xs:annotation元素存储了一个人类可读的标签(如果不存在,为什么不呢?),我会将Name属性提取出来XmlElementSchemaInfo属性,而不是暴露底层元素名称.

显然我想添加验证,所以我添加一个验证方法来检查它XmlElementSchemaInfo属性并解释它.(假设你要验证的元素是简单的内容,那应该不会很难.)有关于如何在WPF应用程序中实现验证的百万篇教程,所以我不会在这里详细介绍.

如果有大量的配置选项,并且您有一些智能的方法将它们分组到类别中,我将构建一个更高级别的类,它暴露(至少)两个属性 - 字符串CategoryName属性和OptionsViews集合 - 从XML文档中填充它,并将其添加到窗口中ResourceDictionary.在窗口中,我将它绑定到a TabControl,例如:

<TabControl ItemsSource="{DynamicResource OptionCategories}">
   <TabControl.ItemContainerStyle>
      <Style TargetType="{x:Type CategoryView}">
         <Setter Property="Header" Value="{Binding Path=CategoryName}"/>
         <Setter Property="Content" Value="{Binding Path=OptionsViews}"/>
         <Setter Property="ContentTemplate" Value="{StaticResource OptionViewTemplate}"/>
      </Style>
   </TabControl.ItemContainerStyle>
</TabControl>
Run Code Online (Sandbox Code Playgroud)

或者对项目容器模板创建的项目控件Expander.或者其他的东西.(所有代码都保证未经测试!但大多数代码都是从工作项目中复制出来的.)

如果您以前没有对WPF做过任何事情,这是一个非常好的项目.它将向您展示数据绑定和项目控制和验证的基础知识,最终结果将是有用的,可能看起来很不错.

您会注意到,虽然创建模板所涉及的标记非常详细,但只有两个模板.应用程序中唯一的代码(到目前为止)是将XmlElements 公开给UI 的代码.