2012-03-21 33 views
0

我在玩MVVM,瞭解模式中涉及的東西。我正在編寫的第一個應用程序是一個非常小的應用程序,它基本顯示App.Config中的兩個設置。使用ICommand將設置保存到App.Config中?

我的目標是能夠在單擊該按鈕時寫入此app.config。

我的問題在於我不確切地知道如何連接一個命令來委託這項工作,或者如果這是甚至要走的路。

我的App.config是非常簡單的:

<configuration> 
    <appSettings> 
    <add key="duration" value="100" /> 
    <add key="operators" value="10" /> 
    </appSettings> 
</configuration> 

這個模型看起來像:

get 
    { 
     // try to parse the setting from the configuration file 
     // if it fails return the default setting 0 
     int durationSetting = 0;     
     Int32.TryParse(ConfigurationManager.AppSettings["duration"], out durationSetting); 

     return durationSetting; 
    } 
    set 
    {     
     var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     config.AppSettings.Settings.Remove("duration"); 
     config.AppSettings.Settings.Add("duration", Convert.ToString(value)); 
     ConfigurationManager.RefreshSection("appSettings"); 
     config.Save();  
    } 
} 

因此,該模型是負責實際的數據訪問,這是我們想要的,對?

此外我有一個視圖模型(ViewModelBase實現INotifyPropertyChanged):

public class SettingsViewModel : ViewModelBase 
{ 
    private Settings Settings { get; set; } 

    private SaveCommand saveCommand = new SaveCommand(); 

    public ICommand SaveCommand 
    { 
     get 
     { 
      return saveCommand; 
     } 
    } 

    public SettingsViewModel(Settings settings) 
    { 
     if (settings == null) 
      throw new ArgumentNullException("Settings", "Settings cannot be null"); 
     Settings = settings; 
    } 

    public int Duration 
    { 
     get { return Settings.Duration; } 
     set 
     { 
      if (Settings.Duration != value) 
      { 
       Settings.Duration = value; 
       RaisePropertyChanged("Duration"); 
      } 
     } 
    } 

該視圖是XAML用戶控件,實例化是這樣的:

public partial class MainWindow : Window 
{ 
    public SettingsViewModel SettingsViewModel { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 

     Settings settings = new Settings(); 

     SettingsViewModel = new SettingsViewModel(settings); 
    } 
} 

最後有一個SaveCommand它實現的ICommand,這是在這一點上基本上是空的。我已將該命令連接到視圖中的按鈕。

但基本上,現在是什麼?處理值保存的最佳方法是什麼? 我工作的例子太過於人爲了嗎?

回答

1

我會推薦使用非常有用的MVVM Light toolkit

基本上,你將暴露返回RelayCommand實例的ICommand公共財產:

private RelayCommand myCommand; 

public ICommand MyCommand 
{ 
    get 
    { 
     return this.myCommand; 
    } 
} 

... 

// in constructor of the view model: 
this.myCommand = new RelayCommand(this.MyCommandImplementation); 

... 

private void MyCommandImplementation() 
{ 
    // Save your parameters here from your model 
} 

的東西在你的代碼奇怪的是,你實際上已經保存在名爲Duration公共setter方法設置。 你可以做什麼,而不是(從每個屬性被修改節省時間,防止)是簡單地使用私有變量在您的視圖模型:

private int duration; 
public int Duration 
{ 
    get { return this.duration; } 
    set 
    { 
     if (this.duration != value) 
     { 
      this.duration = value; 
      RaisePropertyChanged("Duration"); 
     } 
    } 
} 

所以當你修改UI字段綁定您的Duration屬性,只更新私人duration字段。因此,您只能將其保存到MyCommandImplementation方法中的app.config文件中。

private void MyCommandImplementation() 
{ 
    this.Settings.Duration = this.Duration; 
} 

另外請注意,您的Settings管理是一個有點複雜(刪除然後再添加一個設置,爲什麼?)。 最後一件事:在您看來,您當前正在將視圖本身用作datacontext。你必須,而不是指定您的視圖模型:

this.SettingsViewModel = new SettingsViewModel(settings); 
this.DataContext = this.SettingsViewModel; 

另外,我不認爲這是你的看法實例模型的作用。我將從ViewModel實例化Settings

+0

是的,因爲保存行爲,我想知道在這種情況下,命令是否是不必要的,我的例子太過於人爲設計了。 設置是這樣完成的,因爲似乎沒有編輯方法。 – fuaaark 2012-03-21 10:01:14

+0

@fuaaark嗯,這取決於你選擇你真正想要的東西。如果你的目標是「當按鈕被點擊時能夠寫入這個app.config」,那麼你需要一個按鈕和一個'ICommand'。如果你不需要一個按鈕,那麼只需保存到屬性設置器中的app.config文件,你就不需要'ICommand'。 – ken2k 2012-03-21 10:10:19

+0

我要使用該命令來實現它,以學習東西:)但是我可能會考慮一些SaveSettings()方法並從命令中調用該方法,以免用數據訪問邏輯來監視該命令。是對的嗎? – fuaaark 2012-03-21 10:14:21

0

您只需在類中實現ICommand接口並將SaveCommand屬性設置爲此類的實例即可。您可以使用一些第三方命令類,如棱鏡庫的DelegateCommand或RelayCommand。 請參閱以下網頁以獲取ICommand的示例實現; http://weblogs.asp.net/fredriknormen/archive/2010/01/03/silverlight-4-make-commanding-use-lesser-code.aspx

然後要採用的動作應該在命令中註冊;

this.SaveCommand= new SaveCommand((o) => 
     { 
      //change the model 
     }); 
+0

我在一個名爲「SaveCommand」的類中描述了我的問題狀態。 – fuaaark 2012-03-21 09:33:16