WPF DataGrid 多选绑定

Posted

技术标签:

【中文标题】WPF DataGrid 多选绑定【英文标题】:WPF DataGrid multiselect binding 【发布时间】:2011-02-06 14:24:50 【问题描述】:

我有一个启用多选的数据网格。我需要更改视图模型中的选择。但是,SelectedItems 属性是只读的,不能直接绑定到视图模型中的属性。那么如何向视图发出选择已更改的信号呢?

【问题讨论】:

另见***.com/questions/1579700/… 【参考方案1】:

我对@9​​87654321@ 的使用不多,但一种适用于ListView 的技术是绑定到单个ListViewItemIsSelected 属性。只需为列表中的每个对象将其设置为 true,然后它就会被选中。

也许DataGrid 中表示一行的对象也有IsSelected 属性,也可以这样使用?

【讨论】:

【参考方案2】:

安迪是对的。 DataGridRow.IsSelected 是一个依赖属性,可以通过数据绑定来控制来自 ViewModel 的选择。下面的示例代码演示了这一点:

<Window x:Class="DataGridMultiSelectSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <tk:DataGrid AutoGenerateColumns="False" ItemsSource="Binding" EnableRowVirtualization="False">
            <tk:DataGrid.Columns>
                <tk:DataGridTextColumn Header="Value" Binding="Binding Value" />
            </tk:DataGrid.Columns>
            <tk:DataGrid.RowStyle>
                <Style TargetType="tk:DataGridRow">
                    <Setter Property="IsSelected" Value="Binding IsSelected, Mode=TwoWay" />
                </Style>
            </tk:DataGrid.RowStyle>
        </tk:DataGrid>
        <Button Content="Select Even" Click="Even_Click" />
        <Button Content="Select Odd" Click="Odd_Click" />
    </StackPanel>
</Window>

using System.ComponentModel;
using System.Windows;

namespace DataGridMultiSelectSample

    public partial class Window1
    
        public Window1()
        
            InitializeComponent();
            DataContext = new[]
                              
                                  new MyViewModel Value = "Able",
                                  new MyViewModel Value = "Baker",
                                  new MyViewModel Value = "Charlie",
                                  new MyViewModel Value = "Dog",
                                  new MyViewModel Value = "Fox",
                              ;
        

        private void Even_Click(object sender, RoutedEventArgs e)
        
            var array = (MyViewModel[]) DataContext;
            for (int i = 0; i < array.Length; ++i)
                array[i].IsSelected = i%2 == 0;
        

        private void Odd_Click(object sender, RoutedEventArgs e)
        
            var array = (MyViewModel[])DataContext;
            for (int i = 0; i < array.Length; ++i)
                array[i].IsSelected = i % 2 == 1;
        
    

    public class MyViewModel : INotifyPropertyChanged
    
        public string Value  get; set; 

        private bool mIsSelected;
        public bool IsSelected
        
            get  return mIsSelected; 
            set
            
                if (mIsSelected == value) return;
                mIsSelected = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
            
        

        public event PropertyChangedEventHandler PropertyChanged;
    

请务必在 DataGrid 元素上设置 EnableRowVirtualisation="False",否则 IsSelected 绑定可能会失衡。

【讨论】:

完美。并感谢示例代码 - 很好地说明了它。 谢谢。希望您不介意我在您的示例中添加EnableRowVirtualisation="False",因为没有它,就会出现绑定不在新行上的错误。【参考方案3】:

伙计们,感谢您的帮助。我的问题解决了。我认为这个问题对于新的 WPF 开发人员来说很常见,所以我将在此处重申我的问题以及更详细的解决方案,以防其他人遇到相同类型的问题。

问题:我有一个启用多选的音频文件数据网格。网格有多个列标题。用户可以多选几行。当他单击“播放”按钮时,音频文件将按列标题(例如 A 列)的顺序播放。播放开始时,多选被清除,仅突出显示当前播放的文件。当所有文件的播放结束时,将重新显示多选。回放在视图模型中完成。如您所见,这里有两个问题:1)如何从viewmodel中选择当前正在播放的文件,以及2)如何从viewmodel中向视图发出播放完成并重新显示多选的信号。 /p>

解决方案:为了解决第一个问题,我在视图模型中创建了一个属性,该属性绑定到视图的 SelectedIndex 属性来选择当前正在播放的文件。为了解决第二个问题,我在视图模型中创建了一个布尔属性来指示播放完成。在后面的视图代码中,我订阅了布尔属性的 PropertyChanged 事件。在事件处理程序中,视图的 SelectedItems 属性是从保存的多选中重新创建的(SelectedItems 的内容被保存到列表中,并且 SelectedItems 在播放开始时被清除)。起初,我在重新创建 SelectedItems 时遇到了麻烦。事实证明,问题是由于重新创建是通过第二个线程启动的。 WPF 不允许这样做。解决方案是使用 Dispatcher.Invoke() 让主线程完成工作。对于有经验的开发者来说,这可能是一个非常简单的问题,但对于新手来说,这是一个小挑战。无论如何,来自不同人的很多帮助。

【讨论】:

【参考方案4】:

只需在任何 MultiSelector 派生类上使用 SelectedItems,并在它返回的 IList 上使用 Add、Remove、Clear 方法。

【讨论】:

以上是关于WPF DataGrid 多选绑定的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 中使用 Datagrid 的多选复选框

WPF DataGrid CheckBox 多选 反选 全选

WPF DataGrid CheckBox 多选 反选 全选

WPF Datagrid - 行的编程选择似乎打破了多选(特别是shift-click多选)

wpf datagrid根据多选选中的获取单元格内容,进行操作数据

wpf datagrid 怎么增加数据行