Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
#1

dataGreedVew - bug-a или feature-?

31.01.2012, 18:00. Просмотров 862. Ответов 12
Метки нет (Все метки)

//vs2008
//добавляем на форму в дизайнере dataGridView1
//там же добавляем в dataGridView1 три столбца add columns
//получаем табличку из 3-х ячеек по горизонтали - Ok!
//сразу выберите размер видимой области что бы поместилось 3-5 Rows (строк таблицы)

//Добавляем кнопку с таким вот кликом

C++
1
2
3
4
5
6
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
this->dataGridView1->Rows->Add();
this->dataGridView1->Rows->Add();
this->dataGridView1->Rows[1]->Cells[1]->Value="кака!";
this->dataGridView1->Rows[1]->Cells[1]->Style->BackColor=Drawing::Color::Aqua;//Color::1;//это для красоты
             }
//кликаем и любуемся - Ok!
//теперь закоментируем первую строчку в обработчике

C++
1
2
3
4
5
6
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
//this->dataGridView1->Rows->Add();
this->dataGridView1->Rows->Add();
this->dataGridView1->Rows[1]->Cells[1]->Value="кака!";
this->dataGridView1->Rows[1]->Cells[1]->Style->BackColor=Drawing::Color::Aqua;//Color::1;//Без этого тоже same
             }
//кликаем и ... я - лично этому явлению название не придумал, (если Вы видите то-же, что и я).

Добавлено через 4 часа 53 минуты
Забавно, не уж-то это только у меня такой глюк
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.01.2012, 18:00
Ответы с готовыми решениями:

Streaming cluster replication bug or ne bug
Как только оно появилось с версии 8.5х - так сразу его рекомендовали отключить...

BUG или фича с PasswordChar
Всем привет! С удивлением обнаружил, что установка символа "*" в свойствах...

Bug NetBeans или я тупой
public void analised() { if(jTextArea2.getText() != "" ||...

Feature.xml
Посмотрела по форуму, вроде нет такого вопроса. Планшет Samsung Galaxy tab 2...

Определение признаков (feature selection)
Коллеги, здравствуйте! Подскажите пожалуйста по следующему вопросу. Есть...

12
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
31.01.2012, 19:04 #2
IGPIGP, судя по всему это не глюк, просто если включена возможность добавления новых строк в грид, то последняя строка, которая служит для вставки новых строчек, тоже считается элементом коллекции DataGridView::Rows. То есть если возможность добавления столбцов будет включена, то изначально в гриде значение Rows->Count будет равно 1, следовательно последний код добавит одну строку, так что Rows[1] окажется валидным элементом, и будет записана информация в эту последнюю строчку, которая нужна для вставки; а если столбцы добавлять нельзя, тогда Rows->Count будет 0, и при исполнении последнего приведённого кода вылетит ошибка времени выполнения, говорящая о том, что имеется выход за рамки коллекции DataGridView::Rows.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
31.01.2012, 21:31  [ТС] #3
Цитата Сообщение от Ma3a Посмотреть сообщение
IGPIGP, судя по всему это не глюк
Скажите Ma3a, а Вы это откомпилили и запустили или так глядя на код говорите?
Дело в том, что ошибок то не вылетает. Я специально привел код в котором раскрасил ячейку заполняемую значением, что бы получить максимум впечатлений.
Первый код работает нормально, а во втором:
C++
1
2
this->dataGridView1->Rows[1]->Cells[1]->Value="кака!";
this->dataGridView1->Rows[1]->Cells[1]->Style->BackColor=Drawing::Color::Aqua;
инициализируют 1,1 только при первом clicke, а далее:
2,1; 3,1; 4,1 и т.д.
0
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
31.01.2012, 21:58 #4
Цитата Сообщение от IGPIGP Посмотреть сообщение
инициализируют 1,1 только при первом clicke, а далее:
2,1; 3,1; 4,1 и т.д.
Да, этот момент я проглядел. Но опять же мне кажется, что это нормальное поведение для данного контрола. По моим наблюдениям получается так, что объект, представляющий последнюю строку для вставки, всегда позиционируется последним в коллекции Rows, так что при первом нажатии кнопки мы изменяем этот самый объект, а при последующих нажатиях так выходит, что последняя вставленная строка будет иметь индекс Rows->Count - 2, то есть вставка новой строки идет не в конец коллекции, а на позицию предпоследнего элемента, а самая последняя "временная" строка всегда остается последним элементом коллекции строк, поэтому эта последняя строка и остается измененной.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
31.01.2012, 22:29  [ТС] #5
Последняя строка не остается неизменной а заполняется значением, а не должна бы. Посмотрите как первый вариант работает - нормально работает. Добавляем по 2 строки и все окей - обновляется только клетка 1,1.
ДатаГрид - индексно адресуется как 2-мерный массив (должен), но когда добавляется 1 строка (я долго не экспериментировал, но это вроде единственный случай) обновляется последняя добавленная!
0
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
31.01.2012, 22:48 #6
IGPIGP, я имел ввиду то, что если включена возможность добавления записей в грид ручками на форме, тогда содержимое коллекции Rows всегда выглядит следующим образом:
Код
1 строка
2 строка
...
n-1 строка
n строчка(для добавления записей)
и когда мы добавляем запись в грид посредством вызова метода Rows::Add, имеем такую картину
Код
1 строка
2 строка
...
n-1 строка
n строка (которую вставили только что)
n+1 строчка(для добавления записей)
Последняя строка всегда остается при таком раскладе одним и тем же объектом по сути, и поскольку мы его в самом начале изменили, когда первый раз нажали на кнопку(и при последующих нажатиях просто объект, который представлял ту вторую, последнюю строку, остается всегда в конце), то при последующих нажатиях изменение, которое мы занесли туда этим кодом в начале сохранится.
C++
1
2
this->dataGridView1->Rows[1]->Cells[1]->Value="кака!";
this->dataGridView1->Rows[1]->Cells[1]->Style->BackColor=Drawing::Color::Aqua;
К такому выводу можно прийти потому что во втором варианте(когда один из вызовов Rows::Add закомментирован) если мы нажмем несколько раз на кнопку, то у нас сначала заполнится последняя строка, а следующий раз, как и должно быть, будет изменена ячейка за индексами [1][1], что и делает приведённый выше код, изменений в последнюю строку же никаких не вносится.
Более того, можно попробовать написать в тот метод ещё нечто вроде
C++
1
this->dataGridView1->Rows[dataGridView1->Rows->Count - 1]->Cells[0]->Value += "Yay!";
тогда мы увидим, что каждый раз к этой строчке в первой ячейке добавляется выражение "Yay!", что опять же показывает, что последняя строка всегда по сути есть один объект, который при каждой вставке по абсолютной позиции всегда остается в конце.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
31.01.2012, 23:09  [ТС] #7
Цитата Сообщение от Ma3a Посмотреть сообщение
если мы нажмем несколько раз на кнопку, то у нас сначала заполнится последняя строка, а следующий раз, как и должно быть, будет изменена ячейка за индексами [1][1]
Во-первых, спасибо Вам, что откликнулись Ma3a, мне казалось, что это по-крайней мере прикольно
Вернемся к цитате: "сначала заполняется последняя строка" - и это единственный раз правильно, т.к. строк уже 2-е (была одна и + один add)? а поскольку стартовый индекс ноль, [1][1] вторая сверху, вторая слева, и это в обоих вариантах одинаково при первом нажатии. Со второго нажатия первый вариант работает верно [1][1], а второй обновляет (перемещает посути [1][1] вконец), ячейку с координатами rows[нижний] cells[1] Вообще обещаю, сегодня пока будет возможность, и завтра перечитаю Ваш ответ, что-то я в нем не понял, а это значит, что-то в нем есть
0
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
31.01.2012, 23:37 #8
Цитата Сообщение от IGPIGP Посмотреть сообщение
Во-первых, спасибо Вам, что откликнулись Ma3a, мне казалось, что это по-крайней мере прикольно
Вернемся к цитате: "сначала заполняется последняя строка" - и это единственный раз правильно, т.к. строк уже 2-е (была одна и + один add)? а поскольку стартовый индекс ноль, [1][1] вторая сверху, вторая слева, и это в обоих вариантах одинаково при первом нажатии. Со второго нажатия первый вариант работает верно [1][1], а второй обновляет (перемещает посути [1][1] вконец), ячейку с координатами rows[нижний] cells[1] Вообще обещаю, сегодня пока будет возможность, и завтра перечитаю Ваш ответ, что-то я в нем не понял, а это значит, что-то в нем есть
Попытаюсь привести чуть более наглядный пример, чтобы пояснить ситуацию. Положим, что каждая строка(объект класса DataGridViewRow) имеет свой уникальный номер ID(вообще они и так его имеют, но там есть свойства вроде относительного индекса позиции в гриде, а конкретно GUID вроде нету, впрочем, не суть важно). Пусть самая последняя строка DataGridViewRow всегда имеет ID равный "TheLastOne". Вновь добавляемые строки имеют идентификаторы вида "Row_n", где n бегает от 1 до некоторого N.
В самом начале, при создании грида, контейнер строк у грида имеет вид такой:
Код
TheLastOne
То есть состоит из одного элемента, хэндл на который характеризуем таким идентификатором.

Мы нажимаем button, что происходит — добавляется строка с идентификатором Row_1, прямо перед элементом с ID = "TheLastOne". Контейнер строк Rows выглядит так:
Код
Row_1
TheLastOne
причем позиция DataGridViewRow с идентификатором TheLastOne сместилась(при пустом гриде она была нулём), теперь она равна 1. Обновляем содержимое грида по адресу [1][1], то есть вторую ячейку записи TheLastOne.

Теперь нажимаем второй раз на button, что получается теперь — опять же, перед последним элементом TheLastOne добавляется новая строчка, то есть относительное положение элемента TheLastOne в контейнере не изменилось, но перед ним появилась новая строка. Итого контейнер строк выглядит так:
Код
Row_1
Row_2
TheLastOne
Причем тут самое важное, что тот TheLastOne, что у нас есть на этом шаге является тем же самым объектом, который у нас был когда мы первый раз нажимали на кнопку, и когда ещё вообще не нажимали, один и тот же объект по сути, просто перед ним добавилось несколько элементов. Стоит заметить, что индекс элемента TheLastOne в коллекции сместился, и теперь равен 2(то есть можно обратиться к нему по адресу Rows[2]). Что происходит дальше: обновляем содержимое ячейки по адресу [1][1] — здесь обновляется уже не TheLastOne, а строчка на одну выше, с идентификатором Row_2. Но! при этом, если мы вернемся чуть раньше по тексту
Обновляем содержимое грида по адресу [1][1], то есть вторую ячейку записи TheLastOne.
то замечаем, что самый последний элемент у нас тоже изменен.
И как мы сейчас установили, при каждом последовательном добавлении строки мы будем иметь контейнер Rows в следующем виде
Код
Row_1
...
Row_N
TheLastOne
Объект с идетификатором TheLastOne на протяжении всех этих манипуляций с нажатиями кнопки остается неизменным(вернее, мы его изменили только один раз, при первом нажатии), но он никуда не делся, просто он всё время остается в конце всего массива строк, а при втором и последующих вызовах обработчика button_Click будет обновляться одна ячейка с адресом [1][1], во второй строке, втором столбце, плюс к тому, на последней строчке всегда будут оставаться изменения, сделанные нами в самом начале, они не применяются каждый раз заново к последней строчке, они просто сохраняются как есть, потому что объект этой строчки остается одним и тем же, с идентификатором TheLastOne.

То есть в первом случае, как Вы и сказали, обновляется только вторая строчка, второй столбец. А во втором случае, получается так, что мы затрагиваем этот элемент, который сначала был на позиции[1][1], но при последующих вставках он просто перемещается выше, плюс к тому, начиная со второго вызова обработчика, как и положено, обновляется вторая строчка, второй столбец.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
01.02.2012, 00:13  [ТС] #9
У одного популярного римского сенатора была фраза которая звучала как-то так:
"Если это все и неправда, то придумано очень хорошо!". Не подумайте, что язвлю, наоборот примите как комплимент. Скорее всего это содержит логику поведения dataGreedVeW. Но не оправдывает. Ведет то она себя нехорошо. Как объяснить расхождение в поведении после первого клика пользуясь Вашей логикой? В первом случае у нас первым кликом инициализируется тоже [1][1] и в первый раз оно совпадает с [1][last_one]. Если он тупит и не может выпустить проинициализированную ячейку в last_one, то и при добавлении двух ячеек должна держать ее в последней строке зубами. Забавно, кстати то, что я с dataGreedVew работаю давненько, но ничего подобного не замечал. Вчера когда обнаружил эту feature посидел ночью чуток проверяя, как в последней проге дела. Слава богу везде сначала определяется размерность таблицы, а потом заполнение в цикле. Вроде везде все работает верно. Однако буду ещё проверять, сомнения есть...
Сейчас уже почти сплю. Впрочем до 1-00 все равно не светит. Так, что если не устали меня переубеждать - попробуйте, еще... хотя лучше - завтра бо голова у меня сейчас - ясень.
Если перечитав завтра окажется, что я протупил и у Вас все логично, буду просить прощения, но это будет завтра
0
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
01.02.2012, 00:23 #10
Цитата Сообщение от IGPIGP Посмотреть сообщение
Как объяснить расхождение в поведении после первого клика пользуясь Вашей логикой?
Ну этим объяснением я и занял последние пару сообщений На всякий пожарный, просто чтобы не перечитывать слишком много текста, приведу маленькую сводку, как оно получается на деле. В первом случае, когда мы добавляем сразу две строки и вносим изменения в ячейку за номером [1][1], то последняя строка вообще не изменяется(она представляет собой особый случай, как мы выяснили), поэтому при дальнейших действиях никаких странностей(в последней строке ничего не появляется, потому что мы её не трогали).
А при добавлении одной строки, мы в первый раз "задеваем" этот особый объект "последней строки", вот он и волочится вслед за всеми остальными строками со своими изменениями на последней позиции контейнера Rows.
Мне кажется, всё логично
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
01.02.2012, 17:49  [ТС] #11
Цитата Сообщение от Ma3a Посмотреть сообщение
Мне кажется, всё логично
Логично, если принимать как описание механизма действий dataGreedVew.
Что-же касается вопросов "Почему она так делает?" и "Правильно ли она делает?" - не убедили Вы меня Ma3a.
Проиллюстрирую, еще так:
C++
1
2
3
4
5
6
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
this->dataGridView1->Rows->Add();
                         }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
this->dataGridView1->Rows[1]->Cells[1]->Value="кака гарна вэсчь!";
                         }
Жмем button1 раз 5.
Жмем button2 раз 5.
Всё правильно.
А теперь парами т.е.
Жмем button1, жмем button2. И так 5 раз. Результат другой. Но в коде обр. каждой кнопки видно без затей - одна добавляет строку, вторая присваивает УКАЗАННУЮ ПРЯМО ячейку.
И обычно все получает именно так, только не в данном случае...
Хоть бы написали, где-то We're proud to present the outstanding feature of...
Может плохо читал. У меня английский - так-себе...
0
Ma3a
Эксперт С++
619 / 463 / 57
Регистрация: 28.01.2011
Сообщений: 605
01.02.2012, 18:16 #12
Цитата Сообщение от IGPIGP Посмотреть сообщение
Логично, если принимать как описание механизма действий dataGreedVew.
Что-же касается вопросов "Почему она так делает?" и "Правильно ли она делает?" - не убедили Вы меня Ma3a.
Да, фактически я просто описал механизм работы контрола, а вот единственный способ узнать, действительно ли это баг или так было задумано, можно, только написав куда-нибудь в поддержку Microsoft Connect и получив ответ от разработчиков
Цитата Сообщение от IGPIGP Посмотреть сообщение
Жмем button1 раз 5.
Жмем button2 раз 5.
Всё правильно.
А теперь парами т.е.
Жмем button1, жмем button2. И так 5 раз. Результат другой. Но в коде обр. каждой кнопки видно без затей - одна добавляет строку, вторая присваивает УКАЗАННУЮ ПРЯМО ячейку
Я понимаю, впрочем, я уже неоднократно приводил логику работы контрола, почему, если верить тому, что я сказал ранее, происходит в одном случае так, а в другом случае иначе. А уж почему происходит именно так — для меня самого загадка (вернее, было ли так задумано разработчиками или нет)
Цитата Сообщение от IGPIGP Посмотреть сообщение
dataGreedVew
И всё-таки DataGridView
Цитата Сообщение от IGPIGP Посмотреть сообщение
Хоть бы написали, где-то We're proud to present the outstanding feature of...
Может плохо читал. У меня английский - так-себе...
Я тоже занялся слегка поиском описания подобного поведения, или явного указания на такое поведение, но увы никто больше не интересуется изменением последней пустой строки в гриде
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
01.02.2012, 18:25  [ТС] #13
Спасибо, еще раз Ma3a, стало быть DataGridView не только у меня такой. Почему ни-кто больше не высказался - не знаю... Наверное что-то знают, но молчат
Тема закрыта.
0
01.02.2012, 18:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2012, 18:25

slider jquery-feature-carousel
Ребят, такой вопрос: есть слайдер jquery-feature-carousel в данный момент он...

Ignoring Portion Of Document That Uses A Feature From Another Version
Есть mail-in база письма которой обрабатываются. Но если пришло письмо со...

Undocumented feature: ViewNavigatort.skip(int entriesToSkip)
На днях внимательно перечитал статью. Как ни странно, но открыл для себя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru