2013-02-08 56 views
3

我有一個綁定到名稱的ObservableCollection的列表框。列表中的一些項目將會有一個複選框被打開/關閉,表示該項目已被選中。爲MVVM選擇的多個ListBox /收集項目

如何在Master-Details概念之後的第一個列表框的選定項目中創建ObservableCollection?

(我打算用我的MasterViewModel作爲在DataContext我的DetailsView控件顯示所選項目集合。)

提前感謝!

回答

5

是的,我之前也遇到過這個。 ListBox和類似的有一個名爲'SelectedItem'的依賴項屬性,但'SelectedItems'(帶有's')屬性不是作爲一個實現的。

我找到的最乾淨的解決方案只是爲了列表框子類,並創建我自己的依賴屬性,名爲'SelectedItems'。沒有樂趣,但它是我認爲最好的解決方案。

UPDATE

首先我們的視圖模型:

class ViewModel : INotifyPropertyChanged 
{ 
    // Set up our collection to be read from the View 
    public ObservableCollection<String> Collection { get; private set; } 

    // This collection will maintain the selected items 
    public ObservableCollection<String> SelectedItems { get; private set; } 

    public ViewModel() 
    { 
     // Instantiate 
     this.Collection = new ObservableCollection<String>(); 
     this.SelectedItems = new ObservableCollection<String>(); 

     // Now let's monitor when this.SelectdItems changes 
     this.SelectedItems.CollectionChanged += SelectedItems_CollectionChanged; 

     // Fill our collection with some strings (1 to 10). 
     // (1) Generate the numbers 1 - 10 
     // (2) Convert each number to a string 
     // (3) Cast into a list so we can use foreach 
     // (4) Add each item to the collection. 
     Enumerable.Range(1, 10) 
      .Select(number => number.ToString()) 
      .ToList()        
      .ForEach(this.Collection.Add); 

     // Remember! Never reset the ObservableCollection. 
     // That is, never say this.Collection = new... (or you'll break the binding). 
     // instead use this.Collection.Clear(), and then add the items you want to add 
    } 

    void SelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) 
     { 
      foreach (String str in this.SelectedItems) 
       System.Diagnostics.Debug.WriteLine("New item added {0}", str); 

     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

然後我們的擴展ListBoxEx:

class ListBoxEx : ListBox 
{ 
    // Use the 'new' keyword so that we 'hide' the base property. 
    // This means that binding will go to this version of SelectedItems 
    // rather than whatever the base class uses. To reach the base 'SelectedItems' property 
    // We just need to use base.SelectedItems instead of this.SelectedItems 
    // Note that we register as an observable collection. 
    new DependencyProperty SelectedItemsProperty = 
     DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<String>), typeof(ListBoxEx)); 

    // Accessor. Again, note the 'new'. 
    new public ObservableCollection<String> SelectedItems 
    { 
     get { return (ObservableCollection<String>) GetValue(SelectedItemsProperty); } 
     set { SetValue(SelectedItemsProperty, value); } 
    } 

    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     // Guard against ViewModel being null 
     if (this.SelectedItems != null) 
     { 
      // Clear the list 
      this.SelectedItems.Clear(); 

      // (1) On selection changed. Get the new base.SelectedItems 
      // (2) Cast each item to a String ("Make a string collection") 
      // (3) Cast to list, and use foreach to add each item to 
      // this.SelectedItems (note this is different from the original base.SelectedItems) 
      base.SelectedItems.Cast<String>() 
       .ToList() 
       .ForEach(this.SelectedItems.Add); 
     } 
    } 
} 

最後我們的觀點:

<Window.DataContext> 
    <lol:ViewModel /> 
</Window.DataContext> 
<Grid> 
    <lol:ListBoxEx ItemsSource="{Binding Collection}" SelectedItems="{Binding SelectedItems}" 
        SelectionMode="Multiple"/> 
</Grid> 
+0

我在思考更多沿着向視圖模型添加「isSelected」bool的方法,然後在新的「details」viewmodel創建一個ObservableCollection,這是真的。我不確定這將如何解決。 至於你的「在列表框中的多個選擇」評論 - 我有一種感覺,這可以通過設置SelectionMode =「Multiple」或SelectionMode =「Extended」來解決。 – Rachael

+0

好吧,將isSelected布爾添加到對象本身將工作。但是'isSelected'是一個視圖屬性,而不是一個model/viewModel屬性 - 所以當它工作時,它在技術上是不正確的。另外,在您的原始文章中,聽起來好像您要填充由所選項目組成的集合。問題是要把這些項目放到vm中,你必須有一個依賴屬性,但是不存在這樣的事情 - 你不得不自己做一個。 – sircodesalot

+0

哦不是對象,而是_viewmodel_對象。有人在另一個問題中指出,喬希史密斯在他的博客中這樣做。 – Rachael