将ListView的SelectedItem绑定到ViewModel

时间:2015-07-02 06:25:17

标签: c# wpf mvvm

我有一个列表视图,用于在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的选定项目?

2 个答案:

答案 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上的属性包装。 希望它有所帮助!