How to bind multiple selection of listview to viewmodel?

后端 未结 9 2001
刺人心
刺人心 2020-12-13 09:14

I am implementing a listview, and a button next to it. I have to be able that when i select multiple items in a listview, and then click on a button, then the selected items

相关标签:
9条回答
  • 2020-12-13 09:38

    If you are using Metro/WinRT you may want to look at the WinRTXXAMLToolkit as it offers a bindable SelectedItems dependency property as one of its extensions.

    0 讨论(0)
  • 2020-12-13 09:39

    What you can do is you can handle the Button_Click(...) in your code-behind. Then in that code-behind method you can create a List of selected items by iterating over the selected items of the listView.

    Since it is allowed to access the ViewModel from the View you can now call a method on your ViewModel and pass the list of selected items as a parameter.

    I'm not sure if this would also work with Bindings only, however it is not bad practice to use code-behind as well.

    Example Code:

    public void Button_Click(object sender, EventArguments arg)
    {
      List<ListViewItem> mySelectedItems = new List<ListViewItem>();
    
      foreach(ListViewItem item in myListView.SelectedItems)
      {
        mySelectedItems.Add(item);
      }
    
      ViewModel.SomeMethod(mySelectedItems);
    }
    

    EDIT

    Here is a minimalist example, XAML:

    <DataTemplate
                x:Key="CarTemplate"
                DataType="{x:Type Car}">
    </DataTemplate>
    
    <ListView x:Name="myListView"
              ItemsSource="{Binding Path=Cars}"
              ItemTemplate="{StaticResource CarTemplate}">
    </ListView>
    

    CODE-BEHIND:

    public void Button_Click(object sender, EventArguments arg)
        {
          List<Car> mySelectedItems = new List<Car>();
    
          foreach(Car item in myListView.SelectedItems)
          {
            mySelectedItems.Add(item);
          }
    
          ViewModel.SomeMethod(mySelectedItems);
        }
    
    0 讨论(0)
  • 2020-12-13 09:41

    It's kind of tricky to do this Mutliple Selection in MVVM, because the SelectedItems property isn't a Dependency Property. However, there are some tricks you can use. I found this triology of blog posts that describe the matter in some details and provide some useful solutions.

    • Part I
    • Part II
    • Part III

    Hope this helps

    0 讨论(0)
  • 2020-12-13 09:43

    You can't bind, but you can send to Command as an CommandParameter.

    0 讨论(0)
  • 2020-12-13 09:48

    I did a solution for this, to me this was simple enough.

    <ListBox ItemsSource="{Binding ListOfModel}" x:Name="ModelList"
                                    SelectedItem="{Binding SelectedModel, Mode=TwoWay}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="SelectionChanged">
                                        <i:InvokeCommandAction Command="{Binding ExecuteListBoxSelectionChange}" CommandParameter="{Binding ElementName=ModelList}">
                                        </i:InvokeCommandAction>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </ListBox>
    

    Then in the viewmodel:

    public ICommand ExecuteListBoxSelectionChange { get; private set; }
    ExecuteListBoxSelectionChange = DelegatingCommand<ListBox>.For(ListBoxSelectionChnageEvent).AlwaysEnabled();
    

    SelectedModels is the list where I wanted the selection to be filled.

        private void ListBoxSelectionChnageEvent(ListBox modelListBox)
        {
            List<ModelInfo> tempModelInfo = new List<ModelInfo>();
             foreach(ModelInfo a in modelListBox.SelectedItems)
                 tempModelInfo.Add(a);
    
             SelectedModels = tempModelInfo;
        }
    
    0 讨论(0)
  • 2020-12-13 09:54

    Like Doctor has already pointed out, you can bind SelectedItems to XAML CommandParameter

    After a lot of digging and googling, I have finally found a simple solution to this common issue.

    To make it work you must follow ALL the following rules:

    1. Following Ed Ball's suggestion', on you XAML command databinding, define CommandParameter property BEFORE Command property. This a very time-consuming bug.

      enter image description here

    2. Make sure your ICommand's CanExecute and Execute methods have a parameter of object type. This way you can prevent silenced cast exceptions that occurs whenever databinding CommandParameter type does not match your command method's parameter type.

      private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)
      {
          // Your goes here
      }
      
      private bool OnDeleteSelectedItemsExecute(object SelectedItems)
      {
          // Your goes here
      }
      

    For example, you can either send a listview/listbox's SelectedItems property to you ICommand methods or the listview/listbox it self. Great, isn't it?

    Hope it prevents someone spending the huge amount of time I did to figure out how to receive SelectedItems as CanExecute parameter.

    0 讨论(0)
提交回复
热议问题