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

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

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>

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 336x (73.15 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Theodor Johnson
Avatar
Autor má většinou na svědomí projekty v jazyce C#.

Jak se ti líbí článek?
Celkem (3 hlasů) :
4.666674.666674.666674.666674.66667


 


Miniatura
Všechny články v sekci
Okenní aplikace v C# .NET WPF
Miniatura
Následující článek
3. Díl WPF - Pozadí elementů

 

 

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

Avatar
Jan Vargovský
Redaktor
Avatar
Jan Vargovský:

To všem. Kit nedělá v C#, takže to hodnotí tak, aby jen vyvolal diskuzi...

 
Odpovědět  -3 2.1.2014 2:19
Avatar
Kit
Redaktor
Avatar
Odpovídá na Jan Vargovský
Kit:

Jan Vargovský mi zase slíbil, že se naučí číst.

Odpovědět 2.1.2014 2:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Kit:

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:

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:

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:

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:

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  ±0 2.1.2014 22:06
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Petr Čech (czubehead):

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

Odpovědět 28.1.2014 17:33
Why so serious? -Joker
Avatar
1254
Člen
Avatar
1254:

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ý:

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

 
Odpovědět  ±0 27.7.2014 16:02
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 28. Zobrazit vše