2017-06-21 44 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); 
     } 
    } 
} 

我想要從子視圖模型中獲取並使用選定的值。我的方法無效 - 如果SelectedNumber在ChildViewModel中更改,SelectedChildNumber不想刷新。

更新: 好吧,如果我在ParentViewModel中有ChildViewModel集合會怎樣。其中一個ChildViewModels的屬性IsSelected等於true。如何從集合中獲取這一個選定的視圖模型?

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}}" /> 

在轉換器中,我可以找到選定的項目。或者這是個壞主意?

更新2:

好吧,我打了這個問題,埃德賓吉幫助。最終版本應該是:

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 setter中引發PropertyChanged事件? – taquion

+0

因爲我使用Prism框架,所以我不需要提高PropertyChanged事件mannualy。 – Oblomingo

+0

@taquion'SetProperty()'這樣做。他很好。 –

回答

1

直接綁定到子屬性:

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

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

這是在綁定路徑,不是那種父母的ChildViewModel財產的名稱。 Binding現在知道傾聽ChildViewModel對象PropertyChanged有關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

太棒了!如果我在ParentViewModel中有ChildViewModel集合會怎麼樣?其中一個ChildViewModels的屬性IsSelected等於true。如何從集合中獲取這一個選定的視圖模型? – Oblomingo

+1

在這種情況下,父母可能想要處理每個孩子的'PropertyChanged'事件。有趣的是,當我看到您的評論時,我只是在更新中添加了這個想法。 –

+0

我不知道如何從每個孩子舉辦活動。你能舉一個例子嗎? – Oblomingo

相關問題