Выберите несколько элементов из DataGrid в проекте MVVM MVPM

Как выбрать несколько элементов из DataGrid в MVVM проекте MVVM?

Вы можете просто добавить свойство пользовательской зависимости, чтобы сделать это:

 public class CustomDataGrid : DataGrid { public CustomDataGrid () { this.SelectionChanged += CustomDataGrid_SelectionChanged; } void CustomDataGrid_SelectionChanged (object sender, SelectionChangedEventArgs e) { this.SelectedItemsList = this.SelectedItems; } #region SelectedItemsList public IList SelectedItemsList { get { return (IList)GetValue (SelectedItemsListProperty); } set { SetValue (SelectedItemsListProperty, value); } } public static readonly DependencyProperty SelectedItemsListProperty = DependencyProperty.Register ("SelectedItemsList", typeof (IList), typeof (CustomDataGrid), new PropertyMetadata (null)); #endregion } 

Теперь вы можете использовать этот dataGrid в XAML:

      

Моя ViewModel :

 public class MyViewModel : INotifyPropertyChanged { private static object _lock = new object (); private List _myModel; public IEnumerable Model { get { return _myModel; } } private IList _selectedModels = new ArrayList (); public IList TestSelected { get { return _selectedModels; } set { _selectedModels = value; RaisePropertyChanged ("TestSelected"); } } public MyViewModel () { _myModel = new List (); BindingOperations.EnableCollectionSynchronization (_myModel, _lock); for (int i = 0; i < 10; i++) { _myModel.Add (new MyModel { Name = "Test " + i, Age = i * 22 }); } RaisePropertyChanged ("Model"); } public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged (string propertyName) { var pc = PropertyChanged; if (pc != null) pc (this, new PropertyChangedEventArgs (propertyName)); } } 

Моя модель:

 public class MyModel { public string Name { get; set; } public int Age { get; set; } } 

И, наконец, вот код позади MainWindow :

 public partial class MainWindow : Window { public MainWindow () { InitializeComponent (); this.DataContext = new MyViewModel (); } } 

Надеюсь, этот чистый дизайн MVVM поможет.

Я бы сделал это, создав Behaviors используя System.Windows.Interactivity . Вам нужно будет ссылаться на него вручную в своем проекте.

Учитывая элемент управления, который не выставляет SelectedItems например, (ListBox, DataGrid)

Вы можете создать class поведения примерно так

 public class ListBoxSelectedItemsBehavior : Behavior { protected override void OnAttached() { AssociatedObject.SelectionChanged += AssociatedObjectSelectionChanged; } protected override void OnDetaching() { AssociatedObject.SelectionChanged -= AssociatedObjectSelectionChanged; } void AssociatedObjectSelectionChanged(object sender, SelectionChangedEventArgs e) { var array = new object[AssociatedObject.SelectedItems.Count]; AssociatedObject.SelectedItems.CopyTo(array, 0); SelectedItems = array; } public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IEnumerable), typeof(ListBoxSelectedItemsBehavior), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); public IEnumerable SelectedItems { get { return (IEnumerable)GetValue(SelectedItemsProperty); } set { SetValue(SelectedItemsProperty, value); } } } 

И на вашем XAML я бы сделал Binding как это, где ixmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" а behaviors – пространство имен вашего classа Behavior

     

Предполагая, что ваш DataContext для ListBox имеет свойство SelectedItems в ViewModel он автоматически обновит SelectedItems . Вы заключили event подписанное в View ,

  

Вы можете изменить class Behavior на тип DataGrid если хотите.

Я использую это решение в своем приложении:

XAML:

      

в верхней части вашего файла xaml, добавьте эту строку кода:

 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 

SelectedItemsCommand – это тип ICommand, который написан в вашей модели viewmodel.

Используемая DLL:

System.Windows.Interactivity.dll

С помощью DataGrid по умолчанию WPF невозможно использовать привязку, как это возможно при выборе SelectedItem -Property, так как свойство SelectedItems -Property не является DependencyProperty.

Один из способов сделать то, что вы хотите, – зарегистрировать SelectionChanged -Event DataGrid, чтобы обновить свойство ViewModel, которое хранит выбранные элементы.

Свойство SelectedItems DataGrid имеет тип IList, поэтому вам нужно отнести элементы в списке к вашему конкретному типу.

C #

 public MyViewModel { get{ return this.DataContext as MyViewModel; } } private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { // ... Get SelectedItems from DataGrid. var grid = sender as DataGrid; var selected = grid.SelectedItems; List selectedObjects = selected.OfType().ToList(); MyViewModel.SelectedMyObjects = selectedObjects; } 

XAML

      

Вы можете добавить свойство IsSelected в Model и добавить checkBox в строку.

Вы можете maka повторно использовать общий базовый class . Таким образом, вы можете выбирать строки как из кода, так и из пользовательского интерфейса .

Это мой примерный class, который я хочу выбрать

 public class MyClass { public string MyString {get; set;} } 

Создайте общий базовый class для выбираемых classов. INotifyPropertyChanged делает обновление пользовательского интерфейса при установке IsSelected.

 public class SelectableItem : System.ComponentModel.INotifyPropertyChanged { public SelectableItem(T item) { Item = item; } public T Item { get; set; } bool _isSelected; public bool IsSelected { get { return _isSelected; } set { if (value == _isSelected) { return; } _isSelected = value; if (PropertyChanged != null) { PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("IsSelected")); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; } 

Создать выбранный class

 public class MySelectableItem: SelectableItem { public MySelectableItem(MyClass item) :base(item) { } } 

Создать свойство для привязки к

 ObservableCollection MyObservableCollection ... 

Установите пропеты

 MyObservableCollection = myItems.Select(x => new MySelectableItem(x)); 

Привяжите к datagrid и добавьте стиль в DataGridRow, который привязан к IsSelected propety на MySelectedItem

      

Чтобы получить выбранные строки / элементы

 var selectedItems = MyObservableCollection.Where(x=>x.IsSelected).Select(y=>y.Item); 

Чтобы выбрать строки / элементы

 MyObservableCollection[0].IsSelected = true; 

Редактировать —> Кажется, что это не работает, когда EnableRowVirtualization истинна

WPF DataGrid позволяет это. Просто установите DataGrid.Rows.SelectionMode и DataGrid.Rows.SelectionUnit в «Extended» и «CellOrRowHeader» соответственно. Это можно сделать в Blend, как показано на изображении, которое я включил. Это позволит пользователю выбирать каждую ячейку, целые строки и т. Д. Столько, сколько им нравится, используя клавишу shift или ctrl для продолжения выбора. введите описание изображения здесь

Проект, над которым я работаю, использует MVVM Light, и я нашел это сообщение в блоге самым простым решением. Я повторю решение здесь:

Модель:

 using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; ... public class SomeVm : ViewModelBase { public SomeVm() { SelectItemsCommand = new RelayCommand((items) => { Selected.Clear(); foreach (var item in items) Selected.Add((SomeClass)item); }); ViewCommand = new RelayCommand(() => { foreach (var selected in Selected) { // todo do something with selected items } }); } public List Selected { get; set; } public RelayCommand SelectionChangedCommand { get; set; } public RelayCommand ViewCommand { get; set; } } 

XAML:

      ...      ... 
  • Найти элемент WPF внутри DataTemplate в коде
  • Как получить ListBox ItemTemplate, чтобы растянуть по горизонтали всю ширину ListBox?
  • Объединить расширитель и сетку (изменяемый размер расширителя)
  • KeyBinding в UserControl не работает, когда TextBox имеет фокус
  • Взаимоисключающие элементы меню?
  • Приложение WPF, в котором есть только значок в трее
  • Какие подходы доступны для фиктивных данных времени разработки в WPF?
  • Как реализовать воздушное сообщение в приложении WPF
  • наследовать стиль от стиля по умолчанию
  • Как отключить элемент списка ListBox на основе значения свойства?
  • Имеет ли XAML условную директиву компилятора для режима отладки?
  • Давайте будем гением компьютера.