【发布时间】:2025-12-13 12:30:01
【问题描述】:
我遇到了 WPF DataGrid 的问题,这让我抓狂。
让我们考虑一下这个视图模型:
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>
...还有这个代码隐藏:
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 项未选中。前三个项目未全部选中。
调试输出:
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.单身时,一切正常。
问题:
1.我错过了什么吗?
2. 有人知道解决方法吗?
更新。
我为网格添加了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;
}
调试输出显示,SelectedItems 集合已正确更新。例如,对于第一种情况,输出将是:
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 没有更新!
【问题讨论】:
-
没什么可补充的,除了同样的问题也让我发疯。这完全违反直觉。
标签: c# wpf wpfdatagrid