当选择模式为"Extended"时,我如何使DataGrid在单击时取消选定?

6
WPF的默认行为是在单击行时选择DataGrid,如果SelectionMode="Extended",这正是我想要的,但是我也希望在单击已选择的行时取消选择该行。我尝试了以下方法,但它会在选定行之后立即取消选择,似乎是鼠标单击事件发生之前发生了行选择。
private void DoGridMouseLeftButtonUp(object sender, MouseButtonEventArgs args) {
    // Get source row.
    DependencyObject source = (DependencyObject)args.OriginalSource;
    var row = source.FindParent<DataGridRow>();
    if (row == null)
        return;
    // If selected, unselect.
    if (row.IsSelected) {
        row.IsSelected = false;
        args.Handled = true;
    }
}

我正在使用以下表格绑定到此事件。

<DataGrid SelectionMode="Extended"
          SelectionUnit="FullRow"
          MouseLeftButtonUp="DoGridMouseLeftButtonUp">

1
用户不应该自己取消先前选择的行吗?用户只需单击“Ctrl”+“左键”即可完成此操作。 - blindmeis
我错过了datagrid标签,对此感到抱歉。 - Adrian Fâciu
1
@blindmeis - 通常来说这没问题,但是 WPF 的 DataGrid 行为不太标准。通常情况下,控件需要按 CTRL+CLICK 来进行添加和移除,但 DataGrid 只需要按 CTRL 就可以进行移除。我们的目标受众是普通用户,他们会发现直接单击行以选择/取消选择要简单得多。 - Brett Ryan
2个回答

4

我已经成功解决了这个问题,方法是不直接在格子上处理事件,而是在单元格上进行处理。具体操作包括为DataGridCell设置事件触发器,代码如下:

<DataGrid SelectionMode="Extended"
          SelectionUnit="FullRow">
    <DataGrid.Resources>
        <Style TargetType="{x:Type DataGridCell}">
            <EventSetter Event="PreviewMouseLeftButtonDown"
                         Handler="DoCheckRow"/>
        </Style>
    </DataGrid.Resources>
    <!-- Column mapping omitted. -->
</DataGrid>

事件处理程序代码。
public void DoCheckRow(object sender, MouseButtonEventArgs e) {
    DataGridCell cell = sender as DataGridCell;
    if (cell != null && !cell.IsEditing) {
        DataGridRow row = FindVisualParent<DataGridRow>(cell);
        if (row != null) {
            row.IsSelected = !row.IsSelected;
            e.Handled = true;
        }
    }
}

我的网格是只读的,因此在这里忽略任何编辑行为。


这个代码是有效的,但是当我在CellTemplate中添加一个按钮时,它的事件不会被触发,因为我们设置了e.Handled = true。有什么办法可以解决这个问题吗? - Chris Klepeis
我已经解决了我的问题。问题/答案在这里http://stackoverflow.com/a/12113645/71904。 - Chris Klepeis
太好了,我也在考虑提到类似的事情,但是我手头没有Windows电脑来进行测试,很高兴听到你的工作正常。 - Brett Ryan

0

我的WPF数据表格需要使用CTRL+CLICK来添加或删除多个行,这是标准行为;) 但无论如何,你为什么不使用PreviewMouseDown事件,然后检查左鼠标按钮和Ctrl键,并执行取消选择逻辑并设置e.handled=true?


奇怪,我在.NET 4中不需要按CTRL键来进行加法。今晚我会检查预览事件,谢谢。 - Brett Ryan
很奇怪,我也使用 .NET4,如果我想选择每第三行,例如,我需要使用CTRL键。 - blindmeis
PreviewMouseLeftButtonUp 上取消选定会导致与非预览事件相同的行为,即在选择后立即取消选择。不过我有一个解决方案。 - Brett Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接