WinForms - DataGridView - ячейка не выбрана

Есть ли способ сделать DataGridView не выбранной ячейкой? Я замечаю, что даже когда он теряет фокус(), у него есть хотя бы одна активная ячейка. Есть ли другой режим, который позволяет это? или еще какая хитрость?


person BuddyJoe    schedule 04.12.2008    source источник


Ответы (7)


Свойство DataGridView.CurrentCell можно использовать для очистки прямоугольника фокуса.

Вы можете установить для этого свойства (DataGridView.CurrentCell) значение null, чтобы временно удалить прямоугольник фокуса, но когда элемент управления получает фокус и значение этого свойства равно null, ему автоматически присваивается значение свойства FirstDisplayedCell.

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

person Aleris    schedule 04.12.2008

Я обнаружил, что 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, не влияет на желаемое поведение, но я оставил его во фрагменте кода, потому что заметил, что для моих нужд, по крайней мере, лучше прикреплять обработчик только после привязки данных, чтобы избежать события изменения выбора. поднимается для каждого связанного элемента.

person David Hall    schedule 19.12.2008

Проблема с установкой для DataGridView.CurrentCell значения null в событии изменения выбора заключается в том, что более поздние события (например, щелчок) не будут затронуты.

Вариант, который сработал для меня, состоял в том, чтобы изменить цвет выделения на цвет сетки. Таким образом, выбор не будет виден.

RowsDefaultCellStyle.SelectionBackColor = BackgroundColor;
RowsDefaultCellStyle.SelectionForeColor = ForeColor;
person J. Ouwehand    schedule 27.01.2012
comment
Ваше решение не создаст DataGridView без выбранной ячейки. Это просто внешний вид... - person nbadaud; 02.09.2016

Я потратил часы, чтобы найти решение этой проблемы. Сделай это:

  1. Создать проект формы
  2. Добавьте DataGridView с именем «DataGridView1».
  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
    

Важная строка кода

    DataGridView1.CurrentRow.Selected = False

Удачи!

person Community    schedule 10.01.2009

У меня была аналогичная проблема, и я пошел по этому пути:

  1. «Начальная активная ячейка» очищается с помощью dataGridView.ClearSelection().

  2. Очистить/игнорировать выбор в обработчике события CellMouseClick.

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

Я знаю, что это старый вопрос, и 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();

Может быть, это полезно для кого-то еще.

person Jaans    schedule 15.11.2014

Используйте DataGridView.ClearSelection () везде, где вы хотите очистить фокус/выбор (например, InitializeComponent, Control.LostFocus, Form.Load).

person zodo    schedule 21.04.2016