2010-09-09 28 views
0
需要的層疊組合框一個簡單的例子

需要級聯使用MVVM使用MVVM

組合框的一個簡單的例子

WPF/Silverlight的

回答

8

如果我理解你的問題,你希望有下一個組合框填充數據基於以前的價值。

我有一個通用的視圖模型,你可以有捕獲項目的列表和所選擇的項目

class ItemListViewModel<T> : INotifyPropertyChanged where T : class 
{ 
    private T _item; 
    private ObservableCollection<T> _items; 

    public ItemListViewModel() 
    { 
     _items = new ObservableCollection<T>(); 
     _item = null; 
    } 

    public void SetItems(IEnumerable<T> items) 
    { 
     Items = new ObservableCollection<T>(items); 
     SelectedItem = null; 
    } 

    public ObservableCollection<T> Items 
    { 
     get { return _items; } 
     private set 
     { 
      _items = value; 
      RaisePropertyChanged("Items"); 
     } 
    } 

    public T SelectedItem 
    { 
     get { return _item; } 
     set 
     { 
      _item = value; 
      RaisePropertyChanged("SelectedItem"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

然後有將被綁定到視圖的DataContext的主視圖模型。使Load方法做你想做的事

class MyViewModel : INotifyPropertyChanged 
{ 
    public MyViewModel() 
    { 
     First = new ItemListViewModel<string>(); 
     Second = new ItemListViewModel<string>(); 
     Third = new ItemListViewModel<string>(); 

     First.PropertyChanged += (s, e) => Update(e.PropertyName, First, Second, LoadSecond); 
     Second.PropertyChanged += (s, e) => Update(e.PropertyName, Second, Third, LoadThird); 

     LoadFirst(); 
    } 

    public ItemListViewModel<string> First { get; set; } 
    public ItemListViewModel<string> Second { get; set; } 
    public ItemListViewModel<string> Third { get; set; } 

    private void LoadFirst() 
    { 
     First.SetItems(new List<string> { "One", "Two", "Three" }); 
    } 
    private void LoadSecond() 
    { 
     Second.SetItems(new List<string> { "First", "Second", "Third" }); 
    } 
    private void LoadThird() 
    { 
     Third.SetItems(new List<string> { "Firsty", "Secondly", "Thirdly" }); 
    } 

    private void Update<T0, T1>(string propertyName, ItemListViewModel<T0> parent, ItemListViewModel<T1> child, Action loadAction) 
     where T0 : class 
     where T1 : class 
    { 
     if (propertyName == "SelectedItem") 
     { 
      if (parent.SelectedItem == null) 
      { 
       child.SetItems(Enumerable.Empty<T1>()); 
      } 
      else 
      { 
       loadAction(); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

而在你看來有這個代碼的地方。

<ComboBox ItemsSource="{Binding First.Items}" SelectedItem="{Binding First.SelectedItem}" /> 
    <ComboBox ItemsSource="{Binding Second.Items}" SelectedItem="{Binding Second.SelectedItem}" /> 
    <ComboBox ItemsSource="{Binding Third.Items}" SelectedItem="{Binding Third.SelectedItem}" /> 

您可以重構,使之更好,使用MVVM框架或專門推導出ItemListViewModel物品的清單,並在有負載的更好的封裝。隨你便。

如果任何父組合框值發生變化,則所有子列表都將被清除。

HTH

+0

我知道這個答案是舊的 - 但SelectedItem綁定應該是雙向的。並感謝這個有用的例子 – Raziel 2014-12-05 12:37:37

+0

在WPF TwoWay應該是默認的。 Silverlight可能是一個不同的故事,但明確可以幫助任何一種方式。 – aqwert 2014-12-05 22:18:50

+0

解釋它 - 默認情況下Silverlight具有OneWay。有多混亂。 – Raziel 2014-12-06 15:40:47