2012-09-12 1 views
3

이것은 중복 된 질문 일 수 있지만 문제에 대한 해결책을 찾을 수 없습니다.MVVM을 사용하는 BusyIndicator

MVVM 패턴을 사용하는 WPF 응용 프로그램에서 작업하고 있습니다.

ViewModel에 바인드 된 4 개의 뷰가 있습니다. 모든 ViewModel은 BaseViewModel을 부모로가집니다. 내가 MainViewModel에서 IsBusy = true를 설정하면

<extWpfTk:BusyIndicator IsBusy="{Binding IsBusy}"> 
     <ContentControl /> 
    </extWpfTk:BusyIndicator> 

, BusyIndicator가 표시됩니다 :

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    private bool isbusy; 

    public bool IsBusy 
    { 
     get 
     { 
      return isbusy; 
     } 
     set 
     { 
      isbusy = value; 
      RaisePropertyChanged("IsBusy"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void RaisePropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

MAINVIEW는 BusyIndicator가 포함되어 있습니다.

다른 ViewModels에서 IsBusy = true로 설정하려고하면 BusyIndicator가 표시되지 않습니다.

MVVMLight와 같은 타사 라이브러리를 사용하여 메신저를 사용하여 ViewModels간에 통신 할 수는 없습니다.

MAINVIEW :

public class MainWindowViewModel : ViewModelBase 
{ 
    public ViewModel1 ViewModel1 { get; set; } 
    public ViewModel2 ViewModel2 { get; set; } 
    public ViewModel3 Model3 { get; set; } 

    public MainWindowViewModel() 
    { 
     ViewModel1 = new ViewModel1(); 
     ViewModel2 = new ViewModel2(); 
     ViewModel3 = new ViewModel3(); 
     //IsBusy = true; - its working 
    } 
} 

ViewModel1 : 모든 viewModels에

public class ViewModel1 : ViewModelBase 
{ 
    RelayCommand _testCommand; 

    public ViewModel1() 
    { 
    } 

    public ICommand TestCommand 
    { 
     get 
     { 
      if (_testCommand == null) 
      { 
       _testCommand = new RelayCommand(
        param => this.Test(), 
        param => this.CanTest 
        ); 
      } 
      return _testCommand; 
     } 
    } 

    public void Test() 
    { 
     //IsBusy = true; - BusyIndicator is not shown 

    } 

    bool CanTest 
    { 
     get 
     { 
      return true; 
     } 
    } 
} 
+0

FYI MVVMLight는 오픈 소스이므로 Messenger 구현 만 추출하고 나머지는 무시할 수 있습니다. 솔루션에 직접 소스가 포함되어 있으므로 타사 라이브러리가 필요하지 않습니다. –

+0

@ AdamHouldsworth 글쎄, 어떤 이유로 MVVMLight에서 WeakReference 클래스를 사용하려고 할 때 SecurtyException이 발생했습니다. 또한 Mediator 패턴을 시도했지만 WeakReference SecurityException에 문제가 있습니다. –

+0

@GazTheDestroyer 다른 4 개의보기에는 MainView에 대한 참조가 포함되어 있지 않습니다. –

답변

4
public class MainWindowViewModel : ViewModelBase 
    { 
    public ViewModel1 ViewModel1 { get; set; } 
    public ViewModel2 ViewModel2 { get; set; } 
    public ViewModel3 Model3 { get; set; } 

    public MainWindowViewModel() 
    { 
     ViewModel1 = new ViewModel1(); 
     ViewModel2 = new ViewModel2(); 
     ViewModel3 = new ViewModel3(); 
     ViewModel1.PropertyChanged += (s,e) => 
     { 
      if(e.PropertyName == "IsBusy") 
      { 
       // set the MainWindowViewModel.IsBusy property here 
       // for example: 
       IsBusy = ViewModel1.IsBusy; 
      } 
     } 
    //IsBusy = true; - its working 
    } 
} 

Repeate subcsription.

메모리 부족을 피하기 위해 더 이상 필요하지 않은 이벤트를 수신 거부하는 것을 잊지 마십시오.

문제는 다음과 같습니다. MainWindowViewModel의 propetry에 바인드했습니다. 내부 ViewModel의 속성이 아닙니다.

+0

에 대한 참조가 있습니다. IsBusy 속성을 변경하면 모든보기에 알림이 표시되어야합니까? –

+1

아니요, 바인딩은 마법이 아닙니다. 인스턴스가 4 개 있습니다. * MainWindowViewModel *, * ViewModel1 * 요법, 각각은 ** 고유 한 ** * IsBusy * propetry를가집니다. * ViewModel1.IsBusy = true *를 설정하면 다른 IsBusy는 여전히 * false *입니다. –

+0

xaml에서 bindind를 설정할 때 * MainWindowViewModel.IsBusy * 속성을 연결하면 제대로 작동합니다. 그러나보기는 다른 * IsBusy * 속성을 감지 할 수 없습니다. 따라서 뷰를 수동으로 알려야합니다. –