XAML.cz Magazín moderních technologií založených na XAML

Navigace v ListBoxu pomocí TreeView

Napsáno pro WPF od Jarda Jirava  [11.06.2010]

Snad každého nadšence a vývojáře potěší, když se o technologii, kterou si zvolil začne zajímat větší okruh lidí. Jednak má možnost svoje případné problémy s kým řešit a druhak ví, že to asi není tak úplně slepá cesta, kterou se vydal.

A tak i mě potěšilo, hned dvakrát, že se poslední dobou začali i na českých komunitních fórech objevovat čím dál častěji otázky týkající se WPF a případně Silverlightu.

Jedna taková, poměrně záludná, byla položena na serveru builder.cz a to WPF synchronizace TreeView a ItemsControl, kde se David dotazoval jakým způsobem provést navigaci v ListBoxu, který používá vlastní DataTemplate přes ItemTemplateSelector, pomocí TreeView. TreeView v tomto případě bylo použito z toho důvodu, že zdroj dat byl hierarchický a tomu odpovídalo i vykreslování v navigovaném ListBoxu.

Na první pohled by to nemělo být nic složitého. David však přiložil příklad, který vše jasně demonstroval (mimochodem, takováto snaha získat odpověď se docela vymyká z tamních standardů). Narychlo jsem tak zkusil několik pokusů, které však ke správnému výsledku nevedly.

V noci jsem pak měl chvíli čas a tak jsem se k problému vrátil a pokusil se jej dořešit do zdárného konce. Co mě napadlo hned jako první, už při prvním pokusu, že je využívána virtualizace pro ListBox a tak nedojde k vygenerování všech prvků, na které je následně navěšena attached property.

Tuto skutečnost jsem si ověřil tedy jako první a skutečně tomu tak bylo. ListBox od verze .NET 3.5 SP1 používá jako výchozí panel pro vykreslování prvků VirtualizingStackPanel. Což je samozřejmě na jednu stranu chválihodné, na druhou to zapříčinilo výše popisovaný problém.

Možným řešením je tak vypnout tuto virtualizaci a nechat si vykreslit všechny prvky pomocí nastavení attached vlastnosti VirtualizingStackPanel.IsVirtualizing="False". Tím dojde nejen k vykreslení všech prvků ihned, ale zároveň se nastaví i attached property, která zajistí přesun vybraného prvku do viditelné části ListBoxu pomocí volání metody BringIntoView.

Úvaha nad možným řešením

Když jsem dále přemýšlel, jak by se daný problém dal řešit, napadlo mě hned několik možných řešení. Ani jedno jsem nerealizoval a je to tedy skutečně jen úvaha, která nemusí být realizovatelná.

Ona úvaha spočívá ve využití rozhraní IScrollInfo, kterým ListBox disponuje a pomocí něhož se dá nastavit – odskrolovat – na pozici, kterou potřebujeme. Pokud by tedy výška prvků byla známá, tak by nemuselo být velkým problémem zjistit potřebnou pozici vybraného prvku a tuto nastavit přes IScrollInfo. Tím by se dalo použít i nadále možností virtualizace prvků v ListBoxu.

Je to jen námět a pokud jej David nebo kdokoliv jiný úspěšně nebo i neúspěšně realizuje, budu rád, pokud se o to podělí v komentářích.

Komentáře

ukládám komentář, vyčkejte prosím..
  1. Buďte první, kdo napíše komentář.

@xamlcz

  • RT @jvanrhyn: XAML, It's a bit like olives. Takes a while to get used to. But once you're used to it. It is actually pretty good. <3 XAML
  • RT @moser_christian: WPF Inspector 0.9.7 is released. It supports .NET 3.5 and 4.0 The project is now open source and available on CodeP ...
  • Jeff Handley oznámil vydání WCF RIA Services v.1.0 SP1 RTM http://bit.ly/gOgckn ke stažení na http://bit.ly/gVAXdK
  • jedna výzva pro Brno. Byl někdo z vás na přednášce o RIA v MS Akvárku? Dejte o sobě vědět. Děkuji
  • také jste uvažovali o tom, že zkusíte na projekt použít Caliburn Micro nebo naopak Prism 4? A co tak obojí, šlo by to nebo ne? Již brzy