виртуальный режим datagridview, обновление RowCount приводит к срабатыванию CellValueNeeded для всех строк - PullRequest
5 голосов
/ 06 декабря 2011

Я пытаюсь реализовать виртуальный режим datagridview, но когда я устанавливаю RowCount на некоторое число (чтобы показать полосу прокрутки), сетка хочет, чтобы все строки были одновременно, а не только отображались.

DataGridView grid = new ...;

grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
grid.RowCount = dataprovider.GetFullCount();

Как я могу сказать сетке запрашивать только отображаемые строки?

Ответы [ 5 ]

5 голосов
/ 06 декабря 2011

Это всего лишь предположение, но у вас установлены значения AutoSizeRowsMode или AutoSizeColumnsMode, равные AllCells, или для какого-либо из столбцов установлено это значение?Попробуйте установить режим изменения размера None или просто DisplayedCells и посмотрите, есть ли проблема.

2 голосов
/ 05 июня 2013

Не уверен, что это та же проблема, что и у меня, но у меня очень низкая производительность при регулярном радикальном изменении RowCount в VirtualMode DataGridView.

Что я заметил, так это то, что полоса прокрутки менялась «медленно»; то есть выглядело так, как будто он удалял мои виртуальные строки (!).

В любом случае, выполнение grid.Rows.Clear() перед каждым вызовом grid.RowCount = n значительно повышает производительность.

1 голос
/ 23 января 2012

к сожалению, это, кажется, стандартное поведение.Я мог бы решить это либо

void OnCellValueNeeded(...)
{
    if(!_active) return;
}

grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
_active = false;
grid.RowCount = dataprovider.GetFullCount();
_active = true;

, либо внедрив IBindingList, ITypedList со сложной ленивой выборкой в ​​фоновом потоке

Обновление: проблема, похоже, исправлена.Я больше не могу воспроизвести его, используя следующее:

static class Program
{
    private static Form form;
    private static int i;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        var grid = new DataGridView
        {
            Dock = DockStyle.Fill,
            VirtualMode = true,
            AllowUserToAddRows = false,
            Columns =
            {
                new DataGridViewTextBoxColumn { HeaderText = "foo" },
                new DataGridViewTextBoxColumn { HeaderText = "bar" },
            },
        };
        grid.CellValueNeeded += OnCellValueNeeded;
        form = new Form
        {
            Controls = { grid }
        };

        //grid.RowCount = 0;
        grid.RowCount = 10000;

        Application.Run(form);
    }

    private static void OnCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        i++;
        form.Text = i.ToString();
        e.Value = "fooValue";
    }
}
0 голосов
/ 22 сентября 2015

Вы должны установить RowCount на ноль перед установкой полного счета

DataGridView grid = new ...;
grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
grid.RowCount = 0;
grid.RowCount = dataprovider.GetFullCount();
0 голосов
/ 24 октября 2013

У меня та же проблема, и я попытался решить проблему установки активного флага, как вы, и я также попробовал решение установить RowCount в 0 (или grid.Rows.Clear ()) перед установкой нового RowCount.

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

Я нашел два других решения:

1) Используйте нумерацию страниц, чтобы вам не нужно было устанавливать RowCount так высоко для начала. Я думаю, что это отличное решение, если вы уже используете нумерацию страниц (в этом случае вас здесь нет), но слишком громоздкое, если вы не планируете его внедрять.

2) Поместите вызов, чтобы установить RowCount в своем собственном потоке. Это тот, который я собираюсь попробовать. Честно говоря, не уверен, насколько это безопасно, если вы пытаетесь редактировать ячейки, пока поток еще не закончил, но я думаю, я скоро это выясню.

EDIT:

ОК, поэтому я попытался проделать это, надеясь, что это поможет, так как я прочитал в другом месте, что это действительно помогло другому парню. Кажется, это хорошее решение ЕСЛИ вы просто время от времени меняете значение, но оно все равно зависает, если вы делаете это несколько раз подряд (что я). Я думаю, что это потому, что вы должны использовать Invoke (), и во второй раз он все еще ждет завершения первого. Не могу сказать, что полностью понимаю, в чем дело, но я решил пока просто жить с пустыми строками, потому что это СООО гораздо быстрее и менее сложно, когда я просто оставляю их там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...