gpt4 book ai didi

c# - 为 MVVM 选择的多个列表框/集合项

转载 作者:行者123 更新时间:2023-11-30 15:01:00 26 4
gpt4 key购买 nike

我有一个绑定(bind)到 ObservableCollection of Names 的列表框。列表中的某些项目将有一个打开/关闭的复选框,表示该项目已被选中。

如何根据主从概念从第一个列表框中的选定项创建 ObservableCollection?

(我计划将我的 MasterViewModel 用作显示所选项目集合的 DetailsView 的 DataContext。)

提前致谢!

最佳答案

是的,我以前也遇到过这个问题。列表框等具有名为“SelectedItem”的依赖属性,但“SelectedItems”(带有“s”)属性并未实现为一个属性。

我找到的最干净的解决方案就是将列表框子类化,并创建我自己的名为“SelectedItems”的依赖属性。没有乐趣,但我认为这是最好的解决方案。

更新

首先是我们的 ViewModel:

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);
}
}
}

最后是我们的 View :

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

关于c# - 为 MVVM 选择的多个列表框/集合项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14763745/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com