Nekonzistentní chování Resources v ItemTemplate pro Anniversary Update

Zdá se, že Windows 10 Anniversary Update obsahuje skrytou chybu ve zpracování Resources unvitř ItemTemplate pro položky seznamů. Narazil jsem na ni při práci na UWP aplikaci a popíšu problém samotný spolu s řešením, kterým můžete zajistit, že se vaše aplikace bude chovat správně na všech verzích Windows 10.

Problém

Předpokládejme že chceme vytvořit seznam položek následujícího typu:

Budeme používat vlastnost IsAnimating  abychom určili, kdy se budou jednotlivé položky seznamu animovat.

Nyní implementujeme ListView , který položky zobrazí:

Je nutné podotknout dvě důležité věci o ItemTemplate  našeho ListView :

  • Do Resources jsme přidali Storyboard BlinkingAnimation . Tato animace zajistí, že bude pozadí položky seznamu blikat červeně.
  • Každá položka obsahuje DataTriggerBehavior  a ControlStoryboardAction , které jsou součástí balíčku XAML Behaviors (zde na GitHubu). Pomocí nich chceme spouštět animaci právě když se změní hodnota vlastnosti IsAnimating

Očekáváme, že po spuštění aplikace a nastavení Items[2].IsAnimating = true  začne třetí položka seznamu blikat červeně. Překvapivě to však v případě  Anniversary Update není pravda.

Jak můžete vidět, jak November Update (build 10586) tak Creators Update (build 15063) pracují správně. U Anniversary Update se ale vlastnost IsAnimating  nastaví správně u třetí položky, ale animace se spustí na první položce seznamu.

Experimenty

Vyzkoušel jsem některé experimenty, abych zjistil, co se přesně odehrává.

Nezáleží na SDK, pro které aplikaci zkompilujeme. Aplikace se vždy chová stejně bez ohledu na SDK, jediné co rozhoduje je verze Windows 10, na které běží.

Chování je stejné pro Mobile i Desktop SKU.

Pokud zkusíme debugovat ControlStoryboardAction , zjistíme, že u Anniversary Update je instance Storyboardu, který je nastaven jeho stejnojmenné vlastnosti pomocí výrazu StaticResource  je skutečně vždy instancí první položky seznamu. Přesto však každá položka vytváří svou vlastní unikátní instanci, která však není použita.

Je zřejmé, že v Anniversary Update systém zpracovává Resources v DataTemplate trochu jinak než v ostatních verzích Windows 10. Protože se “správné” chování v Creators Update vrátilo, lze pravděpodobně bezpečně říci, že jde o nedokumentovaný bug.

Řešení

Naštěstí je velmi snadné problém obejít. Můžeme zabalit obsah ItemTemplate  do UserControlu  a použít jej namísto přímého obsahu.

Nejprve do projektu přidáme nový UserControl s následujícím XAML kódem:

A použijeme jej v seznamu takto:

Všimněme si, že data binding pomocí syntaxe Binding  nadále funguje, protože UserControl  používá aktuální DataContext . Pokud chceme použít x:Bind syntaxi, musíme vytvořit manuálně novou dependency property, ke které budeme bindovat.

Tato jednoduchá změna zajistí, že animace bude fungovat správně ve všech verzích Windows 10.

Následující obrázky porovnávají najednou obě implementace:

Zdrojový kód

Ukázkový zdrojový kód k tomuto článku je dostupný na mém GitHubu.

Shrnutí

Ukázali jsme si, že Anniversary Upate nepracuje s Resource uvnitř položek seznamů správně. Přestože jde nyní (duben 2017) o nejpoužívanější verzi  Windows 10, zdá se, že tento problém zatím nebyl nikde dokumentován.

Naštěstí pro nás vývojáře je možné chybu snadno obejít zabalením obsahu ItemTemplate  do UserControlu , čímž vynutíme správné chování ve všech verzích Windows 10.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*