WPF 分享一種設定程式儲存配置檔案的方法
阿新 • • 發佈:2018-11-22
最近需要做一個配置程式,主要給其他程式做相關配置的小工具。
配置項蠻多的,一般我們都是將各個配置項寫到配置檔案的節點中,比如App.config檔案或者自定義的xml檔案。
因為我用的是wpf,MVVM,所以其實介面上的所有資料我都存著ViewModel的實體屬性中。比如我們新建一個Model,叫SettingModel,介面上不管做任何更改,其實資料都和SettingModel中一樣。
我們將這個SettingModel的記憶體資料序列化到本地檔案。等下次執行程式時,再去反序列化將SettingModel的資料載入到ViewModel中。
public classView CodeSettingModel: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"); } } }
序列化和反序列化方法
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中的檔案開啟後是亂碼了。