简体   繁体   English

当SelectionMode =“ Extended”时,DataGrid无法正确取消选择隐藏项

[英]DataGrid doesn't deselect hidden items properly when SelectionMode=“Extended”

I have an issue with WPF DataGrid , which drives me crazy. WPF DataGrid出现问题,这使我发疯。 Let's consider this view model: 让我们考虑一下这种视图模型:

public class ViewModel : INotifyPropertyChanged
{
    public int Id { get; set; }
    public string Name { get; set; }

    public bool IsSelected 
    {
        get { return isSelected; }
        set
        {
            System.Diagnostics.Debug.WriteLine("{0}'s IsSelected new value is: {1}", Name, value);
            if (isSelected != value)
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
    }
    private bool isSelected;

    // INPC implementation
}

... this XAML: ...此XAML:

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid ItemsSource="{Binding}" IsReadOnly="True" AutoGenerateColumns="False" 
                  SelectionMode="Extended" SelectionUnit="FullRow">
            <DataGrid.ItemContainerStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                </Style>
            </DataGrid.ItemContainerStyle>

            <DataGrid.Columns>
                <DataGridCheckBoxColumn Header="Is selected" Binding="{Binding IsSelected}"/>
                <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

...and this code-behind: ...以及以下代码:

public partial class MainWindow : Window
{
    private IList<ViewModel> GenerateViewModels()
    {
        var viewModels = new List<ViewModel>();

        for (var i = 0; i < 100; i++)
        {
            viewModels.Add(new ViewModel
            {
                Id = i,
                Name = string.Format("Item {0}", i)
            });
        }

        return viewModels;
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = GenerateViewModels();
    }
}

Case 1. 情况1。

  • Select Item 0. Item 0 is selected, check box is checked. 选择项目0。选择项目0,选中复选框。
  • Scroll grid's content to hide Item 0. Let the Item 6 be on top of visible area. 滚动网格的内容以隐藏项目0。让项目6位于可见区域的顶部。
  • Select Item 10. Item 10 is selected, check box is checked. 选择项目10。选择项目10,选中复选框。
  • Scroll up to Item 0. 向上滚动到项目0。
  • Select Item 0. Item 10 is selected, check box is not checked. 选择项目0。选择项目10, 选中该复选框。

Debug output: 调试输出:

Item 0's IsSelected new value is: True
Item 0's IsSelected new value is: False
Item 10's IsSelected new value is: True
Item 10's IsSelected new value is: False

截图:

Case 2. 情况2

  • Restart application. 重新启动应用程序。
  • Select several items on top of grid (eg, three first items). 选择网格顶部的几个项目(例如,前三个项目)。 Items are selected, check boxes are checked. 选中项目,选中复选框。
  • Scroll grid's content to hide Item 0. Let the Item 6 be on top of visible area. 滚动网格的内容以隐藏项目0。让项目6位于可见区域的顶部。
  • Select Item 10. Item 10 is selected, check box is checked. 选择项目10。选择项目10,选中复选框。
  • Scroll up to Item 0. 向上滚动到项目0。
  • Item 0 and Item 1 are still checked . 项目0和项目1 仍被选中 Item 2 isn't checked. 没有检查项目2。 All of three first items aren't selected. 没有选择所有三个第一项。

Debug output: 调试输出:

Item 0's IsSelected new value is: True
Item 1's IsSelected new value is: True
Item 2's IsSelected new value is: True
Item 2's IsSelected new value is: False
Item 10's IsSelected new value is: True

截图:

The problem is reproducing, when the selection mode is extended. 当扩展选择模式时,问题正在重现。 When it is single, everything works fine. 当它是单个时,一切正常。

Questions: 问题:
1. Am I missing something? 1.我想念什么吗? 2. Anybody knows a workaround? 2.有人知道解决方法吗?

UPDATE . 更新

I've added SelectionChanged event handler for the grid: 我为网格添加了SelectionChanged事件处理程序:

    private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);
            }
        }

        e.Handled = true;
    }

Debug output says, that SelectedItems collection is updated properly . 调试输出显示, SelectedItems集合已正确更新。 Eg, for the first case output will be: 例如,对于第一种情况,输出为:

Item 0's IsSelected new value is: True
** Item 0 is added to selection.
Item 0's IsSelected new value is: False
Item 10's IsSelected new value is: True
** Item 10 is added to selection.
** Item 0 is removed from selection.
Item 10's IsSelected new value is: False
** Item 0 is added to selection.
** Item 10 is removed from selection.

But the bound data property IsSelected isn't updated! 但是绑定数据属性IsSelected不会更新!

At least, one workaround is found, and its related to the question's update. 至少找到了一种解决方法,它与问题的更新有关。
Let's modify SelectionChanged event handler a little: 让我们对SelectionChanged事件处理程序进行一些修改:

    private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);

                if (!item.IsSelected)
                {
                    // if bound data item still isn't selected, fix this
                    item.IsSelected = true;
                }
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);

                if (item.IsSelected)
                {
                    // if bound data item still is selected, fix this
                    item.IsSelected = false;
                }
            }
        }

        e.Handled = true;
    }

But it's definitely a bug in DataGrid , isn't it? 但这绝对是DataGrid的错误,不是吗?

I tried it and I think you need to set the isSelected to false to both condition. 我尝试了一下,我认为您需要同时将isSelected设置为false。 It works for me. 这个对我有用。 But thanks for the initial solution! 但是感谢您的最初解决方案! It helped me a lot. 这对我帮助很大。

private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);

                if (!item.IsSelected)
                {
                    // if bound data item still isn't selected, fix this
                    item.IsSelected = false;
                }
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);

                if (item.IsSelected)
                {
                    // if bound data item still is selected, fix this
                    item.IsSelected = false;
                }
            }
        }

        e.Handled = true;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WPF Datagrid不会取消选择隐藏项 - WPF Datagrid doesn't deselect hidden items 如何获得绑定到DataTable的DataGrid SelectionMode =“ Extended” SelectionUnit =“ Cell”的选择 - How to get selection of DataGrid SelectionMode=“Extended” SelectionUnit=“Cell” Binded to DataTable 如何使用 SelectionMode=&quot;Extended&quot; 在 MVVM 中设置所选项目? - How to set selected items in MVVM using SelectionMode=“Extended”? 使用SelectionMode = Extended选择列表框 - Listbox IsSelected with SelectionMode=Extended 当我将ListBox SelectionMode设置为“ None”时,它不会对DataSource的更改做出反应 - When I set the ListBox SelectionMode to “None”, it doesn't react to DataSource changes 使用SelectionMode Multiple / Extended在多个嵌套ListBox中获取所有选定项 - Get all selected items across multiple nested ListBoxes with SelectionMode Multiple/Extended WPF扩展工具包CheckComboBox不显示项目 - WPF Extended Toolkit CheckComboBox doesn't display items WPF Datagrid - 在DataGrid中单击空格时取消选择所选项 - WPF Datagrid - deselect selected item(s) when clicking whitespace in the DataGrid 如何将数据绑定并填充/显示从ListBox选定项的DataGrid或UniformGrid(SelectionMode = Multiple) - How to bind data and fill/display to DataGrid or UniformGrid from ListBox selected items (SelectionMode=Multiple) 行折叠时,DataGrid不会调整大小 - DataGrid doesn't resize when rows are collapsed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM