简体   繁体   中英

WPF selectAll/unselectAll rows of a DataGrid with MVVM

I have a WPF DataGrid, the ItemsSource property is bound to the viewmodel. On click on a Button a method is doing work on the selected rows of the DataGrid. When the work is done, I would like to unselectAll the DataGrid's rows from the viewmodel, how can I achieve this in a MVVM way?

XAML:

<DataGrid AutoGenerateColumns="False"
     ItemsSource="{Binding ObCol_View}"
     SelectedItem="{Binding SelectedItem}

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <GalaCmd:EventToCommand Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding SelectedItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>

<Button Content="Apply" Command="{Binding PerformCommand}"/>

The viewmodel

public class ViewModelprices_manager<T> : WindowViewModel
{
    public ViewModelprices_manager()
    {
        SelectionChangedCommand = new RelayCommand<IList>
        (items =>
            {
                SelectedItems = items;
            }
        );

        myObCol_View = new ObservableCollection<View_prices_manager<T>>();
    }

    public IList SelectedItems { get; set; }

    private readonly ObservableCollection<View_prices_manager<T>> myObCol_View;
    public ObservableCollection<View_prices_manager<T>> ObCol_View_Parametric { get { return myObCol_View; } }

    public RelayCommand<IList> SelectionChangedCommand
    {
        get;
        private set;
    }

    private RelayCommand myPerformCommand;

    public RelayCommand PerformCommand
    {
        get
        {
            if (myPerformCommand == null)
                myPerformCommand = new RelayCommand(PerformCommandAction);

            return myPerformCommand;
        }
    }

    private void PerformCommandAction()
    {
        perform();
    }

    public void perform()
    {
        foreach (View_prices_manager<T> item in SelectedItems)
        {
            item.Price *= ratio;
        }

        //DataGrid.UnselectAll <-- Here I want to unselect all to reset the selection in SelectedItems
    }
}

To clear the selection the MVVM way.

Bind to the SelectedItem property to the view model:

<DataGrid SelectedItem="{Binding SelectedItem, Mode=TwoWay}">

And set the SelectItem to null in your code:

viewModel.SelectItem = null;

Of course, your viewModel class must implement INotifyPropertyChanged properly.

The topic is reopened, I would like to see your solution

A simplified example.
If you need any additional details, then write which ones and I will add or explain them.

The example uses the BaseInpc and RelayCommand classes.

Collection item class :

using Simplified;

namespace ClearSelectedItems
{
    public class Product : BaseInpc
    {
        private string _title;
        private decimal _price;

        public string Title { get => _title; set => Set(ref _title, value); }
        public decimal Price { get => _price; set => Set(ref _price, value); }
    }
}

ViewModel :

using Simplified;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;

namespace ClearSelectedItems
{
    public class ProductsViewModel
    {
        public IList SelectedProducts{ get; set; }

        public decimal Ratio { get; set; }

        private ICommand _performCommand;
        public ICommand PerformCommand => _performCommand
            ?? (_performCommand = new RelayCommand(PerformExecute));

        private void PerformExecute(object parameter)
        {
            foreach (var product in SelectedProducts.Cast<Product>())
            {
                product.Price *= Ratio;
            }

            // Clearing selection
            SelectedProducts.Clear();
        }

        // An example of filling a collection
        public List<Product> Products { get; }
            = new List<Product>()
            {
                new Product() { Title = "IPhone", Price=1500},
                new Product() { Title = "Samsung", Price=1200},
                new Product() { Title = "Nokia", Price=1000},
                new Product() { Title = "LG", Price=500}
           };
    }
}

Class of static handlers . Used for simplicity, so as not to create Behavior.

using System;
using System.Windows.Controls.Primitives;

namespace ClearSelectedItems
{
    public static class Handlers
    {
        public static EventHandler OnDataGridInitialized { get; } = (sender, e) =>
        {
            MultiSelector selector = (MultiSelector)sender;
            ProductsViewModel viewModel = (ProductsViewModel)selector.DataContext;
            viewModel.SelectedProducts = selector.SelectedItems;
        };
    }
}

Window XAML :

<Window x:Class="ClearSelectedItems.ExampleWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ClearSelectedItems"
        mc:Ignorable="d"
        Title="ExampleWindow" Height="450" Width="400">
    <Window.DataContext>
        <local:ProductsViewModel/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Products}"
                  Initialized="{x:Static local:Handlers.OnDataGridInitialized}"/>
        
        <TextBox Text="{Binding Ratio}" VerticalAlignment="Bottom" HorizontalAlignment="Left" 
                 MinWidth="100" Margin="5" Padding="15 5"/>
        
        <Button Content="Apply Ratio" Command="{Binding PerformCommand}"
                Margin="5" Padding="15 5"
                HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
    </Grid>
</Window>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM