是的,我之前也遇到過這個。 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>
我在思考更多沿着向視圖模型添加「isSelected」bool的方法,然後在新的「details」viewmodel創建一個ObservableCollection,這是真的。我不確定這將如何解決。 至於你的「在列表框中的多個選擇」評論 - 我有一種感覺,這可以通過設置SelectionMode =「Multiple」或SelectionMode =「Extended」來解決。 – Rachael
好吧,將isSelected布爾添加到對象本身將工作。但是'isSelected'是一個視圖屬性,而不是一個model/viewModel屬性 - 所以當它工作時,它在技術上是不正確的。另外,在您的原始文章中,聽起來好像您要填充由所選項目組成的集合。問題是要把這些項目放到vm中,你必須有一個依賴屬性,但是不存在這樣的事情 - 你不得不自己做一個。 – sircodesalot
哦不是對象,而是_viewmodel_對象。有人在另一個問題中指出,喬希史密斯在他的博客中這樣做。 – Rachael