.net WinForms - DataGridView - 没有选择单元格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/341018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:45:45  来源:igfitidea点击:

WinForms - DataGridView - no cell selected

.netwinformsdatagridview

提问by BuddyJoe

Is there a way to make a DataGridView have no cell selected? I notice even when it loses focus() it has a at least one active cell. Is there another mode that allows this? or some other trick?

有没有办法让 DataGridView 没有选择单元格?我注意到即使它失去了 focus() ,它也至少有一个活动单元格。是否有另一种模式允许这样做?或其他一些技巧?

采纳答案by Aleris

DataGridView.CurrentCell property can be used to clear the focus rectangle.

DataGridView.CurrentCell 属性可用于清除焦点矩形。

You can set this property (DataGridView.CurrentCell) to null to temporarily remove the focus rectangle, but when the control receives focus and the value of this property is null, it is automatically set to the value of the FirstDisplayedCell property.

您可以将此属性 (DataGridView.CurrentCell) 设置为 null 以暂时移除焦点矩形,但是当控件接收到焦点且此属性的值为 null 时,它会自动设置为 FirstDisplayedCell 属性的值。

http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcell.aspx

http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcell.aspx

回答by David Hall

I found that the DataGridView.CurrentCell = nulldidn't work for me when trying to get the requested behaviour.

我发现DataGridView.CurrentCell = null在尝试获得请求的行为时对我不起作用。

What I ended up using was:

我最终使用的是:

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

        dgvMyGrid.SelectionChanged += dgvMyGrid_SelectionChanged;
    }

It needed to be in the DataBindingCompleteevent handler.

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

Where you attach the SelectionChangedevent handler doesn't affect the desired behaviour but I left it in the code snippet because I noticed for my needs at least it was better to only attach the handler after databinding, so that I avoid a selection changed event being raised for each item bound.

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

回答by J. Ouwehand

The problem with setting the DataGridView.CurrentCell to null on the selection change event is that later events (like click) will not be hit.

在选择更改事件上将 DataGridView.CurrentCell 设置为 null 的问题是不会命中以后的事件(如单击)。

The option that worked for me was to change the selection color to the grid color. The selection will therefore not be visible.

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

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

回答by J. Ouwehand

I spent hours to find the solution for this problem. Do this:

我花了几个小时来找到这个问题的解决方案。做这个:

  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
    
  1. 创建表单项目
  2. 添加名为“DataGridView1”的 DataGridView
  3. 将以下代码添加到您的类 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
    

The importaint line of code is

重要的代码行是

    DataGridView1.CurrentRow.Selected = False

Good luck!

祝你好运!

回答by KbManu

I had similar problem and I followed this way:

我遇到了类似的问题,我遵循了以下方法:

  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. dataGridView.ClearSelection() 清除了“初始活动单元格”。

  2. 清除/忽略事件处理程序“CellMouseClick”事件中的选择。

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

回答by Jaans

I know this is an old question and WinForms is superseded (but not for a long while still in our shop anyway), so this is still relevant to us and I suspect a few others too.

我知道这是一个老问题,WinForms 已被取代(但无论如何也不会在我们的商店中持续很长时间),所以这仍然与我们相关,我也怀疑其他一些问题。

Instead of fiddling with the selection or CurrentCell, I found the implementation to simply change the row selection colours much more suitable for our needs.

而不是摆弄选择 or CurrentCell,我发现实现简单地更改行选择颜色更适合我们的需要。

In addition I no longer have to keep track of the old selected cell when losing focus nor have deal with the tricky issue when the grid is refreshed when not focus (like by a timer) and the old selected cell cannot be "restored" when focus is returned.

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

In addition to the solutions already posted above, we couldn't (didn't want to) inherit from the DataGridViewcontrol and instead opted to use composition. The code below shows the class used to implement the functionality, followed by code on how to use it to "attach" the behaviour to a DataGridView.

除了上面已经发布的解决方案之外,我们不能(不想)从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 );
    }
}

Usage:To use instantiate an instance of the DataGridViewHideSelection class and dispose of it when you don't need functionality any-more.

用法:使用实例化 DataGridViewHideSelection 类的实例并在您不再需要功能时处理它。

var hideSelection = new DataGridViewHideSelection( myGridView );

// ...

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

Alternatively, you can use the convenient extension method AttachHideSelectionBehaviour()to make life a little easier.

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

myDataGrid.AttachHideSelectionBehaviour();

Maybe that's helpful to someone else.

也许这对其他人有帮助。

回答by zodo

Use DataGridView.ClearSelection()whereever you want to clear the focus/selection (e.g. InitializeComponent, Control.LostFocus, Form.Load).

在您想要清除焦点/选择的任何地方使用DataGridView.ClearSelection()(例如 InitializeComponent、Control.LostFocusForm.Load)。