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

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

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

  • Создать проект формы
  • Добавить DataGridView с именем "DataGridView1"
  • Добавьте следующий код в свой класс 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

Удачи!

Ответ 5

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

  • 'Начальная активная ячейка', очищенная даннымиGridView.ClearSelection().

  • Очистить/Игнорировать выделение в обработчике событий, событие CellMouseClick.

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

Ответ 6

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

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