WinForms - DataGridView - 无选定单元格

13
有没有办法使DataGridView没有选定的单元格?我注意到即使失去了焦点,它仍然至少有一个活动单元格。有其他模式允许这样吗?还是有其他的技巧可以做到这一点?
7个回答

12

7

在选择更改事件中将DataGridView.CurrentCell设置为null的问题是,稍后的事件(如点击)将不会被触发。

对我有效的选项是将选择颜色更改为网格颜色。 因此,选择将不可见。

RowsDefaultCellStyle.SelectionBackColor = BackgroundColor;
RowsDefaultCellStyle.SelectionForeColor = ForeColor;

你的解决方案不会使DataGridView没有选中单元格,这只是外观问题... - nbadaud

7

我发现当我试图获取所需的行为时,DataGridView.CurrentCell = null对我没有作用。

我最终使用的是:

    private void dgvMyGrid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        if (dgvMyGrid.SelectedRows.Count > 0)
        {
            dgvMyGrid.SelectedRows[0].Selected = false;
        }

        dgvMyGrid.SelectionChanged += dgvMyGrid_SelectionChanged;
    }

它需要在 DataBindingComplete 事件处理程序中。

附加 SelectionChanged 事件处理程序的位置不会影响所需的行为,但我在代码片段中保留了它,因为我注意到至少对于我的需求,仅在数据绑定后附加处理程序更好,这样可以避免为每个绑定的项引发选择更改事件。


4
我花了好几个小时才找到这个问题的解决方案。请按照以下步骤操作:
  1. Create a Form Project
  2. Add a DataGridView with the name "DataGridView1"
  3. Add the following code to your class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
    Dim dgvRow(17) As DataGridViewRow
    Dim i As Integer
    For i = 0 To dgvRow.Length - 1
        dgvRow(i) = New DataGridViewRow()
        dgvRow(i).Height = 16
        dgvRow(i).Selected = False
        dgvRow(i).ReadOnly = True
        DataGridView1.Rows.Add(dgvRow(i))
        DataGridView1.CurrentRow.Selected = False
    Next
    End Sub
    
重要的代码行是:
    DataGridView1.CurrentRow.Selected = False

祝你好运!


3

我也遇到过类似的问题,我是按照以下方式解决的:

  1. 'Initial active cell' cleared by dataGridView.ClearSelection().

  2. Clear/Ignore the selection in the event handler, 'CellMouseClick' Event.

    void dataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    
    {
    
        DataGridView dgv = sender as DataGridView;
    
        dgv.ClearSelection();
    
    }
    

1

1

我知道这是一个老问题,WinForms已经被取代了(但在我们的商店里仍然使用),所以这对我们仍然很重要,我认为其他人也会这样。

与其摆弄选择或CurrentCell,我发现实现简单地改变行选择颜色更适合我们的需求。

此外,当失去焦点时,我不再需要跟踪旧的选定单元格,也不必处理当网格在没有焦点时刷新(例如通过计时器)并且无法在焦点返回时“恢复”旧的选定单元格的棘手问题。

除了上面已经发布的解决方案之外,我们不能(也不想)从DataGridView控件继承,而是选择使用组合。下面的代码显示了用于实现功能的类,后面是如何将其“附加”到DataGridView的代码。

/// <summary>
/// Responsible for hiding the selection of a DataGridView row when the control loses focus.
/// </summary>
public class DataGridViewHideSelection : IDisposable
{
    private readonly DataGridView _dataGridView;

    private Color _alternatingRowSelectionBackColor = Color.Empty;
    private Color _alternatingRowSelectionForeColor = Color.Empty;
    private Color _rowSelectionBackColor = Color.Empty;
    private Color _rowSelectionForeColor = Color.Empty;

    /// <summary>
    /// Initializes a new instance of the <see cref="DataGridViewHideSelection"/> class.
    /// </summary>
    /// <param name="dataGridView">The data grid view.</param>
    public DataGridViewHideSelection( DataGridView dataGridView )
    {
        if ( dataGridView == null )
            throw new ArgumentNullException( "dataGridView" );

        _dataGridView = dataGridView;
        _dataGridView.Enter += DataGridView_Enter;
        _dataGridView.Leave += DataGridView_Leave;
    }

    /// <summary>
    /// Handles the Enter event of the DataGridView control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    private void DataGridView_Enter( object sender, EventArgs e )
    {
        // Restore original colour
        if ( _rowSelectionBackColor != Color.Empty )
            _dataGridView.RowsDefaultCellStyle.SelectionBackColor = _rowSelectionBackColor;

        if ( _rowSelectionForeColor != Color.Empty )
            _dataGridView.RowsDefaultCellStyle.SelectionForeColor = _rowSelectionForeColor;

        if ( _alternatingRowSelectionBackColor != Color.Empty )
            _dataGridView.AlternatingRowsDefaultCellStyle.SelectionBackColor = _alternatingRowSelectionBackColor;

        if ( _alternatingRowSelectionForeColor != Color.Empty )
            _dataGridView.AlternatingRowsDefaultCellStyle.SelectionForeColor = _alternatingRowSelectionForeColor;
    }

    /// <summary>
    /// Handles the Leave event of the DataGridView control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    private void DataGridView_Leave( object sender, EventArgs e )
    {
        // Backup original colour
        _rowSelectionBackColor = _dataGridView.RowsDefaultCellStyle.SelectionBackColor;
        _rowSelectionForeColor = _dataGridView.RowsDefaultCellStyle.SelectionForeColor;
        _alternatingRowSelectionBackColor = _dataGridView.RowsDefaultCellStyle.SelectionBackColor;
        _alternatingRowSelectionForeColor = _dataGridView.RowsDefaultCellStyle.SelectionForeColor;

        // Change to "blend" in
        _dataGridView.RowsDefaultCellStyle.SelectionBackColor = _dataGridView.RowsDefaultCellStyle.BackColor;
        _dataGridView.RowsDefaultCellStyle.SelectionForeColor = _dataGridView.RowsDefaultCellStyle.ForeColor;
        _dataGridView.AlternatingRowsDefaultCellStyle.SelectionBackColor = _dataGridView.AlternatingRowsDefaultCellStyle.BackColor;
        _dataGridView.AlternatingRowsDefaultCellStyle.SelectionForeColor = _dataGridView.AlternatingRowsDefaultCellStyle.ForeColor;
    }

    #region IDisposable implementation (for root base class)

    private bool _disposed;

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    /// <remarks>
    /// Called by consumers.
    /// </remarks>
    public void Dispose()
    {
        Dispose( true );
        GC.SuppressFinalize( this );
    }

    /// <summary>
    /// Disposes this instance, with an indication whether it is called from managed code or the GC's finalization of this instance.
    /// </summary>
    /// <remarks>
    /// Overridden by inheritors.
    /// </remarks>
    /// <param name="disposingFromManagedCode">if set to <c>true</c> disposing from managed code.</param>
    protected virtual void Dispose( Boolean disposingFromManagedCode )
    {
        if ( _disposed )
            return;

        // Clean up managed resources here
        if ( disposingFromManagedCode )
        {
            if ( _dataGridView != null )
            {
                _dataGridView.Enter -= DataGridView_Enter;
                _dataGridView.Leave -= DataGridView_Leave;
            }
        }

        // Clean up any unmanaged resources here

        // Signal disposal has been done.
        _disposed = true;
    }

    /// <summary>
    /// Finalize an instance of the <see cref="DataGridViewHideSelection"/> class.
    /// </summary>
    ~DataGridViewHideSelection()
    {
        Dispose( false );
    }

    #endregion
}


/// <summary>
/// Extends data grid view capabilities with additional extension methods.
/// </summary>
public static class DataGridViewExtensions
{
    /// <summary>
    /// Attaches the hide selection behaviour to the specified DataGridView instance.
    /// </summary>
    /// <param name="dataGridView">The data grid view.</param>
    /// <returns></returns>
    /// <exception cref="System.ArgumentNullException">dataGridView</exception>
    public static DataGridViewHideSelection AttachHideSelectionBehaviour( this DataGridView dataGridView )
    {
        if ( dataGridView == null )
            throw new ArgumentNullException( "dataGridView" );

        return new DataGridViewHideSelection( dataGridView );
    }
}

用法: 要使用DataGridViewHideSelection类的实例化,请在不再需要功能时将其处理掉。

var hideSelection = new DataGridViewHideSelection( myGridView );

// ...

/// When no longer needed
hideSelection.Dispose();

或者,您可以使用方便的扩展方法AttachHideSelectionBehaviour()来使生活变得更加轻松。

myDataGrid.AttachHideSelectionBehaviour();

也许对其他人有帮助。

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