Xamarin.Forms a případ x:Name-vraždící události

Xamarin WinUI XAML

6 years ago

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". Xamarin logo 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 :-) .