Как связать множественный выбор listview с viewmodel?
Я реализую listview и кнопку рядом с ним. Я должен иметь возможность, когда я выбираю несколько элементов в списке, а затем нажимаю кнопку, тогда выбранные элементы помещаются в список. Но мой вопрос заключается в том, как привязать выбранные элементы к viewmodel?
Я изменил свой метод выбора на несколько. Но тогда мне просто нужно сделать:
SelectedItem={Binding path= selectedItems}
а затем сделайте в моей модели view свойство selectedItems, и он установит эти элементы, которые я выбрал? Или какое правильное решение для этого?
Ответы
Ответ 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.
Ответ 5
К сожалению, SelectedItems - свойство, не доступное для чтения, только для чтения.
Я нашел много помощи из этой статьи Как связать привязку к свойству SelectedItems в WPF
Ответ 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).