3

我正在编写 ac#(如果我找到原因,则为 3.5 或 4)WPF 应用程序,它使用 XamlReader 动态加载 XAML 片段以显示可自定义的 UI。此 UI 在显示之前已绑定到 XmlDataProvider,并且似乎工作得很好。

我一直在尝试找出是否可以让数据源(指向 XML 文档的 XmlDataProvider)自动验证文档的 XSD 架构?

澄清一下 - 由于应用程序的多变性质,我试图避免编写任何自定义验证规则。XSD 架构具有指定的限制(例如正则表达式或最大长度约束),我希望我的 UI 以与 Winforms 错误提供程序类似的方式响应这些限制。

任何帮助,将不胜感激!

(顺便说一句 - 将使用 XmlDataProvider 进行标记,但由于信誉请求而无法创建新标记)

4

1 回答 1

3

我遇到了类似的问题:动态加载 XAML 并验证用户输入。但在我的情况下,我有一个全局DataContext并且所有加载控件都绑定到该上下文。当执行验证操作时,例如用户放置按钮“验证”数据,DataContext序列化为 XML,然后我使用 XSLT 从这个 XML 获取错误标签,但我认为如果你可以序列化DataContext该 XSD,你可以使用 XSD。

我的步骤:

  1. 加载 Xaml 并将我的对象设置为容器DataContext

    String xaml="some xaml";
    MyData myData=new MyData();
    TextReader textReader = new StringReader(CardContext.Xaml);
    XmlReader xmlReader = XmlReader.Create(textReader);
    //setting DataContext for panel named 'content'
    this.content.DataContext = myData;
    FrameworkElement myContent = (FrameworkElement) XamlReader.Load(xmlReader);
    this.content.Children.Clear();
    this.content.Children.Add(myContent);
    InitMyComponents(this.content);
    
  2. xaml 中的控件绑定到 DataContext。DataContext 是类 MyData 像这样:

    public class MyData
    {
        IDictionary<String, MyControl> MyControls{get;set;}
        ....
    }
    

    在哪里

    class MyControl
    {
       String Id{get;set;}
       String Name{get;set;}
       String Value{get;set;}
    }
    

    获取控件的绑定

    public static  Binding GetValueBinding(MyControl control)
    {
       Binding valueBinding = new Binding();
       valueBinding.Mode = BindingMode.TwoWay;
       valueBinding.Path = new PropertyPath("MyControls["+control.Id+"].Value");
       return valueBinding;
    }
    
  3. 用户使用控件并更改某些值。

  4. 当用户需要验证时,我将数据放入名为 MyMetaData 的 XSD 模式中(在该模式中,我有表 MyControls)。

    MyMetaData _myMetaData;
    
    public void PushData(MyData myData)
        {
    
            foreach (MyControl control in myData.MyControls)
            {
             //fill table from xsd schema
       this._myMetaData.MyControls.AddMyControlsRow(control.Id,control.Name,control.Value);
    
    
            }
    
            this._myMetaData.AcceptChanges();
        }
    
  5. 从 DataTable 获取 XML

    this._myMetaData.MyControls.GetXml()
    
  6. 使用 xslt 验证 XML

    XslCompiledTransform xslCompiledTransform = new XslCompiledTransform(); 
    String xml = "some xml";
    TextReader textReader = new StringReader(xml );
    XmlReader xmlReader = XmlReader.Create(textReader);
    StringBuilder validationResult = new StringBuilder();
    XmlWriter xmlWriter = XmlWriter.Create(validationResult);
    //aply xslt (xslt return tags with error description and control Id)
    xslCompiledTransform.Transform(xmlReader, xmlWriter);
    //parsing result tags
    IList<ValidationError> parsedResult = ParseValidationResult(validationResult.ToString());
    
  7. 查找显示错误信息的控件和执行方法

    DependencyObject errorSource = LogicalTreeHelper.FindLogicalNode(this.content, error.Identifier);
    if (errorSource == null)
        return;
    if (errorSource is MyControl)
       (errorSource as MyControl).ShowErrorInfo(error.ErrorText);
    

这是我的算法,但如果您对 XSD 架构有一些限制,当您将数据放入DataTable.

于 2013-02-02T09:10:02.190 回答