November Black Friday C/C++ week
Black Friday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Pouze tento týden sleva až 80 % na e-learning týkající se C/C++

2. Díl WPF - Příběhy

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulém dílu jsme si vysvětlili jak dynamicky přidávat a odebírat elementy za běhu programu, dnes se vrhneme na příběhy. V příbězích se dají vytvářet jednoduché i složitější animace. Já začnu jednoduchou průhlednostní animací, která nám bude měnit průhlednost tlačítka při najetí myši.

Vytvořím si na to nový projekt, jméno není důležité. Ještě bych dodal, že pro příběhy použiji CustomControl, protože je to pro začátek jednodušší než vytvářet potomka elementu.

Do projektu si tedy přidáme Nový -> UserControl a pro příklad si jej pojmenujeme UserButton. Vytvořil se nám objekt který vzdáleně připomíná prázdné okno. Tomuto objektu můžeme přiřadit jen jeden element, stejně jako u okna. Pokud chceme přidat do objektu více elementů, využijeme k tomu Grid. Visual Studio s tím tak nějak počítá, že nám jeden element stačit nebude, a tak nám objekt vygeneruje i s Gridem.

Příběhy přes XAML

Příběhy nebo chcete-li storyboardy jdou vytvářet hned dvěma různými způsoby. Nyní si probereme první způsob a to je způsob vytváření přes XAML kód.

Již máme vytvořený UserButton, přidáme si do gridu ještě přidáme nějakou barvu, aby bylo vidět, zda animace funguje nebo ne. Já v tomto příkladu použiji modrou barvu. Takže si do kódu gridu přidáme Background asi takto:

<Grid Background="Blue" Name="basicGrid">

Vytvoření příběhu

Začneme s vytvářením příběhu. Jako první si rozmyslíme kdy se bude spouštět a podle toho si vybereme příslušný Event. Pro začátek budeme měnit průhlednost při najetí myši, takže budeme potřebovat hned dva eventy a to: MouseEnter a MouseLeave, Ke zjišťování těchto eventů přímo v XAML kódu slouží Triggers. Ty dokáží zjišťovat buď nějakou vlastnost nebo zmíněný event.

<Grid Background="Blue" Name="basicGrid">
    <Grid.Triggers></Grid.Triggers>
</Grid>

Takto vypadá předloha pro naše Triggery. Jako první si do Grid.Triggers přidáme EventTrigger, který nám bude zajišťovat event, který mu ale sdělíme přes vlastnost RoutedEvent, asi takto:

<EventTrigger RoutedEvent="MouseEnter"></EventTrigger>
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Vnitřek tohoto triggeru se bude spouštět pouze při najetí myši nad grid. Do tohoto EventTriggeru si ovšem nemůžeme rovnou přidat příběh, nejdříve musíme programu nějak sdělit, že má příběh začít, takže si ještě do EventTriggeru přidáme

<BeginStoryboard></BeginStoryboard>

Animace

Teď si můžeme napsat příběh s animací nebo i více animacemi současně. Zatím využiji pouze jednu animaci a tou bude DoubleAnimation. Ta nám dokáže plynule měnit Double hodnotu jakou ji zadáme. Ve WPF se již totiž téměř nepoužívají integery, ale ve většině případů je zde double (velikost okna, pozice prvků, vlastnosti prvků, které obsahují číselnou hodnotu, ...).

Budeme si vytvářet animaci, která potrvá jednu vteřinu. K tomu nám slouží vlastnost duration, která se zadává ve formátu hh:mm:ss. Také ji nastavíme do jaké hodnoty se má animavoat. Na to máme vlastnost To a budeme ji chtít při najetí myši na 1. Poslední, co nám zbývá nastavit, je cíl. Animace totiž sama nepozná, že má animovat vlastnost Opacity v prvku basicGrid. To uděláme přes Storyboard.Tar­getName a Storyboard.Tar­getProperty. Tím bychom měli všechny důležité vlastnosti animace i příběhu nastaveny.

Nyní se celý EventTrigger zkopírujeme a vložíme pod něj. Změníme RoutedEvent na MouseLeave a u DoubleAnimation změníme To na 0.5. Tím si zajistíme, že při odsunutí myši z prvku se nám bude snižovat Opacity až na polovinu. Celý Grid.Triggers bude tedy vypadat takto:

<!-- Najetí myši -->
<EventTrigger RoutedEvent="MouseEnter">
    <BeginStoryboard>
        <Storyboard>
            <DoubleAnimation Duration="00:00:01" To="1"
Storyboard.TargetName="basicGrid" Storyboard.TargetProperty="Opacity" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

<!-- Odjetí myši -->
<EventTrigger RoutedEvent="MouseLeave">
    <BeginStoryboard>
        <Storyboard>
            <DoubleAnimation Duration="00:00:01" To="0.5"
Storyboard.TargetName="basicGrid" Storyboard.TargetProperty="Opacity" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

Před vyzkoušením budeme muset udělat ještě jednu věc, jelikož vlastní prvek ještě nenalezneme v ToolBoxu. Jedna možnost je zkompilovat program, ale já dávám přednost nejdříve ho tam vložit a poté až kompilovat. Nebudeme totiž muset kompilovat dvakrát, abychom se podívali, zda naše "tlačítko" funguje.

Přidání UserControl

Přepneme se do XAML kódu hlavního okna aplikace a do tagu Window si přidáme odkaz na celý náš projekt tím, že přímo do tagu přidáme řádek:

xmlns:my="clr-namespace:_2_Ep_WPF_Storyboards"

Tím získáme odkaz 'my', který použijeme do gridu v hlavním okně tak, že si tam přidáme řádek:

<my:UserButton VerticalAlignment="Top" HorizontalAlignment="Left" Width="300" Height="300" Margin="12,12,0,0" />

Zatím se nemůžeme podívat jak bude náš element v designeru vypadat, protože Visual Studio zatím nezná odkaz 'my'. To se dá jednoduše vyřešit kompilací projektu, pokud jste někde neudělali chybu, tak výsledkem bude form se čtverečkem, který mění průhlednost při najetí myši.

Příběhy přes C# kód

Druhým způsobem přidání příběhu je přes C# kód. Příběhy v kódu na pozadí elementu již budou mít trochu jiný styl než v XAML. Jako první si přidáme jméno Gridu, třeba basicGrid, a hned potom si přidáme do kódu eventy tím, že na ně ve vlastnostech gridu dvakrát klikneme:

V metodě MouseEnter si vytvoříme novou DoubleAnimaci (budeme potřebovat nový using) a rovnou ji nastavíme To a Duration:

DoubleAnimation opacityAnimation = new DoubleAnimation { To = 1, Duration = TimeSpan.FromSeconds(1) };

Nyní nám zbývá animaci nastavit na Opacity gridu a spustit ji. To uděláme ve druhém řádku:

basicGrid.BeginAnimation(Grid.OpacityProperty, opacityAnimation);

První argument v metodě basicGrid.Begi­nAnimation nám říká jakou vlastnost budeme animovat a druhý argument co tuto vlastnost bude animovat. Tyto dva řádky si rozkopírujeme i do metody MouseLeave, akorát upravíme To u DoubleAnimation na 0.5. Ještě si do basicGridu přidáme pozadí, tentokrát červené, aby se čtverce dali snadno rozlišit. Ještě přejdeme do XAML kódu hlavního okna a přidáme si nový řádek s druhým elementem

<my:UserButton2 VerticalAlignment="Top" HorizontalAlignment="Left" Width="300" Height="300" Margin="318,12,0,0" />

Tímto by jsme měli probrané základy animací, opět pokud něčemu nerozumíte, tak buď napište do komentářů nebo se podívejte do zdrojových kódů, které jsou přiložené pod článkem.

Výsledná aplikace vypadá následovně:


 

Stáhnout

Staženo 398x (73.15 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

 

Aktivity (1)

 

 

Komentáře
Zobrazit starší komentáře (20)

Avatar
Kit
Redaktor
Avatar
Kit:2.1.2014 2:58

Prefixy jako takové neodsuzuji. Měl jsem výhradu jen k tomu, že tlačítko se jmenuje Button, a uživatel se jmenuje User. Neznám žádného člověka, který by se jmenoval Člověk a měl psa, který se jmenuje Pes.

Možná by se mohlo jmenovat "ucUserNew", pokud by kliknutí mělo znamenat založení nového uživatele nebo "ucAccountDelete", pokud by mělo být ke zrušení účtu.

Odpovědět
2.1.2014 2:58
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Neaktivní uživatel:2.1.2014 21:50

chlapi koukal jsem do xaml kodu toho usercontrolu a zjistil jsem že ani jedna z xmlns adres NEFUNGUJE ?! =proboha proč ?

xmlns="http:/­/schemas.micro­soft.com/winfx/2006/xam­l/presentation"
xmlns:x="http­://schemas.mi­crosoft.com/win­fx/2006/xaml"
xmlns:mc="htt­p://schemas.o­penxmlformats­.org/markup-compatibility/2006"
xmlns:d="http­://schemas.mi­crosoft.com/ex­pression/blen­d/2008"

Editováno 2.1.2014 21:53
Odpovědět
2.1.2014 21:50
Neaktivní uživatelský účet
Avatar
Kit
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
Kit:2.1.2014 21:53

A měly by fungovat? Podle specifikace nemusí.

Odpovědět
2.1.2014 21:53
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Neaktivní uživatel:2.1.2014 21:54

a k čemu tam potom jsou ? je to tedy jenom jakýsi pojmenovaný identifikátor ? nebo jak to chapat ?

Odpovědět
2.1.2014 21:54
Neaktivní uživatelský účet
Avatar
Kit
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
Kit:2.1.2014 22:06

Ano, je to jen unikátní identifikátor, podle kterého si parser XML udělá názvový prostor. Obvykle se na ty adresy dávají stránky s popisem jazyka, ale nikde není psáno, že tam být musí.

Odpovědět
2.1.2014 22:06
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Petr Čech
Redaktor
Avatar
Petr Čech:28.1.2014 17:33

Název příběh je poněkud zavádějící.

Odpovědět
28.1.2014 17:33
the cake is a lie
Avatar
1254
Člen
Avatar
1254:27.7.2014 11:19

Ahoj, chcem sa spýtať čo znamená to "d" pri hodnote To = 0.5d
v zdrojáku UserButton2.xaml.cs
Je to tam potrebné?
Ďakujem.

 
Odpovědět
27.7.2014 11:19
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na 1254
Jan Vargovský:27.7.2014 16:02

Říkáš tomu, že je to typ double. Jestli je to potřebné si můžeš zkusit sám.

 
Odpovědět
27.7.2014 16:02
Avatar
redyder
Člen
Avatar
redyder:18. ledna 12:03

Vytvořím si na to nový projekt, jméno není důležité.

Přepneme se do XAML kódu hlavního okna aplikace a do tagu Window si přidáme odkaz na celý náš projekt tím, že přímo do tagu přidáme řádek:
xmlns:my="clr-namespace:_2_Ep_WPF­_Storyboards"

Když si projekt pojmenuju "MůjNázev" musím vložit
xmlns:my="clr-namespace:Můj­Název"

 
Odpovědět
18. ledna 12:03
Avatar
Theodor Johnson
Redaktor
Avatar
Odpovídá na redyder
Theodor Johnson:29. května 16:56

Díky za upozornění, tutoriály jsem psal již dost dávno, když jsem ještě s WPF začínal, dělal jsem to stylem že jsem si našel anglický tutoriál (protože českých byl nedostatek) a byl jsem vždy o lekci napřed před tutoriálem co jsem psal sem. Pro aktuálnější tutoriály doporučuji od David Čápka který začal psát vlastní poté co mi na další díly nezbývalo moc času a nepokračoval jsem v nich.

Odpovědět
29. května 16:56
Mo8ilε 15 Ѐλđ
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 30. Zobrazit vše