我有一个列表视图,用于在viewmodel中绑定具有属性的项目。
<ListView Height="238"
HorizontalAlignment="Left"
Name="listView"
VerticalAlignment="Top"
Width="503"
ItemsSource="{Binding BusinessCollection}"
SelectionMode="Multiple">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding ID}" Header="ID" />
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
并在viewmodel中。
ICollectionView _businessCollection
public ICollectionView BusinessCollection
{
get { return _businessCollection; }
set {
_businessCollection = value;
RaisePropertyOnChange("BusinessCollection");
}
}
如何在viewmodel中获取businesscollection的选定项目?
答案 0 :(得分:21)
<强> 1。一种来源绑定的方法:
您必须使用CKEDITOR.dom.document
事件。最简单的方法是在codebehind中编写eventhandler来绑定选定项目&#34;到viewmodel。
SelectionChanged
这仍然与MVVM设计保持一致,因为视图和视图模型的可靠性保持分离。您在代码隐藏中没有任何逻辑,并且viewmodel是干净且可测试的。
<强> 2。双向绑定:
如果您还需要更新视图,则当viewmodel更改时,您必须附加到ViewModel的//ViewModel
public ICollectionView BusinessCollection {get; set;}
public List<YourBusinessItem> SelectedObject {get; set;}
//Codebehind
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var viewmodel = (ViewModel) DataContext;
viewmodel.SelectedItems = listview.SelectedItems
.Cast<YourBusinessItem>()
.ToList();
}
事件以及所选项目&#39; PropertyChanged
事件。当然你可以在代码隐藏中做到这一点,但在这种情况下,我会创建一些更可重用的东西:
CollectionChanged
或者可以创建自定义附加属性,因此您可以在xaml中使用绑定语法:
//ViewModel
public ObservableCollection<YourBusinessItem> SelectedObject {get; set;}
//in codebehind:
var binder = new SelectedItemsBinder(listview, viewmodel.SelectedItems);
binder.Bind();
<ListView local:ListViewExtensions.SelectedValues="{Binding SelectedItem}" .../>
附加财产实施
public class SelectedItemsBinder
{
private ListView _listView;
private IList _collection;
public SelectedItemsBinder(ListView listView, IList collection)
{
_listView = listView;
_collection = collection;
_listView.SelectedItems.Clear();
foreach (var item in _collection)
{
_listView.SelectedItems.Add(item);
}
}
public void Bind()
{
_listView.SelectionChanged += ListView_SelectionChanged;
if (_collection is INotifyCollectionChanged)
{
var observable = (INotifyCollectionChanged) _collection;
observable.CollectionChanged += Collection_CollectionChanged;
}
}
public void UnBind()
{
if (_listView != null)
_listView.SelectionChanged -= ListView_SelectionChanged;
if (_collection != null && _collection is INotifyCollectionChanged)
{
var observable = (INotifyCollectionChanged) _collection;
observable.CollectionChanged -= Collection_CollectionChanged;
}
}
private void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach (var item in e.NewItems ?? new object[0])
{
if (!_listView.SelectedItems.Contains(item))
_listView.SelectedItems.Add(item);
}
foreach (var item in e.OldItems ?? new object[0])
{
_listView.SelectedItems.Remove(item);
}
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.AddedItems ?? new object[0])
{
if (!_collection.Contains(item))
_collection.Add(item);
}
foreach (var item in e.RemovedItems ?? new object[0])
{
_collection.Remove(item);
}
}
}
答案 1 :(得分:-2)
由于itemSource是BusinessCollection,您应该能够:
var selectedItems = BusinessCollection.Where(x => x.IsSelected);
将其作为VM上的属性包装。 希望它有所帮助!