Zmiana zawartości pola z tabeli w bazie danych na inną do wyświetlenia w DataGrid

9-sty-2011

Tym razem problem jest następujący:

Projektant bazy danych przewidziałw tabeli kolumnę o znaczeniu symbolicznym np. przez literę R oznacza zmianę ranną, P – popołudniową, a N – nocną. Jendak w DataGrid nie chcemy wyświetlać oznaczeń literowych R/P/N, tylko pełne napisy Ranna/Popołudniowa/Nocna.

Pierwsze z proponowanych rozwiązań polega na utworzeniu odpowiedniego zapytania SQL, które pobierze z bazy danych nie tylko oznaczenia literowe, ale także skonstruuje opisy. Tak skonstruowane zapytanie zasili następnie DataSet, który przekaże dane do DataGrida. Przykładowe zapytanie może wyglądać następująco:

SELECT 
        CzasStart, CzasStop, Symbol
       ,CASE Symbol
                        WHEN 'R' THEN 'Ranna'
                        WHEN 'P' THEN 'Popołudniowa'
                        WHEN 'N" THEN 'Nocna'
        END AS 'Nazwa'
FROM Zmiany

Jak widać, część prezentacyjna programu została w ten sposób przeniesiona do warstwy dostępu do bazy danych, a to nie jest zbyt dobrze.

Kolejne rozwiązanie opiera się o  zdarzenie CellFormating wywoływane podczas wyświetlania zawartości komórki grida. (Dokładniejszy opis pod adresem http://stackoverflow.com/questions/1716984/datacolumn-datagridview-replace-specific-value). W naszym przypadku metoda mogłaby wyglądać następująco:

 private void dataGridZmiany_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
     //e.ColumnIndex to numer koluny DataGrid
     //dataGridZmiany.Columns[e.ColumnIndex].Name zawiera nazwę kolumny
     //Wynik należy zwrócić do zmiennej e.Value

     if (dataGridZmiany.Columns[e.ColumnIndex].Name == "Nazwa")
     {
            switch (e.Value.ToString())
            {
                case "R": e.Value = "Ranna";
                    break;
                case "P": e.Value = "Popołudniowa";
                    break;
                case "N": e.Value = "Nocna";
                    break;
            }
      }    
}

Tutaj dostęp do danych nie został zmieniony, rzeczywiście zmienia się jedynie sposób prezentowania informacji.

Kolejna metoda mogłaby polegać na ustawieniu dla całego obiektu DataGrid właściwości OwnerDraw na TRUE i samodzielnemu obsługiwaniu zdarzenia rysowania zawartości komórki. Metoda powinna sprawdzić adres komórki grida (wiersz i kolumnę) i w razie potrzeby wywołać standardową metodę rysowania zawartości:

e.DrawCell();
return;

lub wyrysować ją samodzielnie:

e.Image = GetEmbeddedIcon("Ikony.noc.bmp");

To rozwiązanie ma tę wadę, że trzeba samodzielnie zadbać o ustawienie odpowiedzniej szerokości kolumny, wyświetlenie hinta (dymku) itp.

Komentarze są wyłączone

Autor: Rafał Kraik