DataGridView не вызывает метод Paint, когда вызывается InvalidateCell

2

Это проблема с приложением WinForm С#.

У меня есть DataGridView, и мне нужен настраиваемый тип DataGridViewColumn, так что когда моя мышь находится над ячейкой в ​​этом столбце, ячейка рисует что-то особенное на ней. Я нашел способ переопределения DataGridViewTextBoxCell для самой картины. В этой статье показан пример реализации перевернутой ячейки, так что при перемещении мыши по ячейке она рисует красный прямоугольник вокруг самих ограничителей.

Если вы видите пример, вы узнаете, что способ, которым заполняет пример, напрямую создает строки в сетке. Когда я использую привязку данных, а не прямую заливку строки, я обнаруживаю, что ячейки не будут рисовать себя в начале. Фактически, сначала вы должны выбрать ячейку, затем все ячейки в этой строке будут правильно рисоваться. Если вы не выбираете ячейку строки, все ячейки в этой строке не будут рисовать соответственно, когда мышь над ними.

Я думаю, что это какая-то оптимизация сетки, так что когда вы выбираете ячейку, основной объект этой строки активируется, и сетка вызывает метод Paint, когда метод InvlidateCell является вызовом. Но если основной объект строки не активирован, сетка просто покрасит ячейки по умолчанию, чтобы сэкономить время.

Очевидно, мне не нужна оптимизация, но медленный путь. В моем случае это не имеет значения, потому что мои данные на этой сетке никогда не становятся слишком большими. Как я могу это достичь? Я пытаюсь вызвать grid.Refresh() после того, как данные привязаны к сетке, но это не помогает.

Спасибо за ваше предложение.

Джи

  • 0
    Если я добавлю this.DataGridView.Refresh () в методы OnMouseEnter и OnMouseLeave, проблема будет исправлена. Но это приводит к тому, что вся сетка мигает, пока на ней движется мышь. Я считаю, что это не очень хорошее решение.
Теги:
winforms
datagridview

2 ответа

0

Я некоторое время боролся с той же проблемой, проблема в том, что любой метод в DataGridViewImageButtonCell : DataGridViewTextBoxCell вызывается с атрибутом объекта RowIndex = -1, поэтому InvalidateCell() запускается с помощью RowIndex = -1, поэтому ничего не происходит.

Это вызвано разделяемыми рядами:

Когда свойство RowIndex возвращает -1, ячейка является либо заголовком столбца, либо , ячейка ячейки является общей..

MSDN показывает несколько способов, как вы можете поддерживать общие строки (таким образом, они идут против них = строка unshare), включая:

Например, строка не может быть разделена ни на одну из следующих ситуации:

  • Строка содержит одну выделенную ячейку, которая не находится в выбранном столбце.
  • Строка содержит ячейку с установленными ее свойствами ToolTipText или ContextMenuStrip.
  • Строка содержит DataGridViewComboBoxCell со своим набором свойств Items.

...

Не обрабатывайте события DataGridViewRowCollection.CollectionChanged или DataGridView.RowStateChanged. Эти события заставляют строки не разделяться. Кроме того, не вызывайте методы DataGridViewRowCollection.OnCollectionChanged или DataGridView.OnRowStateChanged, которые повышают эти события.

Я пробовал использовать:

public MyDataGridView()
    : base()
{
    RowStateChanged += MyDataGridView_RowStateChanged;
}

void MyDataGridView_RowStateChanged( object sender,
         DataGridViewRowStateChangedEventArgs e )
{
}

Это сработало, но я ненавидел идею не разделяющих строк по умолчанию, поэтому я в конечном итоге расширил класс Cell путем перегрузки:

Таким образом, конечный рабочий код выглядит следующим образом:

/// <summary>
/// Required correcting mousve hover displaying
/// </summary>
/// <param name="rowIndex"></param>
/// <returns></returns>
protected override bool MouseEnterUnsharesRow( int rowIndex )
{
    return true;
}

/// <summary>
/// Required correcting mousve hover displaying
/// </summary>
/// <param name="rowIndex"></param>
/// <returns></returns>
protected override bool MouseLeaveUnsharesRow( int rowIndex )
{
    return true;
}
0

Не совсем уверен, что я понял ваш вопрос. Посмотрите, похоже ли это на то, что вам нужно:

bool bSomeFlag = false;
int iCol = 0;
int iRow = 0;
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e) {
            iCol = e.ColumnIndex;
            iRow = e.RowIndex;
            bSomeFlag = true;
            this.dataGridView1.Invalidate();
        }
private void dataGridView1_Paint(object sender, PaintEventArgs e) {
            if (bSomeFlag && iRow >=0 && iCol>=0) {
                dataGridView1.Rows[iRow].Cells[iCol].Style.BackColor = Color.Red;
            }
        }
  • 0
    Я имею в виду, что если вы вызываете метод InvalidateCell в переопределенном событии OnMouseEnter настраиваемой ячейки, каждый раз, когда вызывается метод InvalidateCell, также должен вызываться метод Paint объекта ячейки. Но это не так, если вы используете привязку данных в сетке. Для привязки данных изначально метод InvalidateCell не будет вызывать метод Paint. Это происходит только при выборе ячейки. Как только ячейка выбрана, все ячейки в ее строке ведут себя нормально: метод InvalidateCell всегда запускает метод Paint. Я уже попробовал ваше предложение. Мигает клетка во время движения мыши, что плохо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню