2012-03-21 2 views
0

MVVM을 가지고 놀고있어 패턴과 관련된 내용을 알게되었습니다. 필자가 작성한 첫 번째 응용 프로그램은 기본적으로 App.Config에서 2 개의 설정을 표시하는 아주 작은 응용 프로그램입니다.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();  
    } 
} 

그래서,이 모델이 실제 데이터 액세스에 대한 책임이 우리가 원하는 것입니다, 권리?

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

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

     Settings settings = new Settings(); 

     SettingsViewModel = new SettingsViewModel(settings); 
    } 
} 

가 마지막으로 ICommand의를 구현하는 SaveCommand을 거기에있다 :

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의 UserControl을이다 :

는 또한 내가 뷰 모델은 (ViewModelBase가에서 INotifyPropertyChanged를 구현)이 이 시점에서 기본적으로 비어 있습니다. 보기의 단추에 명령을 연결했습니다.

하지만 기본적으로 지금은 무엇이 있습니까? 값을 저장하는 가장 좋은 방법은 무엇입니까? 제가 작업 한 예가 너무 고심 했습니까?

답변

1

나는 MVVM Light toolkit 매우 유용한를 사용하는 것이 좋습니다 것입니다. 코드에서 이상한

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라는 이름의 공공 재산의 세터의 설정을 저장하는 것이된다

기본적으로

, 당신은 RelayCommand의 인스턴스를 반환하는 ICommand 공용 속성을 노출합니다 . 당신은 (속성이 변경 될 때마다 저장하는 것을 방지하기 위해) 단순히 당신의 ViewModel의 개인 변수를 사용하는 대신에 무엇을 할 수 있는지 : 당신이 UI 필드가 Duration 속성에 바인더 제본 수정할 때 그래서

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

, 당신 비공개 duration 필드 만 업데이트하십시오. 따라서 MyCommandImplementation 메서드의 app.config 파일에만 저장됩니다.

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

또한 Settings 관리가 복잡 조금 (당신이 다음, 왜 다시 설정을 추가, 제거?)입니다 있습니다. 마지막 사항 :보기에서 현재보기 자체를 datacontext로 사용하고 있습니다. 대신 당신의 ViewModel을 지정해야합니다 :

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

은 또한, 나는이 모델을 인스턴스화하는보기의 역할을 생각하지 않습니다. 대신 ViewModel에서 Settings을 인스턴스화합니다.

+0

그래, 저축 행위 때문에 나는이 명령이 불필요한 명령인지 궁금해했다. 내 예제가 너무 고심했다. 편집 방법이 없기 때문에 설정이 이와 같이 이루어집니다. – fuaaark

+0

@fuaaark 글쎄, 당신이 실제로 원하는 것을 선택하는 것은 당신에게 달려 있습니다. 목표가 "버튼을 클릭 할 때이 app.config에 쓸 수 있도록하려면"버튼과 'ICommand'가 필요합니다. 버튼이 필요 없다면, 단순히 속성 setter의 app.config 파일에 저장하면'ICommand'는 필요 없습니다. – ken2k

+0

나는 그것을 배우기 위해 명령을 사용하여 구현할 것이다. :)하지만 데이터 액세스 로직을 사용하여 명령을 폴링하지 않도록 명령에서 일부 SaveSettings() 메서드를 인수로 호출해야합니다. 그게 맞습니까? – fuaaark

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

관련 문제