2016-11-30 3 views
0

У меня есть дата-схема, которая отображает все записи, которые существуют в таблице базы данных SQL, и я хотел бы добавить одну кнопку в свой пользовательский интерфейс, который позволяет пользователям удалять запись) он выбрал. Большинство ссылок, которые я нашел для этого, вращаются вокруг добавления кнопки удаления в каждую строку или связаны с кодом. Я использую шаблон MVVM, и я не хочу кнопки в каждой строке. В настоящее время я могу удалить одну запись за раз, но вам нужна помощь в том, как выполнять итерацию по выбранным элементам. Мой код выглядит следующим образом:Как удалить несколько выбранных строк на datagrid

XAML

  <Button x:Name="revokeBtn" 
       Grid.Row="0" 
       Grid.Column="4" 
       ToolTip="Revoke Selected License or Licenses" 
       Content="Revoke" 
       Command="{Binding RevokeSelectedCommand}" 
       CommandParameter="{Binding}"> 
     </Button> 

     <DataGrid x:Name="licenseGrid" 
        ItemsSource="{Binding LoggedUsers}" 
        SelectedItem="{Binding SelectedLicenses}" 
        Style="{DynamicResource DataGridStyle}" 
        Grid.Row="2" 
        Grid.Column="1" 
        Grid.ColumnSpan="6" 
        Height="535" 
        VerticalAlignment="Top" 
        IsReadOnly="True" 
        AutoGenerateColumns="False" 
        HeadersVisibility="Column" 
        SelectionMode="Extended" 
        CanUserDeleteRows="True" 
        EnableRowVirtualization="False"> 
      <DataGrid.RowStyle> 
       <Style TargetType="DataGridRow"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected}" /> 
       </Style> 
      </DataGrid.RowStyle> 

С DataGrid.Columns, привязанных к столбцам таблицы.

ViewModel

public ObservableCollection<MD_LoggedUsersModel> LoggedUsers 
    { 
     get { return _loggedUsers; } 
     set { _loggedUsers = value; NotifyPropertyChanged(nameof(LoggedUsers)); } 
    } 

    public MD_LoggedUsersModel SelectedLicenses 
    { 
     get 
     { 
      return _selectedLicenses; 
     } 
     set 
     { 
      if (_selectedLicenses != value) 
      { 
       _selectedLicenses = value; 
       OnPropertyChanged(nameof(SelectedLicenses)); 
      } 
      if (_selectedLicenses == null) 
      { 
       LoadData(); 
      } 
     } 
    } 

    public bool IsSelected 
    { 
     get 
     { 
      return _isSelected; 
     } 
     set 
     { 
      if (_isSelected == value) return; 
      _isSelected = value; 
      OnPropertyChanged(nameof(IsSelected)); 
     } 
    } 

    public ICommand RevokeSelectedCommand 
    { 
     get 
     { 
      return _revokeSelectedCommand ?? (_revokeSelectedCommand = new CommandHandler(() => RevokeSelected(), _canExecute)); 
     } 
    } 
    private void RevokeSelected() 
    {need to iterate through selected rows here} 

Что является лучшим способом для достижения этой цели?

+0

Способ, которым я всегда занимался с выбранными строками, заключается в том, чтобы добавить столбец CheckBox в сетку, привязанную к свойству IsSelected в классе. Затем вы можете перебирать свою коллекцию, удалять элементы из DataSource и уведомлять пользовательский интерфейс об изменении. –

+0

Если доступна возможность выбора нескольких строк с помощью Ctrl + щелчка мыши, я должен поверить, что флажок не нужен, d скорее не возьмите этот маршрут. –

ответ

0

Учитывая отсутствие ответов на это сообщение, а также нехватку ресурсов, которые я могу найти по этому вопросу, я выбрал кнопку в каждой строке, которая работает правильно.

0

Я уже имел эту проблему несколько месяцев назад, и для этого я написал следующее прикрепленное свойство:

public class MultiSelectorExtensions 
    { 
     public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached(
      "SelectedItems", 
      typeof(INotifyCollectionChanged), 
      typeof(MultiSelectorExtensions), 
      new PropertyMetadata(default(INotifyCollectionChanged), OnSelectedItemsChanged)); 

     private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      MultiSelector multiSelectorControl = d as MultiSelector; 

      NotifyCollectionChangedEventHandler handler = (sender, args) => 
      { 
       if (multiSelectorControl != null) 
       { 
        IList listSelectedItems = multiSelectorControl.SelectedItems; 
        if (args.OldItems != null) 
        { 
         foreach (var item in args.OldItems) 
         { 
          if (listSelectedItems.Contains(item)) 
           listSelectedItems.Remove(item); 
         } 
        } 

        if (args.NewItems != null) 
        { 
         foreach (var item in args.NewItems) 
         { 
          if (!listSelectedItems.Contains(item)) 
           listSelectedItems.Add(item); 
         } 
        } 
       } 
      }; 

      if (e.OldValue == null && multiSelectorControl != null) 
      { 
       multiSelectorControl.SelectionChanged += OnSelectionChanged; 
      } 

      if (e.OldValue is INotifyCollectionChanged) 
      { 
       (e.OldValue as INotifyCollectionChanged).CollectionChanged -= handler; 
      } 

      if (e.NewValue is INotifyCollectionChanged) 
      { 
       (e.NewValue as INotifyCollectionChanged).CollectionChanged += handler; 
      } 

     } 

     private static void OnSelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      DependencyObject d = sender as DependencyObject; 

      if (GetSelectionChangedInProgress(d)) 
       return; 

      SetSelectionChangedInProgress(d, true); 

      dynamic selectedItems = GetSelectedItems(d); 

      try 
      { 
       foreach (dynamic item in e.RemovedItems.Cast<dynamic>().Where(item => selectedItems.Contains(item))) 
       { 
        selectedItems.Remove(item); 
       } 
      } 
      catch (Exception) { } 

      try 
      { 
       foreach (dynamic item in e.AddedItems.Cast<dynamic>().Where(item => !selectedItems.Contains(item))) 
       { 
        selectedItems.Add(item); 
       } 
      } 
      catch (Exception){} 

      SetSelectionChangedInProgress(d, false); 
     } 

     public static void SetSelectedItems(DependencyObject element, INotifyCollectionChanged value) 
     { 
      element.SetValue(SelectedItemsProperty, value); 
     } 

     public static INotifyCollectionChanged GetSelectedItems(DependencyObject element) 
     { 
      return (INotifyCollectionChanged)element.GetValue(SelectedItemsProperty); 
     } 

     private static readonly DependencyProperty SelectionChangedInProgressProperty = DependencyProperty.RegisterAttached(
      "SelectionChangedInProgress", 
      typeof(bool), 
      typeof(MultiSelectorExtensions), 
      new PropertyMetadata(default(bool))); 

     private static void SetSelectionChangedInProgress(DependencyObject element, bool value) 
     { 
      element.SetValue(SelectionChangedInProgressProperty, value); 
     } 

     private static bool GetSelectionChangedInProgress(DependencyObject element) 
     { 
      return (bool)element.GetValue(SelectionChangedInProgressProperty); 
     } 
    } 

В вашем DataGrid в окне вы должны будете использовать это вложенное свойство, как :

<DataGrid x:Name="licenseGrid" 
      ItemsSource="{Binding LoggedUsers}" 
      SelectedItem="{Binding SelectedLicenses}" 
      Style="{DynamicResource DataGridStyle}" 
      Grid.Row="2" 
      Grid.Column="1" 
      Grid.ColumnSpan="6" 
      Height="535" 
      VerticalAlignment="Top" 
      IsReadOnly="True" 
      AutoGenerateColumns="False" 
      HeadersVisibility="Column" 
      SelectionMode="Extended" 
      CanUserDeleteRows="True" 
      EnableRowVirtualization="False" 
      MyAttachedProperties:MultiSelectorExtensions.SelectedItems="{Binding SelectedLoggedUsers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGrid> 

MyAttachedProperties это пространство имен, где находится MultiSelectorExtension класса.

И в вашем ViewModel вы тогда имеете свойство, которое выглядит как:

private ObservableCollection<MD_LoggedUsersModel> selectedLoggedUsers; 
public ObservableCollection<MD_LoggedUsersModel> SelectedLoggedUsers 
{ 
    get { return selectedLoggedUsers; } 
    set 
    { 
     selectedLoggedUsers = value; 
     NotifyPropertyChanged(nameof(SelectedLoggedUsers)); 
    } 
} 

Важно: В конструкторе ViewModel вы должны инициализировать SelectedLoggedUsers с

SelectedLoggedUsers = new ObservableCollection<MD_LoggedUsersModel>(); 

иначе недвижимость будет null, а прикрепленное свойство не будет работать.

Смежные вопросы