WPF 复选框检查在滚动时移动

问题描述 投票:0回答:5

我有一个数据网格,第一列是 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>

奇怪的是,当用户选中几个复选框,然后向下滚动数据网格时,一些复选标记会从原始复选框中消失,并重新出现在新可见的行中,即使用户没有选中它们。 我的问题是,如何保留所有行中的复选标记,无论该行是否可见。 并且,如何防止复选标记在滚动时移动?

提前致谢, 马克

wpf checkbox datagrid
5个回答
2
投票

我也尝试更改虚拟化模式,但这对我不起作用。我刚刚完全关闭了虚拟化,这就是完全解决问题的方法。

EnableColumnVirtualization =“False”和EnableRowVirtualization =“False”


2
投票

我能够使用 Mode='TwoWay' 和 UpdateSourceProtepry='PropertyChange' 解决它

 <DataTemplate>
<CheckBox IsChecked="{Binding Yes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center"/>
</DataTemplate>

0
投票

这是因为 DataGrid 默认启用虚拟化,这与 Binding 中的 UpdateSourceTrigger 指令冲突。

删除 UpdateSourceTrigger 并进行绑定 TwoWay,或者在声明 DataGrid 的 XAML 中添加“VirtualizingStackPanel.VirtualizationMode =“Standard””


0
投票

如果行对齐中有复选框,您可以尝试添加 EnableColumnVirtualization="False" EnableRowVirtualization="False" 在声明 DataGrid 的 XAML 中

例如。

DataGrid x:名称=“此处”EnableColumnVirtualization =“False”EnableRowVirtualization =“False”


0
投票

如果您想在保留 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);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.