当SelectionMode ="Extended"时,DataGrid无法正确取消选择隐藏项. [英] DataGrid doesn't deselect hidden items properly when SelectionMode="Extended"
问题描述
我对WPF DataGrid
有问题,这使我发疯.让我们考虑一下这种视图模型:
I have an issue with WPF DataGrid
, which drives me crazy.
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
}
...此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();
}
}
案例1.
- 选择项目0.选择项目0,选中复选框.
- 滚动网格的内容以隐藏项目0.让项目6位于可见区域的顶部.
- 选择项目10.选中项目10,选中此复选框.
- 向上滚动到项目0.
- 选择项目0.选择项目10,未选中未复选框.
调试输出:
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
案例2.
- 重新启动应用程序.
- 在网格顶部选择几个项目(例如,三个第一项).选中项目,选中复选框.
- 滚动网格的内容以隐藏项目0.让项目6位于可见区域的顶部.
- 选择项目10.选中项目10,选中此复选框.
- 向上滚动到项目0.
- 项目0和项目1 仍处于选中状态.未选中第2项.未选中所有前三个项.
- Restart application.
- Select several items on top of grid (e.g., 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.
- Select Item 10. Item 10 is selected, check box is checked.
- Scroll up to Item 0.
- Item 0 and Item 1 are still checked. Item 2 isn't checked. All of three first items aren't selected.
调试输出:
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.
问题:
1.我想念什么吗?2.有人知道解决方法吗?
Questions:
1. Am I missing something?
2. Anybody knows a workaround?
更新.
我为网格添加了 SelectionChanged
事件处理程序:
I've added SelectionChanged
event handler for the grid:
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输出说, SelectedItems
集合已正确更新.例如,在第一种情况下,输出为:
Debug output says, that SelectedItems
collection is updated properly. E.g., 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.
但是绑定数据属性 IsSelected
不会更新!
But the bound data property IsSelected
isn't updated!
推荐答案
至少找到了一种解决方法,它与问题的更新有关.
让我们对 SelectionChanged
事件处理程序进行一些修改:
At least, one workaround is found, and its related to the question's update.
Let's modify SelectionChanged
event handler a little:
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;
}
但这绝对是 DataGrid
中的错误,不是吗?
But it's definitely a bug in DataGrid
, isn't it?
这篇关于当SelectionMode ="Extended"时,DataGrid无法正确取消选择隐藏项.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!