DataGridViewCheckBoxColumn - Validating...

0

Mam problem z prawidłową obsługą zdarzenia zmiany wartości w kolumnie typu DataGridViewCheckBoxColumn (kolumna z CheckBox-ami w DataGridView).
Potrzebuję mieć obsługę zmiany wartości zaznaczenie w tej kolumnie natychmiast po zmianie zaznaczenia (kliknięcie lub zmiana za pomocą spacji).
Wygląda na to że system wykrywa taką zmianę (zdarzenie Validating) dopiero po opuszczeniu danej celi, a tutaj chodzi o reakcję natychmiast po wykonaniu zmiany.
Czy ktoś już się spotkał z takim problemem?
Jeżeli tak, to będę wdzięczny za wszelkie uwagi na ten temat.

0

tak.. ostatnio u mnie w pracy wymagano podobnego efektu i jeszce kilku innych wodotryskow jak np. podswietlenie na czerwono jak wartosc wprowadzona jest zla i skonczylo sie na tym ze musialem stworzyc wlasna subklase kolumn, subklase komorki, subklase panelu kontrolki edycyjnej i dostarczyc wlasna kontrolke edycyjna.. a prawidlowa obsluga powiazan pomiedzy nimi to to mozna pol ksiazki napisac..

ogolnie, podczas normalne pracy, datagridview w ogóle nie interesuje sie faktem ze cos w niego wpisujesz. on reaguje dopiero po skonczonej edycji pola --- czyli utracie przez to pole focusu. masz sporo szczescia i nieszczescia ze operujesz na checkboxach. nieszcescie polega na tym, ze te checkboxy nieistnieja. sa udawane - obiekt komorki datagridviewa rysuje je 'z palca' i udaje ich zachowanie. szczescie masz natomiast w tym, ze obiekt komorki udostepnia event OnClick - podepnij sie pod niego w sposob

winitializeczygdziesindziej() { (komorka as datagridviewcheckboxcell).Click += new eventhandler(datagridviewcell_click); }

private blahblah datagridviewcell_click(sender, args)
{
if( (sender as datagridviewcheckboxcell).Checked )
//blah
else
//blah
}


musisz tylko spradzic czy sender rzeczywiscie bedzie obiektem komorki -- mozliwe ze bedzie obiektem datagrida, wtedy gorzej, no ale lapiesz o co chodzi :)
0

Moment kliknięcia wychwycisz przez CellClick, spację przez KeyPress. Rozwiązanie może niezbyt eleganckie, ale za to łatwe w implementacji.

0

Dzięki za odpowiedź :)
Próbowałem już ze znarzeniami OnClick i KeyPresses dla DataGrida, ale wtedy jest problem ze zbadaniem faktycznego stanu klikanej komórki, ponieważ DataGrid widzi ciągle "starą" wartość, która zmienia się dopiero po zmianie focus-a - tak jak napisałeś.
Nie próbowałem jeszcze z podpinaniem zdarzeń bezpośrednio do celi. Zaraz tego spróbuję i dam znać o efektach.

0

Jeste tylko drobny problem.
DataGridViewCheckBoxCell nie ma publicznego zdarzenia Click
(używam VS .NET 2005, .NET Framework 2.0)

0

Jest działające rozwiązanie dla klienkięcja myszką:

private void datagridview_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
datagridview.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange);
Do_Sth_On_Selection_Chenge();
}

// Musi być MuseUp, bo inaczej źle wykrywa dwuklik - generuje tylko jedno zdarzenia, a tak naprawdę w CheckBox-ie stan zmienia się 2 razy

private void Do_Sth_On_Selection_Chenge()
{
// ...
}

To samo rozwiązanie nie działa prawidłowo dla klawiatury (sprawdziłem dla zdarzenia KeyPressed i KeyUp - źle wykrywa stan zaznaczenia komórki - coś jest nie tak z kolejnością zatwierdzania zmian w komórkach). Ale trzeba szukać dalej :)

0
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
            column.Name = "Column1";
            column.HeaderText = "Column1";
            dataGridView1.Columns.Add(column);

            for (int i = 0; i<10;i++)
            {
                dataGridView1.Rows.Add();
                dataGridView1.Rows[i].Cells[0].Value = false;
            }

            this.dataGridView1.CellMouseUp += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView1_CellMouseUp);
            this.dataGridView1.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);
            this.dataGridView1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.dataGridView1_KeyUp);            
        }
             
        private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {            
            MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString());
        }

        private void dataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex == 0 & e.RowIndex >= 0)
            {                 
                dataGridView1.EndEdit();                
            }
        }

        private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
        {           
            if (e.KeyCode == Keys.Space)
            {
                dataGridView1.SelectedCells[0].Value = !((bool)dataGridView1.SelectedCells[0].Value);
                dataGridView1.EndEdit();
            }
        }            
    }

A tu zupełnie działające rozwiązanie. :) Zwróć uwagę na to, że metody wiążę ze zdarzeniami dopiero po napełnieniu DataGrida (!).

0

Wielkie dzięki!
Jesteś WIELKI.

Nie wiem tylko czemu zwracasz uwagę na kolejność 1. wypełnianie data grida 2. podłaczenie metod.
Ja zrobiłem standardowo (metody podłączone w designerze - czyli odpala się na konstuktorze), a wypełnianie DataGrida mam później.... i działa idealnie!!

Jeszcze raz wielkie dzięki!!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.