Pokyny pro návrh ovládacích prvků s podporou stylů

Tento dokument shrnuje sadu osvědčených postupů, které je potřeba zvážit při návrhu ovládacího prvku, který chcete snadno stylizovat a šablonovat. K této sadě osvědčených postupů jsme přišli prostřednictvím velkého počtu pokusů a chyb při práci na stylech ovládacích prvků motivu pro integrovanou sadu ovládacích prvků WPF. Dozvěděli jsme se, že úspěšný styl je stejně funkcí dobře navrženého objektového modelu, jako je samotný styl. Zamýšlenou cílovou skupinou pro tento dokument je autor ovládacího prvku, nikoli autor stylu.

Terminologie

Styling a šablonování odkazují na sadu technologií, které umožňují autorovi ovládacího prvku odložit vizuální aspekty ovládacího prvku na styl a šablonu ovládacího prvku. Tato sada technologií zahrnuje:

  • Styly (včetně setter vlastností, triggerů a scénářů)

  • Prostředky:

  • Šablony ovládacích prvků

  • Šablony dat.

Úvod k stylům a šablonování najdete v tématu Styling a Šablonování.

Než začnete: Pochopení ovládacího prvku

Než se pustíte do těchto pokynů, je důležité pochopit a definovat běžné používání ovládacího prvku. Styling zveřejňuje často nerušnou sadu možností. Ovládací prvky napsané tak, aby se používaly široce (v mnoha aplikacích, mnoha vývojáři) čelí výzvě, kterou je možné použít k provádění dalekosáhlých změn vizuálního vzhledu ovládacího prvku. Ve skutečnosti se stylovaný ovládací prvek nemusí ani podobat záměrům autora ovládacího prvku. Vzhledem k tomu, že flexibilita, kterou styling nabízí, je v podstatě neomezená, můžete použít myšlenku společného použití, která vám pomůže určit rozsah rozhodnutí.

Abyste pochopili běžné použití ovládacího prvku, je vhodné uvažovat o hodnotové nabídce ovládacího prvku. Co váš ovládací prvek přináší do tabulky, kterou nemůže nabídnout žádný jiný ovládací prvek? Běžné použití neznamená žádný konkrétní vizuální vzhled, ale spíše filozofie ovládacího prvku a přiměřenou sadu očekávání o jeho použití. Toto porozumění vám umožní provést určité předpoklady o modelu složení a chování definované stylem ovládacího prvku v běžném případě. V případě ComboBox, například pochopení společného použití vám neudělí žádný přehled o tom, jestli má konkrétní ComboBox zaoblené rohy, ale poskytne vám přehled o skutečnosti, že ComboBox pravděpodobně potřebuje automaticky otevírané okno a nějaký způsob přepínání, jestli je otevřený.

Obecné pokyny

  • Nevynucujte výhradně kontrakty šablon. Kontrakt šablony ovládacího prvku se může skládat z prvků, příkazů, vazeb, triggerů nebo dokonce nastavení vlastností, které jsou požadovány nebo očekávány pro správné fungování ovládacího prvku.

    • Co nejvíce minimalizujte kontrakty.

    • Návrh kolem očekávání, že během návrhu (tj. při použití nástroje pro návrh) je běžné, že šablona ovládacího prvku bude v neúplném stavu. WPF nenabízí "vytváření" stavové infrastruktury, takže ovládací prvky musí být sestaveny s očekáváním, že takový stav může být platný.

    • Nevyvolávejte výjimky, pokud není dodržen žádný aspekt kontraktu šablony. V těchto řádcích by panely neměly vyvolat výjimky, pokud mají příliš mnoho nebo příliš málo podřízených položek.

  • Funkce periferního zařízení faktoru do pomocných prvků šablony Každý ovládací prvek by se měl zaměřit na jeho základní funkce a skutečnou hodnotu a definovat běžné použití ovládacího prvku. Za tímto účelem pomocí skládání a pomocných prvků v šabloně povolte periferní chování a vizualizace, to znamená, že tato chování a vizualizace, které nepřispívají k základním funkcím ovládacího prvku. Pomocné prvky spadají do tří kategorií:

    • Samostatné pomocné typy jsou veřejné a opakovaně použitelné ovládací prvky nebo primitivy, které se v šabloně používají "anonymně", což znamená, že ani pomocný prvek ani stylovaný ovládací prvek ostatní nezná. Technicky vzato může být libovolný prvek anonymním typem, ale v tomto kontextu termín popisuje typy, které zapouzdřují specializované funkce umožňující cílené scénáře.

    • Pomocné prvky založené na typech jsou nové typy, které zapouzdřují specializované funkce. Tyto prvky jsou obvykle navrženy s užším rozsahem funkcí než běžné ovládací prvky nebo primitivy. Na rozdíl od samostatných pomocných prvků jsou pomocné prvky založené na typech vědomy kontextu, ve kterém se používají, a obvykle musí sdílet data s ovládacím prvku, do jehož šablony patří.

    • Pojmenované pomocné prvky jsou běžné ovládací prvky nebo primitivy, které ovládací prvek očekává, že se v rámci šablony najde podle názvu. Tyto prvky mají v šabloně dobře známý název, takže ovládací prvek může najít prvek a interagovat s ním programově. V libovolné šabloně může být pouze jeden prvek s daným názvem.

    V následující tabulce jsou uvedeny pomocné prvky používané styly ovládacích prvků dnes (tento seznam není vyčerpávající):

    Element (Prvek) Type Používá
    ContentPresenter Na základě typu Button, , CheckBoxRadioButton, Framea tak dále (všechny ContentControl typy)
    ItemsPresenter Na základě typu ListBox, ComboBox, Menua tak dále (všechny ItemsControl typy)
    ToolBarOverflowPanel S názvem ToolBar
    Popup Samostatné ComboBox, ToolBar, Menu, ToolTipa tak dále
    RepeatButton S názvem Slider, ScrollBara tak dále
    ScrollBar S názvem ScrollViewer
    ScrollViewer Samostatné ListBox, ComboBox, Menu, Framea tak dále
    TabPanel Samostatné TabControl
    TextBox S názvem ComboBox
    TickBar Na základě typu Slider
  • Minimalizujte požadované vazby zadané uživatelem nebo nastavení vlastností u pomocných prvků. Pomocný prvek obvykle vyžaduje určité vazby nebo nastavení vlastností, aby správně fungoval v šabloně ovládacího prvku. Ovládací prvek pomocné rutiny a ovládací prvek šablony by měly co nejvíce navázat tato nastavení. Při nastavování vlastností nebo vytváření vazeb je třeba dbát na to, aby uživatel nepřepsala hodnoty nastavené uživatelem. Konkrétní osvědčené postupy jsou následující:

    • Pojmenované pomocné prvky by měly být identifikovány nadřazeným prvkem a nadřazený objekt by měl navázat všechna požadovaná nastavení v pomocném prvku.

    • Pomocné prvky založené na typu by měly přímo na sobě navazovat požadovaná nastavení. To může vyžadovat pomocný prvek k dotazování na kontext informací, ve kterém se používá, včetně jeho TemplatedParent (typ ovládacího prvku šablony, ve které se používá). Například ContentPresenter automaticky sváže Content vlastnost jeho TemplatedParent s jeho Content vlastností při použití v odvozeného ContentControl typu.

    • Samostatné pomocné elementy nelze tímto způsobem optimalizovat, protože podle definice ani pomocný prvek ani nadřazený prvek o druhém neví.

  • Vlastnost Name slouží k označení prvků v rámci šablony. Ovládací prvek, který potřebuje najít prvek ve svém stylu, aby k němu měl přístup prostřednictvím kódu programu, by to měl provést pomocí Name vlastnosti a FindName paradigmatu. Ovládací prvek by neměl vyvolat výjimku, pokud prvek nebyl nalezen, ale bezobslužně a elegantně zakázat funkce, které tento prvek vyžadovaly.

  • Použijte osvědčené postupy pro vyjádření stavu řízení a chování ve stylu. Následuje seřazený seznam osvědčených postupů pro vyjádření změn stavu řízení a chování ve stylu. Měli byste použít první položku v seznamu, která umožňuje váš scénář.

    1. Vazba vlastností. Příklad: vazba mezi ComboBox.IsDropDownOpen a ToggleButton.IsChecked.

    2. Aktivované změny vlastností nebo animace vlastností Příklad: stav Buttonpřechodu na .

    3. Příkaz. Příklad: LineUpCommand / LineDownCommand in ScrollBar.

    4. Samostatné pomocné prvky. Příklad: TabPanel in TabControl.

    5. Pomocné typy založené na typech Příklad: ContentPresenter in Button, TickBar in Slider.

    6. Pojmenované pomocné prvky Příklad: TextBox in ComboBox.

    7. Bublinové události z pojmenovaných pomocných typů Pokud nasloucháte bublinovým událostem z elementu stylu, měli byste vyžadovat, aby byl prvek generující událost jednoznačně identifikován. Příklad: Thumb in ToolBar.

    8. Vlastní OnRender chování. Příklad: ButtonChrome in Button.

  • Používejte triggery stylu (na rozdíl od triggerů šablon) střídmě. Triggery, které ovlivňují vlastnosti prvků v šabloně, musí být deklarovány v šabloně. Triggery, které ovlivňují vlastnosti ovládacího prvku (ne TargetName), mohou být deklarovány ve stylu, pokud nevíte, že změna šablony by měla také zničit trigger.

  • Být konzistentní s existujícími vzory stylů. Často existuje několik způsobů, jak problém vyřešit. Mějte na paměti a pokud je to možné, konzistentně s existujícími vzory stylů ovládacích prvků. To je zvlášť důležité pro ovládací prvky, které jsou odvozeny ze stejného základního typu (například ContentControl, ItemsControl, RangeBaseatd.).

  • Zveřejnění vlastností pro povolení běžných scénářů přizpůsobení bez opakování WPF nepodporuje připojitelné/přizpůsobitelné části, takže uživatel ovládacího prvku zůstává pouze se dvěma metodami přizpůsobení: nastavení vlastností přímo nebo nastavení vlastností pomocí stylů. S ohledem na to je vhodné vytvořit omezený počet vlastností cílených na velmi běžné scénáře přizpůsobení s vysokou prioritou, které by jinak vyžadovaly opakování. Tady jsou osvědčené postupy pro případy, kdy a jak povolit scénáře přizpůsobení:

    • Velmi běžná přizpůsobení by měla být vystavena jako vlastnosti ovládacího prvku a spotřebované šablonou.

    • Méně časté (i když ne vzácné) přizpůsobení by mělo být vystaveno jako připojené vlastnosti a spotřebované šablonou.

    • Je přijatelné pro známé, ale vzácné přizpůsobení, aby vyžadovalo opakování.

Důležité informace o motivu

  • Styly motivů by se měly pokoušet mít konzistentní sémantiku vlastností napříč všemi motivy, ale nemají žádnou záruku. V rámci jeho dokumentace by měl mít váš ovládací prvek dokument popisující sémantiku vlastností ovládacího prvku, tedy "význam" vlastnosti ovládacího prvku. ComboBox Například ovládací prvek by měl definovat význam Background vlastnosti v rámci ComboBox. Výchozí styly ovládacího prvku by se měly pokusit dodržovat sémantiku definovanou v dokumentu napříč všemi motivy. Na druhou stranu by měli být vědomi toho, že se sémantika vlastností může změnit z motivu na motiv. V některých případech nemusí být daná vlastnost v rámci vizuálních omezení vyžadovaných konkrétním motivem vyjádřitelná. (Například klasický motiv nemá jednoduché ohraničení, na které Thickness lze použít mnoho ovládacích prvků.)

  • Styly motivů nemusí mít konzistentní sémantiku triggerů napříč všemi motivy. Chování vystavené stylem ovládacího prvku prostřednictvím triggerů nebo animací se může lišit od motivu po motiv. Uživatelé ovládacích prvků by měli vědět, že ovládací prvek nemusí nutně používat stejný mechanismus k dosažení určitého chování napříč všemi motivy. Jeden motiv může například použít animaci k vyjádření chování při najetí myší, kde jiný motiv používá trigger. To může vést k nekonzistence v zachování chování na přizpůsobených ovládacích prvcích. (Změna vlastnosti pozadí, například nemusí mít vliv na stav najetí ovládacího prvku, pokud je tento stav vyjádřen pomocí triggeru. Pokud se ale stav přechodu myší implementuje pomocí animace, změna na pozadí by mohla nenávratně přerušit animaci, a proto přechod stavu.)

  • Styly motivů nemusí mít konzistentní sémantiku rozložení napříč všemi motivy. Výchozí styl například nemusí zaručit, že ovládací prvek bude zabírat stejnou velikost ve všech motivech nebo zaručit, že ovládací prvek bude mít stejné okraje obsahu / odsazení napříč všemi motivy.

Viz také