我有一个数据网格,第一列是 Checkbox 类型的 DataGridTemplateColumn。
<DataGridTemplateColumn Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<CheckBox Name="chkSelectForMassRequest" Tag="{Binding AcctNum}" IsChecked="{Binding Path=IsSelected, UpdateSourceTrigger=PropertyChanged}" ClickMode="Press" Unchecked="chkSelectForMassRequest_Checked" Checked="chkSelectForMassRequest_Checked" ></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
奇怪的是,当用户选中几个复选框,然后向下滚动数据网格时,一些复选标记会从原始复选框中消失,并重新出现在新可见的行中,即使用户没有选中它们。 我的问题是,如何保留所有行中的复选标记,无论该行是否可见。 并且,如何防止复选标记在滚动时移动?
提前致谢, 马克
我也尝试更改虚拟化模式,但这对我不起作用。我刚刚完全关闭了虚拟化,这就是完全解决问题的方法。
EnableColumnVirtualization =“False”和EnableRowVirtualization =“False”
我能够使用 Mode='TwoWay' 和 UpdateSourceProtepry='PropertyChange' 解决它
<DataTemplate>
<CheckBox IsChecked="{Binding Yes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center"/>
</DataTemplate>
这是因为 DataGrid 默认启用虚拟化,这与 Binding 中的 UpdateSourceTrigger 指令冲突。
删除 UpdateSourceTrigger 并进行绑定 TwoWay,或者在声明 DataGrid 的 XAML 中添加“VirtualizingStackPanel.VirtualizationMode =“Standard””
如果行对齐中有复选框,您可以尝试添加 EnableColumnVirtualization="False" EnableRowVirtualization="False" 在声明 DataGrid 的 XAML 中
例如。
DataGrid x:名称=“此处”EnableColumnVirtualization =“False”EnableRowVirtualization =“False”
如果您想在保留 DataGrid 虚拟化的同时解决问题,您可以将以下事件添加到 DataGrid 的 PreviewMouseWheel 事件处理程序中:
private DispatcherTimer scrollFinishTimer;
private List<object> previouslySelectedItems = new List<object>();
private List<DataGridCellInfo> previouseSelectedCells = new List<DataGridCellInfo>();
private void grid_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
// When scrolling starts
if (!scrollFinishTimer.IsEnabled)
{
// Save the currently selected items
previouslySelectedItems.Clear();
foreach (var item in base.SelectedItems)
{
previouslySelectedItems.Add(item);
}
foreach(var item in base.SelectedCells)
{
previouseSelectedCells.Add(item);
}
base.UnselectAllCells();
base.UnselectAll();
}
// Reset the timer every time the event is triggered
scrollFinishTimer.Stop();
scrollFinishTimer.Start();
}
scrollFinishTimer 应该这样定义
scrollFinishTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(200) // Or whatever time you prefer.
};
scrollFinishTimer.Tick += ScrollFinishTimer_Tick;
与 ScrollFinishTimer_Tick 为:
private void ScrollFinishTimer_Tick(object sender, EventArgs e)
{
// When the timer ticks, consider scrolling finished.
scrollFinishTimer.Stop();
// Reselect the previously selected items and cells if they're still valid
foreach (var item in previouslySelectedItems)
{
if (base.Items.Contains(item))
{
base.SelectedItems.Add(item);
}
}
foreach(var cell in previouseSelectedCells)
{
if (!base.SelectedCells.Contains(cell))
{
base.SelectedCells.Add(cell);
}
}
}