WPF c#在绑定验证上序列化为XML是正确的

本文关键字:XML 序列化 绑定 验证 WPF | 更新日期: 2023-09-27 18:12:59

我有一个带有xml配置文件的wpf应用程序。

我做了一个ViewModel类谁是绑定到主窗口。我正在使用IDataErrorInfo和ValidationRule类制作一些验证器。

我想要的是,如果用户更改了一个值,并且该值通过了验证,则配置类被序列化为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);
        }
    }
}

WPF c#在绑定验证上序列化为XML是正确的

好吧,我解决了,但如果有人得到更好的选择,我会非常感激。

我所做的是在配置文件中添加了一个加载的布尔值,该布尔值从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;
    }
    [...]
}

我在主窗口添加了一个loaded事件,当它被触发时,它将loaded属性设置为true