Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Pomocí windows Presentation Foundation (WPF) můžete přizpůsobit vizuální strukturu a chování existujícího ovládacího prvku pomocí vlastní opakovaně použitelné šablony. Šablony se dají použít globálně na vaši aplikaci, okna a stránky nebo přímo na ovládací prvky. Většina scénářů, které vyžadují, abyste vytvořili nový ovládací prvek, je možné pokrýt vytvořením nové šablony pro existující ovládací prvek.
V tomto článku se naučíte, jak vytvořit nový ControlTemplate pro ovládací prvek Button.
Kdy vytvořit ControlTemplate
Ovládací prvky mají mnoho vlastností, například Background, Foregrounda FontFamily. Tyto vlastnosti řídí různé aspekty vzhledu ovládacího prvku, ale změny, které můžete provést nastavením těchto vlastností, jsou omezené. Můžete například nastavit vlastnost Foreground na modrou barvu a FontStyle na kurzívu u CheckBox. Pokud chcete přizpůsobit vzhled ovládacího prvku nad rámec toho, co nastavení ostatních vlastností ovládacího prvku může udělat, vytvoříte .ControlTemplate
Ve většině uživatelských rozhraní má tlačítko stejný obecný vzhled: obdélník s textem. Pokud chcete vytvořit zaokrouhlené tlačítko, můžete vytvořit nový ovládací prvek, který dědí z tlačítka nebo znovu vytvoří funkce tlačítka. Nový uživatelský ovládací prvek navíc poskytuje kruhový vizuál.
Vytváření nových ovládacích prvků můžete zabránit přizpůsobením rozložení vizuálu existujícího ovládacího prvku. K zaoblenému tlačítku vytvořte ControlTemplate s požadovaným vizuálním rozložením.
Na druhou stranu, pokud potřebujete ovládací prvek s novými funkcemi, různými vlastnostmi a novými nastaveními, vytvoříte nový UserControl.
Požadavky
Vytvořte novou aplikaci WPF. V MainWindow.xaml (nebo jiném okně podle vašeho výběru) nastavte následující vlastnosti elementu <Window> :
| Vlastnictví | Hodnota |
|---|---|
| Title | Template Intro Sample |
| SizeToContent | WidthAndHeight |
| MinWidth | 250 |
Nastavte obsah elementu <Window> na následující XAML:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Na konci by měl soubor MainWindow.xaml vypadat podobně jako následující XAML:
<Window x:Class="IntroToStylingAndTemplating.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IntroToStylingAndTemplating"
mc:Ignorable="d"
Title="Template Intro Sample" SizeToContent="WidthAndHeight" MinWidth="250">
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
</Window>
Pokud aplikaci spustíte, vypadá to jako na následujícím obrázku:
Vytvořte ControlTemplate
Nejběžnějším způsobem, jak deklarovat ControlTemplate, je jako prostředek v oddílu Resources v souboru XAML. Vzhledem k tomu, že šablony jsou prostředky, dodržují stejná pravidla rozsahu jako všechny prostředky. Když deklarujete šablonu, bude mít vliv na to, kde ji můžete použít. Pokud například deklarujete šablonu v kořenovém prvku souboru XAML definice aplikace, můžete šablonu použít kdekoli ve své aplikaci. Pokud šablonu definujete v okně, můžou šablonu používat jenom ovládací prvky v daném okně.
Začněte tak, že do souboru Window.Resources přidáte element:
<Window x:Class="IntroToStylingAndTemplating.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IntroToStylingAndTemplating"
mc:Ignorable="d"
Title="Template Intro Sample" SizeToContent="WidthAndHeight" MinWidth="250">
<Window.Resources>
</Window.Resources>
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
</Window>
Vytvořte novou <controlTemplate> a nastavte následující vlastnosti:
| Vlastnictví | Hodnota |
|---|---|
| x:Key | roundbutton |
| TargetType | Button |
Tato šablona ovládacího prvku je jednoduchá:
- kořenový prvek pro ovládací prvek, a Grid
- a Ellipse nakreslit zaokrouhlený vzhled tlačítka
- zobrazení ContentPresenter obsahu tlačítka zadaného uživatelem
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
TemplateBinding
Při vytváření nového ControlTemplateobjektu může být stále vhodné použít veřejné vlastnosti ke změně vzhledu ovládacího prvku. Rozšíření zápisu TemplateBinding sváže vlastnost elementu, který je v ovládacím prvku, s veřejnou vlastností, kterou tento ovládací prvek definuje. Při použití TemplateBinding povolíte vlastnosti ovládacího prvku, aby fungovaly jako parametry šablony. Když nastavíte vlastnost ovládacího prvku, hodnota předá elementu, který má TemplateBinding.
Elipsa
Vlastnosti Fill a Stroke elementu <Ellipse> jsou svázány s vlastnostmi Foreground a ovládacího prvkuBackground.
Prezentér obsahu
Šablona také obsahuje <contentPresenter> element. Vzhledem k tomu, že tato šablona je určena pro tlačítko, nezapomeňte, že tlačítko dědí z ContentControl. Tlačítko zobrazí obsah prvku. V tlačítku můžete nastavit cokoli, například prostý text nebo dokonce jiný ovládací prvek. Obě následující příklady jsou platná tlačítka:
<Button>My Text</Button>
<!-- and -->
<Button>
<CheckBox>Checkbox in a button</CheckBox>
</Button>
V obou předchozích příkladech je text a zaškrtávací políčko nastaveny jako Button.Content vlastnost. To, co je nastavené jako obsah, se dá prezentovat prostřednictvím <ContentPresenteru>, což je to, co šablona dělá.
Pokud použijete ControlTemplate na typ ContentControl, například Button, šablona hledá ContentPresenter ve stromu elementů. Pokud najde ContentPresenter, šablona automaticky propojí vlastnost ovládacího prvku Content na hodnotu ContentPresenter.
Použít šablonu
Najděte tlačítka, která jste deklarovali na začátku tohoto článku.
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Nastavte vlastnost druhého tlačítka Template na roundbutton zdroj:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}">Button 2</Button>
</StackPanel>
Pokud projekt spustíte a podíváte se na výsledek, uvidíte, že tlačítko má zaokrouhlené pozadí.
Možná si všimnete, že tlačítko není kruh, ale je zkosené. Vzhledem ke způsobu, jakým <funguje prvek Ellipse> , se vždy rozšiřuje, aby vyplnil dostupné místo. Změňte hodnotu tlačítka width a height vlastností na stejnou hodnotu, aby byl kruh jednotný:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}" Width="65" Height="65">Button 2</Button>
</StackPanel>
Přidejte spouštěč
I když tlačítko s použitou šablonou vypadá jinak, chová se stejně jako jakékoli jiné tlačítko. Pokud stisknete tlačítko, se událost Click aktivuje. Můžete si ale všimnout, že když na tlačítko přesunete myš, vizuály tlačítka se nezmění. Šablona definuje tyto vizuální interakce.
Pomocí dynamických systémů událostí a vlastností, které WPF poskytuje, můžete sledovat konkrétní vlastnost pro hodnotu a pak šablonu podle potřeby změnit. V tomto příkladu se díváte na vlastnost tlačítka IsMouseOver . Když je myš nad ovládacím prvkem, nastylizujte <Elipsa> s novou barvou. Tento typ triggeru se označuje jako PropertyTrigger.
Aby tato funkce fungovala, musíte přidat název do <elipsy> , na kterou můžete odkazovat. Pojmenujte ho backgroundElement.
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
Dále přidejte nový Trigger do kolekce ControlTemplate.Triggers. Trigger sleduje událost IsMouseOver na hodnotu true.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Dále přidejte <Setter> do <Trigger>, který změní vlastnost Výplň objektu <Ellipse> na novou barvu.
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="backgroundElement" Value="AliceBlue"/>
</Trigger>
Spusťte projekt. Když na tlačítko přesunete myš, změní se barva elipsy<>.
Použijte VisualState
Vizuální stavy jsou definovány a aktivovány ovládacím prvkem. Například když přesunete myš nad ovládací prvek, ovládací prvek aktivuje CommonStates.MouseOver stav. Změny vlastností můžete animovat na základě aktuálního stavu ovládacího prvku. V předchozí části jste použili <PropertyTrigger> ke změně pozadí tlačítka na AliceBlue, když byla vlastnost IsMouseOvertrue. Místo toho vytvořte vizuální stav, který animuje změnu této barvy a poskytuje hladký přechod. Další informace o VisualStates naleznete v tématu Styly a šablony WPF.
Pokud chcete převést <PropertyTrigger> do animovaného vizuálního stavu, odeberte <z šablony element ControlTemplate.Triggers> .
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Dále v kořeni <mřížky> šablony pro ovládací prvek přidejte <prvek VisualStateManager.VisualStateGroups> s <VisualStateGroup> pro CommonStates. Definujte dva stavy Normal a MouseOver.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
</VisualState>
<VisualState Name="MouseOver">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Při aktivaci tohoto stavu použijte všechny animace, které definujete ve <VisualState> . Vytváření animací pro každý stav Vložte animace do elementu <Storyboard> . Další informace o scénářích najdete v tématu Přehled scénářů.
Normální
Tento stav animuje výplň elipsy a obnoví ho na barvu ovládacího prvku
Background.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{TemplateBinding Background}" Duration="0:0:0.3"/> </Storyboard>Přejeďte myší
Tento stav animuje barvu elipsy
Backgroundna novou barvu:Yellow.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.3"/> </Storyboard>
ControlTemplate<> by teď měl vypadat jako následující kód.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<Storyboard>
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{TemplateBinding Background}"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Spusťte projekt. Když na tlačítko přesunete myš, barva <elipsy> se animuje.
Další kroky
.NET Desktop feedback