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.