Nem rég szembejött a probléma, hogy egy sokablakos, bonyolult WPF-app működése során néha kézzel – vagyis kóddal – kellene a fókuszt egy DataGrid egy sorára helyezni. A DataGrid.Focus() és a SelectedIndex beállításának kombója nem járható út, ilyenkor maga a Grid kapja meg a fókuszt, nem lehet rögtön lépkedni benne a le/fel nyilakkal.
Mit tehet ilyenkor az ember? Kiválasztja az adott sort a Rows tulajdonságból, és meghívja azon a Focust. Igen ám, de nem. Nincs Row/Rows tulajdonság, amiből kiválaszthatnánk a sorokat, illetve nincs GetRow metódus. Itt kezdené visszasírni az ember a DataGridViewt. 🙂
(Amúgy nem. Épp valamelyik nap kellett vele dolgoznom, és így 2-3 év WPF-ezés után már érzi az ember, hogy a DataGrid barátibb. Bár ez ízlés dolga.)
Akkor mit lehet tenni?
Nos, a DataGridnek, mint minden ItemsControlnak van egy Items tulajdonsága. Ezen keresztül elérhetjük az elemeket, amelyeket meg kell jelenítenie a gridnek. A probéma csak az, hogy ezek tényleg a megjelenítendő elemek. Az adatok a grid mögött, nem pedig a vizuális fában megjelenő sorok/cellák. Magyarán ez egy objectekből álló lista, tehát esélyünk sincs Focust hívni rajtuk, és kasztolni is max. az adattípusra tudjuk, amivel megint nem vagyunk beljebb.
Nem húzom tovább a dolgot (nem lenne mókás, ha végigvinnélek titeket azon a fél órás hajhulláson, amíg eljutottam a megoldásig 🙂 ), inkább prezentálom a végeredményt.
public static class DataGridExtender
{
public static bool SetFocusOnDataGridRow(this DataGrid dg,
int rownum = 0, bool setSelectedIndex = true)
{
if (rownum >= 0 && rownum < dg.Items.Count)
{
DataGridRow dgrow = (DataGridRow)dg.ItemContainerGenerator
.ContainerFromItem(dg.Items[rownum]);
if (setSelectedIndex) dg.SelectedIndex = rownum;
return dgrow.Focus();
}
return false;
}
}
Na, nézzük, mit látunk…
Ahogy látható, a C# 3.0 extension method (bővítőfüggvény) rendszerét használjuk, hogy a DataGrid osztálynak adjunk egy plusz metódust. A rownum paraméterrel várjuk, hogy mely sort akarják kiválasztani, a setSelectedIndex pedig azért “kell”, mert a fókuszáthelyezés és a grid kiválasztott elemének beállítása két külön dolog – ez a metódus képes lesz külön kezelni ezeket. A paraméterlistában kihasználom a C# 4.0-ás optional/named parameter fejlesztését, így a metódus gyakorlatilag paraméterek átadása nélkül is hívható lesz.
Ezek után jön a varázslat. A DataGrid ItemContainerGeneratorjának pontosan az a feladata, hogy egy adott adatelemhez (amit a fentebb ismertetett módon ki tudunk szedni a gridből) adjon nekünk egy olyan objektumot, ami a vizuális fában reprezentálja majd ezt az elemet. Vagyis eme objektum segítségével tudjuk áthidalni a szakadékot a megjelenítendő adat és a konkrét vizuális reprezentáció között.
A következő sor gondolom, világos: ha a programozó kérte, a selectedindexet is beállítjuk a sorra.
Ezután jön az, hogy akkor ki is jelöljük a sort, vagyis rárakjuk a fókuszt. Látható, hogy ez sem nehéz.
Ha kipróbáljátok, látni fogjátok, hogy azért nem tökéletes a leányzó fekvése. A sort kijelöli, a fókuszt is rárakja, de nem lehet rögtön mozogni a nyilakkal, mert a DataGridben cellánként megy az ugrálás – és most még nincs kijelölt cella.
A WPF-nek van egy nagyon szép bonyolult fókuszkezelő alrendszere, ami hajlamos igen randomisztikusan működni, de itt speciel pont jó lesz nekünk. Ha lecseréljük a “fókuszátrakó” sort a következőre, máris kijelöli az első cellánkat a fókusz rárakásánál:
return dgrow.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
Ennyi. Máris azonnal lépkedhető a gridünk. Remélem, sikerül megspórolnom némi kollektív hajhullást. 🙂
A WorkItemek nem oldják meg magukat, úgyhogy most (megintcsak) vissza kódolni.
ui.: bocs a kódszöveg mérete miatt, még harcolok a wordpress-szel, hogy ne legyen satu.
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDetect languageDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
⇄AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
English (auto-detected) » English
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDetect languageDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
⇄AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
English (auto-detected) » English
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDetect languageDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish⇄AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
English (auto-detected) » English
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDetect languageDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish⇄AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
English (auto-detected) » English
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDetect languageDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish⇄AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBulgarianCatalanChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKoreanLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishThaiTurkishUkrainianUrduVietnameseWelshYiddish
English (auto-detected) » English
Tetszett a bejegyzés?
Tetszik Betöltés...
Kapcsolódó bejegyzések