Модераторы: gambit, Kefir, Partizan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DataGridView медленно работает при загрузке данных 
:(
    Опции темы
leon78
Дата 13.9.2012, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Использую в проекте WPF DataGridView. В нем несколько столбцов и 630 строк. Заполняется он при загрузке контрола в цикле из массива.
 При первой загрузке время терпимое, несколько секунд.
 После выгрузки контрола при следующей загрузке время заполнения приближается к нескольким минутам. В чем может быть проблема?
Заголовки заполняются так:
Код

                for (int j = 1; j <= 125; j++)
                {
                    DGV.Rows[j * 5].HeaderCell.Value = "[" + Convert.ToString(j) + "].x";
                    DGV.Rows[j * 5].HeaderCell.Style.Font = HeaderCellFont;
                    DGV.Rows[j * 5 + 1].HeaderCell.Value = "[" + Convert.ToString(j) + "].y";
                    DGV.Rows[j * 5 + 2].HeaderCell.Value = "[" + Convert.ToString(j) + "].z";
                    DGV.Rows[j * 5 + 3].HeaderCell.Value = "[" + Convert.ToString(j) + "].a";
                    DGV.Rows[j * 5 + 4].HeaderCell.Value = "[" + Convert.ToString(j) + "].b";
                }


Столбцы так:
Код

            for (int j = 1; j <= 125; j++)
            {
                DGV[i, j * 5].Value = "AAA";
                DGV[i, j * 5].Style.Font = HeaderCellFont;
                DGV[i, j * 5 + 1].Value = "AAA";
                DGV[i, j * 5 + 2].Value = "AAA";
                DGV[i, j * 5 + 3].Value = "AAA";
            }

PM MAIL   Вверх
leon78
Дата 14.9.2012, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Пробовал сделать загрузку в другом потоке - не помогло 
PM MAIL   Вверх
leon78
Дата 15.9.2012, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Сделал тестовый пример.
За одну секунду в DataGridView заполняется всего 6 ячеек!
Что я делаю не так?

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  test_grid.zip 82,36 Kb
PM MAIL   Вверх
Экскалупатор
Дата 15.9.2012, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: нет
Всего: 24



ну ведь тебе не нужны все 630 строк одновременно? грузи столько сколько надо, а не все, тогда все будет норм.
PM MAIL ICQ   Вверх
leon78
Дата 15.9.2012, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Даже если на экране в данный момент видно 30 ячеек, заполнение займет 5 секунд. Как же будет работать прокрутка?
Мне не понятно, почему так долго происходит запись в одну ячейку.
PM MAIL   Вверх
lomaster
Дата 15.9.2012, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Хидеры надо заполнять один раз, а не так как в примере.
Долго работает потому что сразу идет отрисовка, а контрол не родной.
Да и зачем так заполнять?

Зачем вам тут DataGridView, есть же свои контролы.
PM   Вверх
leon78
Дата 15.9.2012, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Цитата(lomaster @ 15.9.2012,  16:54)
Хидеры надо заполнять один раз, а не так как в примере.

Это я в примере сделал, чтобы не заморачиваться. В реальной программе один раз заполняю.
Цитата
Да и зачем так заполнять?

А как лучше?
Цитата
Зачем вам тут DataGridView, есть же свои контролы.

Какой лучше использовать? Я в C# и WPF новичок.
PM MAIL   Вверх
lomaster
Дата 15.9.2012, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Вы поясните что делаете. Контролов много разных, какой вам лучше подойдет сложно сказать.
А так есть ListView, DataGrid, ...
PM   Вверх
leon78
Дата 15.9.2012, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Мне надо сохранить массив настроек. Ячейки - текст, числа с плавающей запятой, TimeSpan. Некоторые из них - ComboBox для выбора вариантов.
Большая часть настроек - повторяющийся из нескольких элементов массив (string - string - float - float).
Я сейчас пытаюсь разобраться с DataGrid. Как вывести обычные поля, разобрался. Но как массив - не могу пока понять, как в тексте программы привязку сделать, т.е. аналог
Код

                <DataGridTextColumn Binding="{Binding Path=ID}" Header="col1" />
                <DataGridTextColumn Binding="{Binding Path=Name}" Header="col2" />      

в программе на C#
Можно, конечно, и там прописать, но это же 600 строк!
Дошел до этого:
Код

            for (int i = 0; i < 100; i++)
            {
                DataGridTextColumn DGC = new DataGridTextColumn();
                DGC.Header = "K_add_" + i;
                Binding binding = new Binding();
                PropertyPath path = new PropertyPath("{Binding Path=K_add[" + i + "]}");
                binding.Path = path;
                DGC.Binding = binding;
                dataGrid1.Columns.Add(DGC);
            }

Но пока ругается на 
PropertyPath path = new PropertyPath("{Binding Path=K_add[" + i + "]}");
PM MAIL   Вверх
leon78
Дата 15.9.2012, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Работает!
Код

                DataGridTextColumn DGC = new DataGridTextColumn();
                DGC.Header = "K_add_" + i;
                Binding binding = new Binding("K_add[" + i + "]");
                DGC.Binding = binding;
                dataGrid1.Columns.Add(DGC);

DataGrid на порядок быстрее работает, но выглядит не так красиво, как DataGridView

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  test_grid.zip 93,14 Kb
PM MAIL   Вверх
lomaster
Дата 15.9.2012, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Цитата

DataGrid на порядок быстрее работает, но выглядит не так красиво, как DataGridView 
 В впф красоту навести гораздо проще. Стилями можно что угодно нарисовать.
И возможностей больше. 
PM   Вверх
Экскалупатор
Дата 15.9.2012, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: нет
Всего: 24



Цитата(leon78 @  15.9.2012,  14:38 Найти цитируемый пост)
Как же будет работать прокрутка?

по событию догружать то, что надо.
Цитата(leon78 @  15.9.2012,  17:37 Найти цитируемый пост)
Мне надо сохранить массив настроек. Ячейки - текст, числа с плавающей запятой, TimeSpan. Некоторые из них - ComboBox для выбора вариантов.
Большая часть настроек - повторяющийся из нескольких элементов массив (string - string - float - float).

че то тут совсем не понял. куда сохранить? откуда взять? хочу больше деталей...
PM MAIL ICQ   Вверх
leon78
Дата 15.9.2012, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



А как сделать запись в DataGrid изменений не сразу же, а после нажатия кнопки "Save"?
И возможность восстановления состояния до редактирования после нажатия "Cancel"?
Сейчас данные из DataGrid сразу же оказываются в коллекции - источнике данных

Добавлено через 7 минут и 47 секунд
Цитата(Экскалупатор @ 15.9.2012,  20:34)
по событию догружать то, что надо.

Я имел ввиду, скорость прокрутки будет очень низкая.

Цитата(Экскалупатор @ 15.9.2012,  20:34)
че то тут совсем не понял. куда сохранить? откуда взять? хочу больше деталей...

Есть структура
Код

    public struct sMн
    {
        public string Name ;
        public uint u1;
        public uint u2;
        public string s1;
        public string s2;
        public string s3;
        public string s4;
        public TimeSpan t1;
        public TimeSpan t2;
        public string st1;
        public string st2;
        public string s5;
        public uint u3;
        public uint u4;
        public uint u5;
        public float[] f1;
        public float[] f2;
        public float f3;

    }

f1 и f2 - по 125 элементов
Из этой структуры создается массив на 200 элементов
Надо иметь возможность отобразить этот массив в таблице, отредактировать его, и сохранить по кнопке "Сохранить". Или вернуть значения до редактирования по кнопке "Отмена".

Добавлено через 9 минут и 48 секунд
Забыл добавить. Массив на 200 элементов создал по максимуму.
Отображаться в данный момент может и один элемент.
Надо иметь возможность добавить - удалить элементы.
PM MAIL   Вверх
lomaster
Дата 15.9.2012, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



По Save сохраняйте уже в файл/базу/....
А вот при undo либо перечитывать данные из источника (файл/база/...), либо как-то еще, опять-таки все зависит от конкретики. Посмотрите возможности биндинга.

Это сообщение отредактировал(а) lomaster - 15.9.2012, 20:53
PM   Вверх
leon78
Дата 15.9.2012, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



У меня этот массив используется в других потоках, поэтому менять его без нажатия "Save" нельзя. Вычитывание из БД/файла при нажатии "Cancel" не подходит
PM MAIL   Вверх
lomaster
Дата 15.9.2012, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Ктож редактирует "боевые" данные? так нельзя
PM   Вверх
leon78
Дата 16.9.2012, 07:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Т.е. надо держать 2 копии коллекции - 1 "боевая", 2я для DataGrid. И при нажатии кнопки "Save" копировать в боевую, а при "Cancel" - из боевой? А попроще варианта нет? Может, можно настроить биндинг, чтобы копирование происходило в заданном направлении по команде, а не постоянно?
PM MAIL   Вверх
lomaster
Дата 16.9.2012, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Я же раньше писал - "посмотрите возможности биндинга".
Есть такое свойство UpdateSourceTrigger, установите его в Explicit. Это значит что вы теперьотвечаете за то когда данные попадут в источник.
А дальше что-то типа такого:
Цитата

 BindingExpression b =
      BindingOperations.GetBindingExpression(your_obj, dependency_property );
    if (b != null) be.UpdateSource();
 и так длякаждого сонтрола.
Хотя мне этот вариант не очень...
PM   Вверх
leon78
Дата 16.9.2012, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Пытаюсь разобраться как раз с этим Explicit.
Стоит он для всех колонок, но данные из DataGrid все равно попадают в источник

Добавлено через 9 минут и 7 секунд
Во вложении проект. Точка останова на кнопке "Cancel".
Видно, что данные в коллекции обновляются сразу после изменения в DataGrid, не смотря на UpdateSourceTrigger= Explicit

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  test_grid.zip 94,85 Kb
PM MAIL   Вверх
lomaster
Дата 16.9.2012, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 27.5.2012

Репутация: 1
Всего: 2



Зачем столько колонок?
Их количество только указывает на то, что вы что-то не то делаете.. smile

PM   Вверх
leon78
Дата 16.9.2012, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Количество колонок соответсвует количеству параметров, их не уменьшишь.
Для "Cancel" написал такой код:
Код

            BindingExpression binding =
                dataGrid1.GetBindingExpression(TextBox.TextProperty);
            // Обновить связанный элемент FlowDocument
            binding.UpdateTarget();

Но binding = null, не работает.
Не могу понять, что ставить вместо TextBox.TextProperty ?
PM MAIL   Вверх
leon78
Дата 16.9.2012, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Ничего не получается :(
 smile 
PM MAIL   Вверх
erm0l0v
Дата 17.9.2012, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: нет
Всего: 1



Передайте свой массив в DataGrid.ItemSource и все будет отображаться нормально и при большем количестве строк)))
PM MAIL   Вверх
leon78
Дата 17.9.2012, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



У меня сейчас так и привязано. Не могу разобраться, как сделать копирование из DataGrid в Source и наоборот по командам, а не постоянно.
UpdateSourceTrigger= Explicit не помогает
PM MAIL   Вверх
erm0l0v
Дата 17.9.2012, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: нет
Всего: 1



В смысле копирование. Коллекция одна просто она же используется и в коде и она же используется для отображения в интерфейсе. Используйте ObserverCollection для отслеживания изменений коллекции.
PM MAIL   Вверх
leon78
Дата 17.9.2012, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Коллекция используется для работы в другом потоке.
Надо, чтобы запись из DataGrid в коллекцию происходила по кнопке "Save". А при нажатии "Cancel" происходило копирование из коллекции в DataGrid для восстановления состояния, предшествующего редактированию.
PM MAIL   Вверх
erm0l0v
Дата 19.9.2012, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: нет
Всего: 1



В таком случае вам в модели нужно заменить коллекцию и сгенерироворь событие PropertyChanged. Тогда в представлении коллекция тоже заменится.
PM MAIL   Вверх
leon78
Дата 19.9.2012, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Не очень понял, речь идет о "Save" или "Cancel"?
И не могу понять, почему при UpdateSourceTrigger= Explicit  после редактирования DataGrid данные сразу же меняются в коллекции?
PM MAIL   Вверх
erm0l0v
Дата 19.9.2012, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: нет
Всего: 1



Приведите пример кода где у вас к DataGrid цепляется коллекция.
PM MAIL   Вверх
leon78
Дата 19.9.2012, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



PM MAIL   Вверх
erm0l0v
Дата 21.9.2012, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: нет
Всего: 1



Старайтесь не использовать WindowsFormsHost, он очень медленный, даже на более простых компонентах. Попробуйте найти аналог на WPF.

Для того чтобы изменения на форме записывались в массив вам в бинденге необходимо указать:
UpdateSourceTrigger= PropertyChanged
и
Mode = TwoWay

Для того чтобы на форме отображались данные, вам необходимо унаследовать объект к которому производится биндинг от INotifyPropertyChanged, и кидать событие PropertyChanged с названием свойства которое будет меняться, в вашем случае K_add[i]
PM MAIL   Вверх
leon78
Дата 25.9.2012, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 10.10.2006

Репутация: нет
Всего: нет



Сделал две коллекции, одна рабочая, другая привязана к DataGrid. При нажатии "Save" параметры второй копируются в первую в цикле, при нажатии "Cancel" наоборот. Неужели это единственное решение?
PM MAIL   Вверх
Kefir
Дата 2.11.2012, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Я точно не помню, но по-моему WPF DataGrid плюет на ваш UpdateSourceTrigger для любой колонки кроме DataGridTemplateColumn (ибо там вы все биндинги ручками привязываете напрямую в CellTemplate и CellEditingTemplate. Во всех остальных случаях если я не ошибаюсь DataGrid при генерации ячеек ставит UpdateSourceTrigger=LostFocus (или Explicit, который сам же и коммитит). Так что если хотите контролировать время коммита в сорс - используйте исключительно DataGridTemplateColumn, где вы сами даете темплейты для содержимого ячеек.

Вообще если вкратце - DataGrid это не панацея и не очень любит, когда его используют не так, как это задумывали авторы. Его основная суть - редактирование рядов. Когда вы клацаете по ячейке и что-нибудь редактируете - начинается формальный edit текущего ряда. Когда вы уходите с этого ряда происходит коммит данных обратно в сорс.

У вас же случай крайне странный (я слабо представляю зачем вам save/cancel для датагрида, но мало-ли какие бывают случаи). Для того чтобы осуществить ваш замысел с save/cancel вам надо условно говоря предотвращать коммит ряда (смотрите в сторону какого-нибудь RowEditEnding -  там вроде есть cancel, это в случае если вы таки используете стандартные колонки, а не templatecolumn) а также в сторону CommitEdit.

Также на всякий случай хочу заметить, что DataGrid поддерживает IEditableObject, так что это тоже может как-то облегчить задачу.
PM MAIL WWW Skype   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.1314 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.