2017-06-21 10 views
0

私はPrism MVVMフレームワークでWPFアプリケーションを開発しています。また、親ビューモデルと子ビューモデルの間でデータが正しくどのように正しく渡されるかはわかりません。WPFアプリケーションで子ビューモデルプロパティにバインドする方法はありますか

私は2つのビューモデルParentViewModelと内部ChildViewModelを持っています。

public class ParentViewModel 
{ 
    public ParentViewModel 
    { 
     ChildViewModel = new ChildViewModel(params); 
    } 

     private ChildViewModel _childViewModel; 
     public ChildViewModel ChildViewModel 
     { 
      get { return _childViewModel; } 
      set 
      { 
       SetProperty(ref _childViewModel, value); 
      } 
     } 

     //This is does not work 
     public int SelectedChildNumber 
     { 
      return _childViewModel.SelectedNumber; 
     } 
} 

public class ChildViewModel 
{ 
    public ChildViewModel 
    { 
     _numbers = new List<int>(); 
    } 

    private List<int> _numbers; 
    public List<int> Numbers 
    { 
     get { return _numbers; } 
     set 
     { 
      SetProperty(ref _numbers, value); 
     } 
    } 

    private int _selectedNumber; 
    public int SelectedNumber 
    { 
     get { return _selectedNumber; } 
     set 
     { 
      SetProperty(ref _selectedNumber, value); 
     } 
    } 
} 

子ビューモデルから選択した値を取得して使用します。私のアプローチは動作しません - ChildViewModelでSelectedNumberが変更された場合、SelectedChildNumberは更新したくありません。

更新: 私はChildViewModelコレクションをParentViewModelに持っていますか?このChildViewModelの1つに、IsSelectedプロパティがtrueと等しいプロパティがあります。選択した1つのビューモデルをコレクションから取得するにはどうすればよいですか?

public class ParentViewModel 
{ 
    public ParentViewModel 
    { 
     Items = GetItems(); 
    } 

    private ObservableCollection<ChildViewModel> _items; 
    public ObservableCollection<ChildViewModel> Items 
    { 
     get 
     { 
      return _items; 
     } 
     set 
     { 
      SetProperty(ref _items, value); 
     } 
    } 
} 

public class ChildViewModel 
{ 
    public ChildViewModel 
    { 
    } 

    private bool _isSelected; 
    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set 
     { 
      SetProperty(ref _isSelected, value); 
     } 
    } 
} 

選択したビューモデルを取得するにはどうすればよいですか?多分コンバータを使用しますか?

<someUserControl DataContext="{Binding ParentViewModel.Items, Converter={x:Static c:GetSelectedItemConverter.Instance}}" /> 

コンバーターでは、選択したアイテムを見つけることができます。またはこれは悪い考えですか?

UPDATE 2:

[OK]を、私はエドプランケットの助けを借りて、この問題を破りました。最終版は次のようになります。子プロパティに直接

public class ParentViewModel 
{ 
    public ParentViewModel 
    { 
     Items = GetItems(); 
     foreach (var item in Items) 
     { 
      item.PropertyChanged += ChildViewModel_PropertyChanged; 
     } 
    } 

    private ObservableCollection<ChildViewModel> _items; 
    public ObservableCollection<ChildViewModel> Items 
    { 
     get 
     { 
      return _items; 
     } 
     set 
     { 
      SetProperty(ref _items, value); 
     } 
    } 

    private ChildViewModel _selectedChild; 
    public ChildViewModel SelectedChild 
    { 
     get { return _selectedChild; } 
     set 
     { 
      SetProperty(ref _selectedChild, value); 
     } 
    } 

    private void ChildViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     var child = (ChildViewModel)sender; 
     if (e.PropertyName == nameof(ChildViewModel.IsSelected) && child.IsSelected) 
     { 
      SelectedChild = child; 
     } 
    } 
} 
+0

SelectedNumberセッターでPropertyChangedイベントを発生させていますか? – taquion

+0

私はPrismフレームワークを使用しているので、PropertyChangedイベントを手動で呼び出す必要はありません。 – Oblomingo

+0

@taquion 'SetProperty()'はそれを行います。彼はとてもいい。 –

答えて

1

バインド:

<ListBox 
    ItemsSource="{Binding ChildViewModel.Numbers}" 
    SelectedItem="{Binding ChildViewModel.SelectedNumber}" 
    /> 

<Label Content="{Binding ChildViewModel.SelectedNumber}" /> 

結合パス、いないタイプで、親のChildViewModelプロパティの名前です。 Bindingは、PropertyChangedの通知のオブジェクトChildViewModelを聞くことを知っています。SelectedNumberNumbersに関する通知です。

あなたのバージョンが機能しないのは、SelectedChildNumberが変更されたときに親がPropertyChangedを発行しないことです。実際、親はUIよりもそれが何時変わるかを知らない。親のは、子のPropertyChangedイベントを処理するとすることができます。

public ParentViewModel() 
{ 
    ChildViewModel = new ChildViewModel(params); 

    // Handle child's PropertyChanged event 
    ChildViewModel.PropertyChanged += ChildViewModel_PropertyChanged; 
} 

private void ChildViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    var child = (ChildViewModel)sender; 

    if (e.PropertyName == nameof(ChildViewModel.SelectedNumber)) 
    { 
     // Do stuff 
    } 
} 

しかし、このような場合は、これを行う必要はありません。

ChildViewModel.Numbersは、おそらくObservableCollection<int>であり、List<int>ではありません。そうすれば、番号を追加したり削除したりすると、UIによってコレクションによって自動的に通知され、ListBoxはそれに応じて自動的に更新されます。

+0

素晴らしい! ChildViewModelコレクションがParentViewModelにある場合はどうなりますか?このChildViewModelの1つに、IsSelectedプロパティがtrueと等しいプロパティがあります。選択した1つのビューモデルをコレクションから取得するにはどうすればよいですか? – Oblomingo

+1

その場合、親は各子の 'PropertyChanged'イベントを処理したいかもしれません。おかげで、あなたのコメントを見たときにそのアイデアをアップデートに追加していただけです。 –

+0

私はどの子どもからどのようにイベントを起こすのか分かりません。あなたは例を見せてもらえますか? – Oblomingo

関連する問題