【问题标题】:WPF selectAll/unselectAll rows of a DataGrid with MVVM带有 MVVM 的 DataGrid 的 WPF selectAll/unselectAll 行
【发布时间】:2021-08-06 23:29:28
【问题描述】:

我有一个 WPF DataGrid,ItemsSource 属性绑定到视图模型。 单击按钮时,方法正在对 DataGrid 的选定行进行操作。 工作完成后,我想从视图模型中取消选择 DataGrid 的所有行,如何以 MVVM 方式实现?

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}"/>

视图模型

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

【问题讨论】:

  • 您正在使用 SelectedItems 列表。在此属性中,您有一个指向 DataGrid.SelectedItems 的链接。处理完后,只需要清空这个列表SelectedItems.Clear()即可。另外,在我看来,您对 SelectionChangedCommand 的实现并不完全正确。它的唯一功能是获取 SelectedItems 列表。但是这个列表在 DataGrid 中没有改变。只有其中的元素被更改(添加、删除)。因此,在 DataGrid 初始化(或加载)之后弹出一次这个列表就足够了。
  • 这个实现的原因是 SelectedItems 属性是只读属性。即使启用了 EnableRowVirtualization 属性,此实现也允许我获取选定项。也可以通过一种行为来做到这一点。所以 SelectedItems.Clear() 对 DataGrid 的选择没有影响。
  • 我明白了,你是对的!我确实误会了。可惜这个话题已经关闭了。
  • 向问题添加澄清细节并要求打开它。或者创建一个新主题,但不是重复的,而是包含所有指定细节,包括所有自定义类型的实现(以简化的形式)。这样其他人就可以将您的代码复制到他们的项目中并运行它。
  • 话题重开,想看看你的解决方案,非常感谢!

标签: c# wpf mvvm binding datagrid


【解决方案1】:

以 MVVM 方式清除选择。

将SelectedItem 属性绑定到视图模型:

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

并在您的代码中将SelectItem 设置为null:

viewModel.SelectItem = null;

当然,您的viewModel 类必须正确实现INotifyPropertyChanged。

【讨论】:

  • 是的,谢谢!来自视图模型的关于 sellectAll 的想法?
  • 我看不到使用当前DataGrid 实现的方法。也许AreAllItemSelected 附加属性可以解决问题。
【解决方案2】:

话题重开,我想看看你的解决方案

一个简化的例子。
如果您需要任何其他详细信息,请写下哪些,我会添加或解释它们。

该示例使用BaseInpc and RelayCommand 类。

收藏品类:

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

视图模型:

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

静态处理程序类。 用于简单起见,以免创建 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;
        };
    }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 2020-11-28
    • 2017-10-29
    • 2010-12-17
    • 2021-07-04
    • 2023-03-14
    • 2013-08-03
    • 2018-02-11
    相关资源
    最近更新 更多