Подтвердить что ты не робот

Как связать множественный выбор listview с viewmodel?

Я реализую listview и кнопку рядом с ним. Я должен иметь возможность, когда я выбираю несколько элементов в списке, а затем нажимаю кнопку, тогда выбранные элементы помещаются в список. Но мой вопрос заключается в том, как привязать выбранные элементы к viewmodel? Я изменил свой метод выбора на несколько. Но тогда мне просто нужно сделать:

SelectedItem={Binding path= selectedItems}

а затем сделайте в моей модели view свойство selectedItems, и он установит эти элементы, которые я выбрал? Или какое правильное решение для этого?

4b9b3361

Ответ 1

Что вы можете сделать, так это то, что вы можете обрабатывать Button_Click (...) в коде. Затем в этом методе кода вы можете создать список выбранных элементов, итерации по выбранным элементам listView.

Поскольку ему разрешен доступ к ViewModel из представления, теперь вы можете вызвать метод на вашем ViewModel и передать список выбранных элементов в качестве параметра.

Я не уверен, что это также будет работать только с Bindings, однако неплохо использовать код также.

Пример кода:

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

ИЗМЕНИТЬ

Вот минималистский пример: XAML:

<DataTemplate
            x:Key="CarTemplate"
            DataType="{x:Type Car}">
</DataTemplate>

<ListView x:Name="myListView"
          ItemsSource="{Binding Path=Cars}"
          ItemTemplate="{StaticResource CarTemplate}">
</ListView>

КОД-ЗА:

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

Ответ 2

Как Доктор уже указал, вы можете привязать SelectedItems к XAML CommandParameter

После большого поиска и поиска в Google я наконец нашел простое решение этой общей проблемы.

Чтобы заставить его работать, вы должны следовать ВСЕМ следующим правилам:

  • Следуя Ed Ball suggestion ', вы привязываетесь к базе данных XAML, определите свойство CommandParameter ПЕРЕД Командой свойство. Это очень трудоемкая ошибка.

    enter image description here

  • Убедитесь, что методы ICommand CanExecute и Execute имеют параметр object. Таким образом, вы можете предотвратить исключение из-за исключения, которое возникает, когда тип привязки CommandParameter не соответствует типу параметра метода команды.

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

Например, вы можете отправить свойство listview/listbox SelectedItems для вас ICommand или listview/listbox. Отлично, не так ли?

Надеюсь, что это не позволяет кому-то потратить огромное количество времени, которое я сделал, чтобы выяснить, как получить SelectedItems как параметр CanExecute.

Ответ 3

Как-то сложно сделать это Mutliple Selection в MVVM, потому что свойство SelectedItems не является Dependency Property. Однако есть некоторые трюки, которые вы можете использовать. Я нашел эту трилогию сообщений в блогах, которые описывают этот вопрос в некоторых деталях и предоставляют некоторые полезные решения.

Надеюсь, что это поможет

Ответ 4

Если вы используете System.Windows.Interactivity и Microsoft.Expression.Interactions уже, это обходной путь без каких-либо других кодов/поведения, которые могут возникнуть. Если вам это нужно, его можно скачать из здесь

В этом обходном методе использование механизма события и взаимодействия механизмов взаимодействия в вышеприведенных сборках.

Дополнительная декларация пространства имен в XAML

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

XAML:

<ListView Name="MyListView" ItemsSource="{Binding ModelList}" DisplayMemberPath="Name"  Grid.Column="0">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedItems" Value="{Binding Path=SelectedItems, ElementName=MyListView}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListView>

Показать модель:

public class ModelListViewModel
{
  public ObservableCollection<Model> ModelList { get; set; }
  public ObservableCollection<Model> SelectedModels { get; set; }

  public ModelListViewModel() {
    ModelList = new ObservableCollection<Model>();
    SelectedModels = new ObservableCollection<Model>();
  }

  public System.Collections.IList SelectedItems {
    get {
      return SelectedModels;
    }
    set {
      SelectedModels.Clear();
      foreach (Model model in value) {
        SelectedModels.Add(model);
      }
    }
  }
}

В приведенном выше примере ваша ViewModel будет выбирать выбранные элементы всякий раз, когда будет изменен выбор в ListView.

Ответ 6

Вы не можете привязывать, но вы можете отправить команду Command в качестве параметра CommandParameter.

Ответ 7

Если вы используете Metro/WinRT, вы можете посмотреть WinRTXXAMLToolkit, поскольку он предлагает связующее свойство зависимости SelectedItems как одно из его расширения.

Ответ 8

Я сделал для этого решение, для меня это было достаточно просто.

<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>

Тогда в viewmodel:

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

SelectedModels - это список, в котором я хотел, чтобы выбор был заполнен.

    private void ListBoxSelectionChnageEvent(ListBox modelListBox)
    {
        List<ModelInfo> tempModelInfo = new List<ModelInfo>();
         foreach(ModelInfo a in modelListBox.SelectedItems)
             tempModelInfo.Add(a);

         SelectedModels = tempModelInfo;
    }

Ответ 9

Как небольшая вариация на христианском посту, я реализовал аналогичный код, используя событие ListView.SelectionChanged. Вместо вызова метода в ViewModel я устанавливаю свойство SelectedItems:

public void ListView_SelectionChanged( object s, SelectionChangedEventArgs e ) {
    List<Car> mySelectedItems = new List<Car>();

    foreach( Car item in myListView.SelectedItems )
        mySelectedItems.Add(item);

    ViewModel.SelectedItems = mySelectedItems;
}

Таким образом, ViewModel.SelectedItems доступен для любой команды, которую вы можете иметь в своей модели ViewModel, и ее можно использовать для привязки данных (если вы превратите ее в ObservableCollection).