有没有办法在 DataGridView 中禁用拖动选择而不禁用 MultiSelect?

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

我正在尝试以表格格式显示数据并允许用户选择单元格。但是,他们应该只能在每列中选择 1 个单元格,这就是需要 MultiSelect 的原因。

每列选择 1 个单元格的示例:

1 cell selection

目前,我有一个实现,每列仅允许 1 个选定的单元格,直到我尝试拖动选择为止。

拖动选择示例:

drag selection

据我所知,如果需要启用多选,则没有内置方法可以禁用拖动选择。

这是当前的实现:

private void TableViewer_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    // Skip headers
    if (e.RowIndex \< 0 || e.ColumnIndex \< 0)
    {
        return;
    }

    // Disable multiple selections within the same column
    var selectedCells = gridViewTableViewer.SelectedCells.Cast<DataGridViewCell>();
    foreach (DataGridViewCell cell in selectedCells)
    {
        if (cell.ColumnIndex == e.ColumnIndex)
        {
            // Another cell in the same column has already been selected.
            cell.Selected = false;
        }
    }
}

我尝试通过

CellMouseDown
MouseUp
事件 +
TableViewer.ClearSelection()
事件内的
CellMouseEnter
来跟踪按住/按下的鼠标左键 (LMB)(如果按住 LMB):

(TableViewer 是一个 DataGridView)

private void TableViewer_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
    if (isMouseDown)
    {
        TableViewer.ClearSelection();
    }
}
private void TableViewer_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    isMouseDown = true;

    ...
}
private void TableViewer_MouseUp(object sender, MouseEventArgs e)
{
    isMouseDown = false;
}

如有任何帮助,我们将不胜感激 - 非常感谢!

c# winforms datagridview
1个回答
0
投票

如果您愿意延长

DataGridView
,您可以尝试检测鼠标拖动并在检测后的短时间内禁用单元格选择。它与下面所示的测试代码一起工作。

class DataGridViewEx : DataGridView
{
    protected override void SetSelectedCellCore(int columnIndex, int rowIndex, bool selected)
    {
        base.SetSelectedCellCore(columnIndex, rowIndex, selected && !_wdtMove.Running);
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (MouseButtons == MouseButtons.Left) _wdtMove.StartOrRestart();
        base.OnMouseMove(e);
    }
    // <PackageReference Include="IVSoftware.Portable.WatchdogTimer" Version="1.2.1" />
    WatchdogTimer _wdtMove = new WatchdogTimer{ Interval = TimeSpan.FromMilliseconds(250)};
}

测试代码

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
            
        dataGridView.DataSource = Records;
        dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        for (int i = 0; i< 10; i++)
        {
            Records.AddNew();
        }
    }
    BindingList<Record> Records { get; } = new BindingList<Record>();
}
    
public class Record
{
    static int _debugCount = 1;
    public Record()
    {
        col1 = col2 = col3 = _debugCount ++;
    }

    public int col1 { get; set; }
    public int col2 { get; set; }
    public int col3 { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.