2016-10-14 3 views
0

xml 구성 파일이있는 wpf 응용 프로그램이 있습니다.WPF C# 바인딩 유효성 검사시 XML에 serialize

저는 MainWindow.xaml에 Binded 된 ViewModel 클래스를 만들었고 IDataErrorInfo 및 ValidationRule 클래스를 사용하여 일부 유효성 검사기를 만들고 있습니다.

사용자가 값을 변경하고 값이 유효성 검사를 통과하면 config 클래스가 xml로 serialize됩니다.

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)); 
    } 
} 

및 유효성 검사 규칙은 다음과 같습니다의 I 클래스 확장이 용으로 저장

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 예외가 발생합니다. 집합이 deserialize에서 호출되기 때문에 집합에서 serialize를 호출 할 수 있다고 생각합니다. 또한 속성이 데이터를 recive 할 때마다 set이 호출되지만 사용자가 데이터를 입력 할 때만 유효성 검사가 호출됩니다. – Mulflar

+0

사용자가 속성을 변경했는지 또는 프로그래밍 방식으로 속성을 변경해야하는지 구분해야하는 경우에는 두 가지 속성이 있어야합니다. 하나는 핵심 속성이고 다른 하나는 유효성 검사에 바인딩하기위한 것이고 두 번째는 첫 번째 래핑입니다. – Sergey

답변

0

확인을, I 해결되었지만 누군가가 더 좋은 옵션을 얻는다면 나는 매우 위대 할 것이다.

내가 한 것은 config 파일에 있으며, false로 시작하는로드 된 부울을 추가했으며,로드 된 사실이 true 인 경우에만 저장 함수에 조건을 추가했습니다.

[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; 
    } 
    [...] 
} 

내가 메인 창으로로드 이벤트를 추가하고, 해고 때 그것은 사실에로드 된 속성을 설정

는 config 클래스는 지금과 같다.

관련 문제