WPF 分享一種設置程序保存配置文件的方法


最近需要做一個配置程序,主要給其他程序做相關配置的小工具。

配置項蠻多的,一般我們都是將各個配置項寫到配置文件的節點中,比如App.config文件或者自定義的xml文件。

因為我用的是wpf,MVVM,所以其實界面上的所有數據我都存着ViewModel的實體屬性中。比如我們新建一個Model,叫SettingModel,界面上不管做任何更改,其實數據都和SettingModel中一樣。

我們將這個SettingModel的內存數據序列化到本地文件。等下次運行程序時,再去反序列化將SettingModel的數據加載到ViewModel中。

  public class SettingModel:ObservableObject
    {
        private string _FConnStr;

        public string FConnStr
        {
            get { return _FConnStr; }
            set { _FConnStr = value; RaisePropertyChanged("FConnStr"); }
        }


        private string _DBType;

        public string DBType
        {
            get { return _DBType; }
            set { _DBType = value; RaisePropertyChanged("DBType"); }
        }

        private string _SupplierName;

        public string SupplierName
        {
            get { return _SupplierName; }
            set { _SupplierName = value; RaisePropertyChanged("SupplierName"); }
        }

        private string _SupplierNo;

        public string  SupplierNo
        {
            get { return _SupplierNo; }
            set { _SupplierNo = value; RaisePropertyChanged("SupplierNo"); }
        }

        private List<ComboxModel> _SQLList;

        public List<ComboxModel> SQLList
        {
            get { return _SQLList; }
            set { _SQLList = value; RaisePropertyChanged("SQLList"); }
        }

        private string _StartTime;

        public string StartTime
        {
            get { return _StartTime; }
            set { _StartTime = value; RaisePropertyChanged("StartTime"); }
        }

        private string _EndTime;

        public string EndTime
        {
            get { return _EndTime; }
            set { _EndTime = value; RaisePropertyChanged("EndTime"); }
        }

        private int _Rate;

        public int Rate
        {
            get { return _Rate; }
            set { _Rate = value; RaisePropertyChanged("Rate"); }
        }

        private DateTime _TransmissionDate;

        public DateTime TransmissionDate
        {
            get { return _TransmissionDate; }
            set { _TransmissionDate = value; RaisePropertyChanged("TransmissionDate"); }
        }

        private string _ServiceAddress;

        public string ServiceAddress
        {
            get { return _ServiceAddress; }
            set { _ServiceAddress = value; RaisePropertyChanged("ServiceAddress"); }
        }

    }
View Code

序列化和反序列化方法

       public static void MySerialize<T>(T s)
        {
            FileStream fileStream = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "/Config/config.dat", FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(fileStream, s);
            fileStream.Close();

        }
        //T 可以是類型    
        public static T MyBackSerialize<T>(string path)
        {
            FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryFormatter formatter = new BinaryFormatter();
            T s = (T)formatter.Deserialize(fileStream);
            fileStream.Close();
            return s;
        }

但是實行過程中遇到個問題,因為使用了MVVM,Model都實現了INotifyPropertyChanged接口。但是序列化的時候不可以序列化。

於是我們需要再添加一個Model,結構和SettingModel一樣,但是不實現INotifyPropertyChanged接口。

 [Serializable]
    public class SettingModelBack
    {
        private string _FConnStr;

        public string FConnStr
        {
            get { return _FConnStr; }
            set { _FConnStr = value;}
        }


        private string _DBType;

        public string DBType
        {
            get { return _DBType; }
            set { _DBType = value;}
        }

        private string _SupplierName;

        public string SupplierName
        {
            get { return _SupplierName; }
            set { _SupplierName = value; }
        }

        private string _SupplierNo;

        public string SupplierNo
        {
            get { return _SupplierNo; }
            set { _SupplierNo = value;  }
        }

        private List<ComboxModelBack> _SQLList;

        public List<ComboxModelBack> SQLList
        {
            get { return _SQLList; }
            set { _SQLList = value; }
        }

        private string _StartTime;

        public string StartTime
        {
            get { return _StartTime; }
            set { _StartTime = value; }
        }

        private string _EndTime;

        public string EndTime
        {
            get { return _EndTime; }
            set { _EndTime = value; }
        }

        private int _Rate;

        public int Rate
        {
            get { return _Rate; }
            set { _Rate = value;  }
        }

        private DateTime _TransmissionDate;

        public DateTime TransmissionDate
        {
            get { return _TransmissionDate; }
            set { _TransmissionDate = value; }
        }


        private string _ServiceAddress;

        public string ServiceAddress
        {
            get { return _ServiceAddress; }
            set { _ServiceAddress = value; }
        }
    }
View Code

此Model類上添加 [Serializable]標記。

這樣我們在保存時,需要將SettingModel的數據賦給SettingModelBack,我們可以用AutoMapper來實現,很方便。

   private void Save()
        {
            var config = AutoMapper.Mapper.Map<SettingModelBack>(Master);

            MySerialize<SettingModelBack>(config);

            dialogCoordinator.ShowMessageAsync(this, "", "保存成功!");
        }

我們在應用程序中,想讀取配置文件中的信息,我們可以反序列化配置文件,將數據還原到Model中。

 string path = AppDomain.CurrentDomain.BaseDirectory + "/Config/config.dat";

 var configData= MyBackSerialize<SettingModelBack>(path);

這種保存配置文件的方式,有個好處就是如果有新的配置項需要保存,我們只需要在Model中添加相應的屬性,並綁定到界面上(WPF本來也需要做這個事),而不需要再去寫創建新節點,修改新節點的代碼。但是也有個不方便的地方,就是不可以在文本中修改配置文件了,只能通過配置工具修改,因為保存到本地config.dat中的文件打開后是亂碼了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM