2016-10-14 4 views
0

xml構成ファイルを持つwpfアプリケーションがあります。WPF C#バインディング検証でXMLにシリアライズすると正しい

私はMainWindow.xamlにバインドされたViewModelクラスを作成しました。IDataErrorInfoとValidationRuleクラスを使用していくつかのバリデータを作成しています。

私が欲しいのは、ユーザーが値を変更し、値が検証に合格すると、configクラスはxmlにシリアル化されます。

public static class ConfiguracionExtension 
{ 
    public static void Save(this Configuration configXML) 
    { 
     string ConfigPath = AppDomain.CurrentDomain.BaseDirectory + "config.xml"; 
     XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
     XmlSerializer serializer = new XmlSerializer(typeof(Configuration)); 
     Stream writer = new FileStream(ConfigPath, FileMode.Create); 
     ns.Add("", ""); 
     serializer.Serialize(writer, configXML, ns); 
     writer.Close(); 
    } 
} 

は、コンフィギュレーションクラスは、次のようになります:

[Serializable, XmlRoot("configuration")] 
public class Configuration : IDataErrorInfo, INotifyPropertyChanged 
{ 
    private int _minute; 
    [XmlElement] 
    public int minute 
    { 
     get 
     { 
      return _minute; 
     } 
     set 
     { 
      _minute = value; 
      OnPropertyChanged("minute"); 
     } 
    } 
    public static Configuration Load() 
    { 
     string ConfigPath= AppDomain.CurrentDomain.BaseDirectory + "config.xml"; 
     if (File.Exists(ConfigPath)) 
     { 
      try 
      { 
       XmlSerializer _s = new XmlSerializer(typeof(Configuration)); 
       return (Configuration)_s.Deserialize(new XmlTextReader(ConfigPath)); 
      } 
      catch (Exception ex) 
      { 
       Auxiliar.writeError(ex.ToString()); 
       return new Configuration(); 
      } 
     } 
     else 
      return new Configuration(); 
    } 
    public Configuracion() 
    { 
     minutes = 60; 
    } 
    #region IDataErrorInfo Members 
    public string Error 
    { 
     get { return String.Empty; } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
      String errorMessage = String.Empty; 
      switch (columnName) 
      { 
       case "minute": 
        if (minute < 1) 
        { 
         errorMessage = "minutes can't be less than 1"; 
        } 
        break; 
      } 
      return errorMessage; 
     } 
    } 
    #endregion 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(String propertyName) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

と検証ルールは次のようになります。

public class MinutesValidation : ValidationRule 
{ 
    private int _min; 
    public int Minimum 
    { 
     get { return _min; } 
     set { _min = value; } 
    } 
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 
    { 
     int minute; 
     Boolean noIllegalChars; 
     noIllegalChars = int.TryParse(value.ToString(), out minute); 

     if (value.ToString().Length < 1) 
     { 
      return new ValidationResult(false, "Value can't be empty"); 
     } 
     else if (noIllegalChars == false) 
     { 
      return new ValidationResult(false, "Ilegal Character"); 
     } 
     else 
     { 
      return new ValidationResult(true, null); 
     } 
    } 
} 
+0

問題が何であるかは不明です。変更されたプロパティのセッターで保存を呼び出すことができないのはなぜですか? – Sergey

+0

System.Windows.Markup.XamlParseException例外が発生しました。セットがデシリアライズ時に呼び出されるため、セットでシリアル化を呼び出すことができます。また、プロパティはデータを受け取るたびに呼び出されますが、検証はユーザーがデータを入力したときにのみ呼び出されます。 – Mulflar

+0

プロパティがユーザーによって変更されたのかプログラムによって変更されたのかを区別する必要がある場合は、おそらく2つのプロパティが必要です。 1つはコアプロパティ、もう1つは検証とのバインディング、もう1つは最初のラップです。 – Sergey

答えて

0

[OK]を、私、私はクラスの拡張子を持って保存するために

解決されますが、誰かがより良い選択肢を得るなら、私は非常に素晴らしいでしょう。

私が行ったことは、設定ファイルにあります。私はfalseで始まるロードされたブール値を追加しました。そして、ロードされた場合にのみ動作するように保存関数に条件を追加しました。今

のconfigクラスは、このようなものです:

[Serializable, XmlRoot("configuration")] 
public class Configuration : IDataErrorInfo, INotifyPropertyChanged 
{ 
    private int _minute; 
    [XmlElement] 
    public int minute 
    { 
     get 
     { 
      return _minute; 
     } 
     set 
     { 
      _minute = value; 
      this.Save(); 
      OnPropertyChanged("minute"); 
     } 
    } 
    [XmlIgnore] 
    public bool loaded; 

    public static Configuration Load() 
    { 
    string ConfigPath= AppDomain.CurrentDomain.BaseDirectory + "config.xml"; 
    if (File.Exists(ConfigPath)) 
    { 
     try 
     { 
      XmlSerializer _s = new XmlSerializer(typeof(Configuration)); 
      var tempConf = (Configuracion)_s.Deserialize(new XmlTextReader(ConfigPath)); 
      tempConf.loaded = false; 
      return tempConf; 
     } 
     [...] 
    } 
    public Configuracion() 
    { 
     loaded = false; 
     minutes = 60; 
    } 
    [...] 
} 

私は、メインウィンドウにロードされたイベントを追加し、それは解雇だときには、trueにロードされたプロパティを設定します。

関連する問題