Narazil jsem na zajímavý Xamarin.Forms problém na StackOverflow, který jsem podomácku nazval "Xamarin.Forms a případ x:Name-vraždící události". Tazatel vytvořil nevinně vypadající Xamarin.Forms stránku s následujícím obsahem:
<Entry x:Name="Vid"/> <Button Text="Search" Pressed="SearchPressed" />
A takto vypadal code-behind:
void SearchPressed( object sender ) { Application.Current.MainPage = new AnotherPage( Vid.Text ); }
Problém byl velmi jednoduchý ale překvapivý. Když uživatel kliknul na tlačítko, x:Name Vid
uvnitř metody SearchPressed
bylo null
, což způsobilo NullReferenceException
. Nejdříve jsem jal podezření, že stránka se nesprávně inicializovala, načež mě však tázající upozornil, že hned po volání InitializeComponent()
uvnitř konstruktoru ukazovaloVid
na správnou instanci Entry
, takže k jejímu "vynulování" muselo dojít někdy mezi voláním konstruktoru a zpracováním události. A aby toho nebylo málo, kód fungoval na Androidu bez problémů, zatímco padal na UWP. Problém se mi podařilo replikovat na svém počítači, což vyloučilo cyklus "oprava/reinstalace Visual Studia a Xamarinu" a nemohl jsem poochopit, co se děje. Celá věc mi nedávala smysl, protože kód byl opravdu jednoduchý a nebyl důvod, proč by neměl fungovat. Pouze po dlouhém zírání jsem to uviděl. Event handler. Ten event handler!
void SearchPressed( object sender ) // <- něco tady chybí!
Samozřejmě! Každý správný event handler přece musí mít parametr EventArgs
! Takhle by měl event handler vypadat správně:
void SearchVideo( object sender, EventArgs e )
Tato malá změna stačila aby Vid
znovu ukazoval na náš Entry
a vše fungovalo bez potíží.
Ponaučení
Podobné problémy není snadné ladit, především pokud kód nefunguje jen na jedné z platforem. Naštěstí tomuto konkrétnímu přehmatu lze poměrně snadno předejít použitím XAML IntelliSense ve Visual Studiu, který nám dokáže event handler ve správném tvaru automaticky vygenerovat. To je většinou rychlejší, pohodlnější a zachrání nás před nemilými překvapeními :-) .