3

私は、カスタマイズ可能なUIを表示するためにXamlReaderを使用してXAMLフラグメントをオンザフライでロードするac#(理由が見つかった場合は3.5または4)WPFアプリケーションを作成しています。このUIは、表示される前にXmlDataProviderにバインドされており、うまく機能しているようです。

データソース(XMLドキュメントを指すXmlDataProvider)がドキュメントのXSDスキーマに対して自動的に検証されるようにすることが可能かどうかを調べようとしていますか?

明確にするために-アプリケーションの性質が変更可能であるため、カスタム検証ルールの記述を避けようとしています。XSDスキーマには、Winformsエラープロバイダーと同様の方法でUIが応答するように指定された制限(正規表現や最大長の制約など)があります。

どんな助けでもいただければ幸いです!

(ちなみに-XmlDataProviderでタグ付けされていたはずですが、レピュテーション要求のために新しいタグを作成できません)

4

1 に答える 1

3

私は同様の問題に取り組んでいました.XAMLをオンザフライでロードし、ユーザー入力を検証しています。しかし、私の状況では、グローバルがDataContextあり、すべての読み込みコントロールがそのコンテキストにバインドされています。バリデーションアクションを実行する時、例えばユーザーが入れたボタン「validate」のデータDataContextをXMLにシリアライズした後、このXMLからエラータグを取得するのにXSLTを使いましたが、そのXSDでシリアライズできるならXSDを使っても良いと思いますDataContext

私の手順:

  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 スキーマに何らかの制約があると、データを に配置するときにステップ 4 でエラーが発生しますDataTable

于 2013-02-02T09:10:02.190 に答える