将ListView的SelectedItem绑定到ViewModel

编程入门 行业动态 更新时间:2024-10-20 03:17:16
本文介绍了将ListView的SelectedItem绑定到ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个列表视图,该列表视图将项目与viewmodel中的属性绑定在一起.

I have a list view that binding items with a property in 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中.

and in viewmodel.

ICollectionView _businessCollection public ICollectionView BusinessCollection { get { return _businessCollection; } set { _businessCollection = value; RaisePropertyOnChange("BusinessCollection"); } }

如何在视图模型中获取选定的业务集合项?

How to get selected item of businesscollection in viewmodel?

推荐答案

1.获取绑定的一种方法:

您必须使用SelectionChanged事件.最简单的方法是在代码背后编写事件处理程序,以将绑定选定项"绑定到视图模型.

You have to use SelectionChanged event. The easiest way is to write eventhandler in codebehind to "bind selecteditems" to 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(); }

这仍然与MVVM设计保持一致,因为视图和视图模型的可重复性保持分离.您在代码隐藏中没有任何逻辑,并且viewmodel干净且可测试.

This still aligns with MVVM design, because view and viewmodel resposibilities are kept separated. You dont have any logic in codebehind and viewmodel is clean and testable.

2.双向绑定:

如果还需要更新视图,则在更改ViewModel时,必须附加到ViewModel的PropertyChanged事件和所选项目的CollectionChanged事件.当然,您可以在代码隐藏中执行此操作,但是在这种情况下,我将创建一些更可重用的内容:

if you also need to update view, when viewmodel changes, you have to attach to ViewModel's PropertyChanged event and to the selected items' CollectionChanged event. of course you can do it in codebehind, but in this case I would create something more reusable:

//ViewModel public ObservableCollection<YourBusinessItem> SelectedObject {get; set;} //in codebehind: var binder = new SelectedItemsBinder(listview, viewmodel.SelectedItems); binder.Bind();

或可以创建自定义附加属性,因此您可以在xaml中使用绑定语法:

or can create custom attached property, so you can use binding syntax in xaml:

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

附加属性实现

public class ListViewExtensions { private static SelectedItemsBinder GetSelectedValueBinder(DependencyObject obj) { return (SelectedItemsBinder)obj.GetValue(SelectedValueBinderProperty); } private static void SetSelectedValueBinder(DependencyObject obj, SelectedItemsBinder items) { obj.SetValue(SelectedValueBinderProperty, items); } private static readonly DependencyProperty SelectedValueBinderProperty = DependencyProperty.RegisterAttached("SelectedValueBinder", typeof(SelectedItemsBinder), typeof(ListViewExtensions)); public static readonly DependencyProperty SelectedValuesProperty = DependencyProperty.RegisterAttached("SelectedValues", typeof(IList), typeof(ListViewExtensions), new FrameworkPropertyMetadata(null, OnSelectedValuesChanged)); private static void OnSelectedValuesChanged(DependencyObject o, DependencyPropertyChangedEventArgs value) { var oldBinder = GetSelectedValueBinder(o); if (oldBinder != null) oldBinder.UnBind(); SetSelectedValueBinder(o, new SelectedItemsBinder((ListView)o, (IList)value.NewValue)); GetSelectedValueBinder(o).Bind(); } public static void SetSelectedValues(Selector elementName, IEnumerable value) { elementName.SetValue(SelectedValuesProperty, value); } public static IEnumerable GetSelectedValues(Selector elementName) { return (IEnumerable)elementName.GetValue(SelectedValuesProperty); } }

更多推荐

将ListView的SelectedItem绑定到ViewModel

本文发布于:2023-11-06 14:14:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1563914.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:绑定   ListView   SelectedItem   ViewModel

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!