Edycja komórki w DataGridView

0

Mam dwie tabele (faktury , fakturypozycje) połączone relacją (jeden do wielu) w oparciu o pole NrFaktury. Po zakończeniu wprowadzania nowych pozycji dla faktury (DataGridView) chciałem wprowadzić do wszystkich wierszy dla określonej kolumny, numer faktury (typu string).
Niestety, nie do końca jest to możliwe :(
Po wykonaniu poniższego kodu, wszystkie komórki w kolumnie powinny przyjąć wartość zapisaną w zmiennej NrFaktury, tymczasem tylko pierwszy wiersz przyjmuje tą wartość. Pozostałe wiersze pozostają niezmienione.

        private void buttonZapisz_Click(object sender, EventArgs e)
        {
            
            string nrFaktur = "00001";
            foreach (DataGridViewRow dvr in this.fakturypozycjeDataGridView.Rows)
            {
                dvr.Cells[0].Value = nrFaktury;
            }

            this.Validate();
            this.fakturyBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.dataSetFaktury);
        }

Czy coś robię nie tak ?

A teraz działanie które nie powinno niczego zmienić : wprowadzenie kolejnej pętli powoduje, że po jej wykonaniu już dwa pierwsze wiersze przyjmują prawidłową wartość.

        private void buttonZapisz_Click(object sender, EventArgs e)
        {
            
            string nrFaktur = "00001";
            foreach (DataGridViewRow dvr in this.fakturypozycjeDataGridView.Rows)
            {
                dvr.Cells[0].Value = nrFaktury;
            }

            for (int i = 0; i < this.fakturypozycjeDataGridView.RowCount; i++)
            {
                this.fakturypozycjeDataGridView.Rows[i].Cells[0].Value = NrFaktury;
            }
          
            this.Validate();
            this.fakturyBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.dataSetFaktury);
        }

Gdzie popełniam błąd ?

0
  1. sprawdzales ile wynosi Rows.Count ?
  2. czy to ze w gornej masz Cells[0] a w dolnej Cells[1] ma szczegolne znaczenie? czy to tylko taki test byl?
  3. czy pod grid'a/view'a/etc masz podpiete jakies zdarzenia w stylu cellvaluechanged? nie o tej nazwie, ale z tym sensem
  4. wartosci nie pojawiaja sie w gridzie czy na bazie danych?
  5. probowales zamiast podmieniac wartosci w gridview zrobic to na jego datasource? tzn. nie na kontrolce, tylko na datatable/dataset z ktorego ta kontrolka czerpie
0

Drogą prób i błędów sprawdziłem, że natychmiast po zmianie wartości komórki będącej kluczem w relacji z tabelą wiodącą, cały wiersz zostaje "zrzucony" z kolekcji DataGridView.

Tak więc należałoby się skupić tylko na wierszu [0] :

        private void buttonZapisz_Click(object sender, EventArgs e)
        {
              string nrFaktur = "00001";

              for (int i = 0; i < DataGridView.RowCount; i++)
                      DataGridView.Rows[0].Cells[1].Value = nrFaktur;

              this.Validate();
              this.fakturyBindingSource.EndEdit();
              this.tableAdapterManager.UpdateAll(this.dataSetFaktury);
        }

Po takiej zmianie kodu, pozycje faktury mają już prawidłowy numer faktury , z WYJĄTKIEM ostatniej pozycji, która również ma właściwy numer , ale nie zostaje przekazana do tabeli.

quetzalcoatl napisał(a)
  1. sprawdzales ile wynosi Rows.Count ?

Jest zmienne w trakcie wykonywania pętli. Tak jak napisałem wcześniej, modyfikacja kluczowej komórki powoduje zrzucenie wiersza z kolekcji i Rows.Count również ulega zmianie.

quetzalcoatl napisał(a)
  1. czy to ze w gornej masz Cells[0] a w dolnej Cells[1] ma szczegolne
    znaczenie? czy to tylko taki test byl?

To była tylko literówka przy pisaniu kodu w tym wątlku. Problem dotyczy tylko Cells[0].

quetzalcoatl napisał(a)
  1. czy pod grid'a/view'a/etc masz podpiete jakies zdarzenia w stylu cellvaluechanged? nie o tej nazwie, ale z tym sensem

Nie mam .

quetzalcoatl napisał(a)
  1. wartosci nie pojawiaja sie w gridzie czy na bazie danych?

Po wyżej opisanej modyfikacji pętli, z kolekcji grida zostają odrzucone wiersze z nowym numerem faktury(i jest to logiczne), ale pozostaje niezmieniony ostatni wiersz w kolekcji. Odrzucone wiersze są prawidłowo zapisywane w tabeli, a ostatni wiersz , który pozostał w kolekcji trafia do tabeli bez modyfikacji numeru faktury (NrFaktury = null).

Zapewne jest jakiś prosty sposób na rozwiązanie tego problemu - może ktoś coś podpowie :-)

quetzalcoatl napisał(a)
  1. probowales zamiast podmieniac wartosci w gridview zrobic to na jego datasource? tzn. nie na kontrolce, tylko na datatable/dataset z ktorego ta kontrolka czerpie

Nie próbowałem ponieważ na razie nie wiem jak się za to zabrać - chciałem to zrobić najprostszą i najszybszą wg mnie metodą.

0

szczerze mowiac, ciezko mi sie troche juz dzisiaj mysli o tej porze.. ale pomyslalo mi sie:

  • z konstrukcji petli wynika, ze przeleci ona po wszystkich wierszach i na kazdym wykona cells[]=value. czy na ostatnim wiersuz tez to sie wykonuje i potem 'gubi' wartocs? czy tez jakims trafem zostaje on pominiety?
  • jesli wartosc jest tam tez wpisywana, ale potem zapominana - moze jest to grid edycyjny i moze ten ostatni wiersz jest EditingRow'em bedacym w trakcie edycji i grid uznaje ze edycja nie zostala zakonczona i ja anulowuje
  • a jesli jakims trafem jest pomijany - nie mam pojecia jakim - mozna sprobowac odebrac wiersze do tymczasowej kolekcji/tablicy na boku i przeiterowac po niej bez obaw ze beda znikac..
0
quetzalcoatl napisał(a)

szczerze mowiac, ciezko mi sie troche juz dzisiaj mysli o tej porze.. ale pomyslalo mi sie:..

To tym bardziej dziękuję za pomoc !

quetzalcoatl napisał(a)
  • z konstrukcji petli wynika, ze przeleci ona po wszystkich wierszach i na kazdym wykona cells[]=value. czy na ostatnim wiersuz tez to sie wykonuje i potem 'gubi' wartocs? czy tez jakims trafem zostaje on pominiety?

Pętla przechodzi przez wszystkie wiersze i we wszystkich wierszach zostaje zmodyfikowana komórka.

quetzalcoatl napisał(a)
  • jesli wartosc jest tam tez wpisywana, ale potem zapominana - moze jest to grid edycyjny i moze ten ostatni wiersz jest EditingRow'em bedacym w trakcie edycji i grid uznaje ze edycja nie zostala zakonczona i ja anulowuje

Na wszelaki wypadek dodałem przed pętlą :

this.fakturypozycjeDataGridView.EndEdit();

Pomimo tego, nadal komórka NrFaktury w ostatnim wierszu DataGridView zostaje zmodyfikowana, ale zmiany te nie są wprowadzone do tabeli :(
Jeżeli jest to istotne, gdy bezpośrednio po wykonaniu pętli wrócę do formularza, w DataGridView jest widoczny tylko jeden ostatni wiersz z prawidłowo podmienionym numerem faktury i dopiero po ręcznym przejściu do nowego wiersza, ten "zapomniany" wiersz zostaje dopiero wtedy odrzucony z kolekcji i znika.
Wygląda to tak, jakby rzeczywiście pozostawał w trybie edycji i jest nie do ruszenia.

Jednak gdy do faktury wprowadzam tylko jedną pozycję, jest ona prawidłowo zapisywana do tablel. Problem pojawia się gdy faktury posiadają dwie lub więcej pozycji - wartość pola NrFaktury dla ostatniej pozycji wynosi wtedy null.

quetzalcoatl napisał(a)
  • a jesli jakims trafem jest pomijany - nie mam pojecia jakim - mozna sprobowac odebrac wiersze do tymczasowej kolekcji/tablicy na boku i przeiterowac po niej bez obaw ze beda znikac..

To również może być rozwiązanie, ale wolałbym tak daleko nie kombinowac z prostą czynnością (tak mi się przynajmniej kilka dni temu wydawało :( ).

0

niestety po tym co napisales, pomysly mi sie skonczyly. zeby cos wiecej 'zdiagnozowac', musialbym zerknac na caly kod i pobawic sie reflectorem na kontrolce datagrida.. a tak to zostaje happy random..

jak na razie, wydaje mi sie, ze albo trafiles na jedno z (wielu..) niedociagniec w podstawowych kontrolkach frameworka i po prostu trzeba to obejsc na okolo, albo - ze masz pecha i jakies Twoje wczesniejsze akcje jakims trafem zaburzyly ktorys z 'cykli zycia' kontrolek.. ale z tego co mowisz, utrzymujesz wszystko w prostej formie, wiec watpie..

propozycja szybkiego fixu na chama: jesli ten wiersz ostatni zostaje na gridzie i 'wyklikanie' sie z tego wiersza pomaga (btw. z tego co piszesz, tymbardziej mi to wyglada na to ze jest objety edycja.. ale kto to wie:/) to po end edit, po petli przelatujacej powierszach, przed zapisaem do bazy - nakaz gridowi zdefocusowac ten wiersz, ciezko mi powiedziec jak (ciagle mi sie miesza z kontrolkami z paczki DevExpress wiec sorry jesli cos totalnie z kosmosu powiem gdzies).. na bank grid ma jakas medote od focusowania albo zaznaczania wiersza - podanie '-1' jako numeru wiersza powinno wybrac wiersz edycyjny albo żaden, powinno to miec taki sam efekt jak ednedit+'wyklikanie sie z niego'

0

No cóż, na razie odpuszczam więc grzebanie w DGV, ale problem pozostaje.
Muszę inną metodą wprowadzić wygenerowany numer faktury dla wszystkich pozycji faktury :

  1. zmodyfikować zapytanie "INSERT ......" w DataSet.Designer (działa - ale nie chciałbym grzebać w tym pliku)
  2. triger w MySQL (działa, ale mało czytelne z poziomu programu)
  3. zmodyfikować numer pozycji faktury w dataSet powiązanym z DGV przez BindingManagerBase

Dwie pierwsze pozycje są najprostsze do wykonania i działają, ale jest to nieczytelne rozwiazanie i chciałbym tego uniknąć. Poza tym, taki zabieg pomija aktualizację danych w DataSet oraz DGV.

Punkt 3 wydaje się najwłaściwszy do wykonania tego zadania i przy tym pozostanę.

Tak więc problem został rozwiązany nieco inną drogą :)

Dziękuję za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1