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

标签 c# wpf xml xaml xsd

这是场景。我们为我们的服务器产品之一使用大型 XML 配置文件。该文件布局合理,并针对 XSD 文件进行了验证。

现在是时候构建一个配置 GUI 来维护这个文件了,我想深入研究 WPF 来完成它。我可以为每个配置部分设计一个单独的表格,每次我们向配置文件添加一个选项时重构和重新分发,但我希望有一个更聪明的方法来做到这一点。

因为我已经有一个强类型的 xml/xsd 组合,我希望有一个优雅的方法来构建一个 UI 来足够容易地编辑它。我知道我可以编写一个 xml->xaml 转换,但我希望已经有一些东西可以帮我完成繁重的工作了吗?

提前致谢..

最佳答案

我会怎么做:

我将从构建一个简单的 View 模型类开始,该类环绕 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 对象,将该集合添加到窗口的 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}"/>

(注意:稍后,您可以花点心思,根据例如底层XmlElement 的数据类型定义OptionView 的子类。然后您可以定义DataTemplate 用于每个子类,只要每个子类都使用 SharedSizeGroup 在双列网格中显示项目,第二列可以包含日期选择器或单选按钮,或任何适合子类的内容,它们都会在运行时整齐地布置。)

一旦我开始工作(这不会花很长时间),我就会开始扩展 OptionView 类。例如,如果您的模式正在为 xs:annotation 元素中的元素存储人类可读的标签(如果不是,为什么不呢?),我会制作 Name 属性将其从 XmlElementSchemaInfo 属性中提取出来,而不是公开底层元素名称。

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

如果有大量的配置选项,并且您有一些智能的方法将它们分组到类别中,我会构建一个更高级别的类,它公开(至少)两个属性 - 一个字符串 CategoryName 属性和一个 OptionsViews 集合 - 从 XML 文档填充它,并将它添加到窗口的 ResourceDictionary。在窗口内,我会将其绑定(bind)到 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>

或者某些项目控件,其项目容器模板创建了一个 Expander。或者其他的东西。 (保证所有代码都未经测试!不过,其中大部分是从工作项目中复制的。)

如果您以前没有使用过 WPF,那么这是一个非常好的入门项目。它将向您展示数据绑定(bind)和项目控制和验证的基础知识,最终结果将是有用的并且可能看起来不错。

您会注意到,虽然创建模板所涉及的标记非常冗长,但只有两个模板。应用程序中唯一的代码(到目前为止)是将 XmlElement 暴露给 UI 的代码。

关于c# - 基于模式为 XML 文件创建 WPF 编辑器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1922604/

相关文章:

c# - UserControl 与模型的绑定(bind) - "property not found"

java - 在 Java 中解析 XML 符号

c# - Twitter API 在调用 account/verify_credentials.json 时返回 215 Bad Authentication Data

c# - 在 C# 中反序列化 Open Street Map JSON

c# - .NET 计时器,它们是在准确的时间间隔触发还是在处理 + 间隔后触发

wpf - 将 WPF 控件调整为精确的百分比

C#、NUnit : How to deal with testing of exceptions and deferred execution

c# - 有没有办法刷新 WPF 中的所有绑定(bind)?

ASP.NET 无法使用带有命名空间管理器的 SelectSingleNode 方法选择节点

javascript - 读取 xml 文件,修改值/添加元素/属性并保存 xml 如何?