13.12.18 vjj 1 events, triggers.net
13.12.18 vjj 4 Triggers Umožňují definovat reakci na vzniklou situaci Event Trigger invoked when a RoutedEvent is raised " <EventTrigger " Property Trigger invoked when the value of a dependency property changes " <Trigger " Data Trigger invoked when the value of a plain.net property changes
Event Triggers 13.12.18 vjj 5
13.12.18 vjj 6 zprávy ve frontě Win32 API můj program GetMessage DispatchMessage -> WndClass.WndProc WndProc (id instance okna, msg) switch case
Win32 API okno okno okno okno Win32 API program case case case case case WinProc WinProc WinProc DispatchMessage GetMessage fronta WM_ zpráv 13.12.2018 vjj 7
13.12.18 vjj 8 zprávy ve frontě objektové nadstavby runtime (Win32 aplikace) GetMessage DispatchMessage -> WndClass.WndProc WndProc (id instance okna, msg) switch case můj program event handler (pro který objekt?)
objektový program okno okno okno okno moje objekty event handler event handler event handler event handler Win32 API stub case case case case case WinProc WinProc WinProc DispatchMessage GetMessage fronta WM_ zpráv 13.12.2018 vjj 9
13.12.2018 vjj 10 přesměrování jak zpracovat zprávu/událost jinde? standardní ovládací prvky implementované ve standardní knihovně reakci chci mít spojenou s oknem, ve kterém jsou ovládací prvky umístěny runtime -> event handler objektu, kterého se událost týká
13.12.18 vjj 11 Win32 API Controls child okna, pokud explicitně neupozorní rodičovské okno, to se o události nic nedozví standardní ovládací prvky > standardní komunikace (posílají zprávy WM_COMMAND nebo WM_NOTIFY rodičovskému oknu)
13.12.2018 vjj 12 standardní objektové nadstavby standardní ovládací prvky pokud neobsahují příslušný event handler pokud obsahují příslušný event handler
.NET WPF program okno okno okno moje objekty event handler event handler event handler Win32 API stub case case case case case WinProc WinProc DispatchMessage GetMessage fronta WM_ zpráv 13.12.2018 vjj 13
13.12.2018 vjj 14.NET pro každou událost volá runtime v pevně daném pořadí handlery této události zaregistrované i u jiných objektů, než je ten, pro který byla událost vyvolána
13.12.2018 vjj 15.NET objekt může mít zaregistrovaný Event handler i pro jiný typ objektu, než je jeho vlastní pro některé události je možné zaregistrovat dokonce dva handlery najednou Type.PreviewEventName Type.EventName
13.12.2018 vjj 16.NET runtime strom objektů + zaregistrované handlery cesta od kořene k objektu, kterého se událost týká všechny event handlery odshora dolu - tunelování jen event handler objektu, kterého se událost týká - direct všechny event handlery odspodu nahoru - probublávání
13.12.18 vjj 21 Routing Strategies DIRECT.NET runtime zavolá Event Handler pouze toho ovládacího prvku, pro který událost nastala Click, MouseEnter TUNNELING.NET runtime postupně volá Preview Event Handler této události pro všechny nadřazené objekty od kořene vizuálního stromu až k objektu, kde událost nastala PreviewMouseDown BUBBLING.NET runtime postupně volá standardní Event Handler této události stejných objektů jako u tunelování, ale v opačném pořadí MouseDown
13.12.2018 vjj 22.NET tunneling - pro standardní systémovou reakci bubbling - pro speciální reakci aplikace v dokumentaci jsou uvedeny handlery a preview handlery nezávisle na sobě, takže pro zjištění, jakou strategii volání handlerů pro událost runtime používá, je nutné zkontrolovat výskyt popisu obou těchto handlerů
13.12.18 vjj 24 Direct Events klasika je volán Event handler pouze pro ovládací prvek, pro který byla událost vyvolána pokud ten nemá pro tuto událost zaregistrován žádný handler, je událost ignorována
13.12.18 vjj 25 Direct Events MouseEnter MouseLeave Click Button CheckBox RadioButton
13.12.2018 vjj 26 problém sample: Button - Grid - TextBox - MouseEnter sample - Direct událost, která není Direct?!
13.12.18 vjj 27 Attached Events Mouse.MouseEnter Mouse.MouseLeave Mouse.MouseLeftButtonDown Mouse.MouseLeftButtonUp Mouse.MouseRightButtonDown Mouse.MouseRightButtonUp Mouse.MouseDoubleClick Mouse.MouseMove Mouse.MouseWheel Click Button CheckBox RadioButton
13.12.18 vjj 28 tunneling PreviewMouseLeftButtonDown PreviewMouseLeftButtonUp PreviewMouseRightButtonDown PreviewMouseRightButtonUp PreviewMouseDoubleClick PreviewMouseMove PreviewMouseWheel PreviewGotKeyboardFocus PreviewLostKeyboardFocus PreviewKeyDown PreviewKeyUp PreviewTextInput bubbling MouseDown GotKeyboardFocus LostKeyboardFocus KeyDown KeyUp TextInput
13.12.18 vjj 29 tunneling preview handlery jsou volány odshora dolů, tj. handler elementu, který událost vyvolal, je volán jako poslední umožňuje umístění společného handleru pro všechny ovládací prvky do kontejneru, který je obsahuje, a upřednostnit tento globální handler před lokálními protože událost může být vyvolána některým z "child" elementů, je vhodné zkontrolovat "Source" v datech události
13.12.18 vjj 30 bubling bublání následuje po skončení tunelování postupně jsou volány všechny handlery od elementu, pro který byla událost vyvolána, až do kořene stromu objektů uživatelského rozhraní protože událost může být vyvolána některým z "child" elementů, je vhodné zkontrolovat "Source" v datech události
13.12.18 vjj 31 GotMouseCapture LostMouseCapture bubling only QueryCursor
13.12.18 vjj 32 event handled posloupnost tunelování a následného bublání lze kdykoliv ukončit private void mycontainerhandler (object sender, RoutedEventArgs e) {... e.handled = true ;... }
13.12.18 vjj 35 XAML + C# <Button Name="btnHello" Content="AAAAA" Click="btnHello_Clicked"> </Button> void btnhello_clicked (object sender, RoutedEventArgs e) { btnhello.content = "BBBBB"; btnhello.background = new SolidColorBrush(Colors.GreenYellow); }
13.12.18 vjj 36 XAML: EventTrigger Event -> code behind <Button MouseEnter="myEventHandler"... /> Event -> XAML EventTrigger -> actions <Button... /> <Button.Triggers> <EventTrigger RoutedEvent="Button.MouseEnter"> Actions
13.12.18 vjj 37 XAML: Actions <Button Content="Click" Height="30" Width="100" Margin="10"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard... />... </EventTrigger.Actions> </EventTrigger> </Button.Triggers> </Button>
13.12.18 vjj 38 triggered actions může být příkaz BeginStoryboard StopStoryboard PauseStoryboard ResumeStoryboard nebo kombinace takových příkazů možné hodnoty parametru Storyboard vnořená definice scénáře animací odkaz na definici scénáře animací jinde, např. v resources odkaz na odstartovaný scénář animací
13.12.18 vjj 39 XAML: BeginStoryboard <Button Content="Click" Height="30" Width="100" Margin="10"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard... /> </EventTrigger> </Button.Triggers> </Button>
13.12.18 vjj 40 XAML: BeginStoryboard <Button Content="Click" Height="30" Width="100" Margin="10"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation To="150" Duration="0:0:2" AutoReverse="True" Storyboard.TargetProperty="(Button.Width)" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button>
Property Triggers 13.12.2018 vjj 41
13.12.18 vjj 42 Property Triggers system watches for dependency property to have a certain value system watches for property trigger to become inactive and reverts property to the previous value Možné reakce jsou Setter - Nastavení hodnoty libovolné vlastnosti EnterActions ExitActions Property Trigger lze psát pouze jako součást definice stylu
13.12.18 vjj 43 Property Trigger <Trigger Property="..." Value="..."> <Setter Property="..." Value="..." /> <Setter Property="..." Value="..." /> <Setter Property="..." Value="..." /> </Trigger>
13.12.18 vjj 44 XAML - IsMouseOver - syntax error <Button Content="hover over" Height="30" Width="200" Margin="10"> <Button.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Button.Triggers> </Button>
13.12.18 vjj 45 Property Trigger in Style <Page.Resources> <Style TargetType="Button">... Control"> <Style.Triggers> <Trigger Property="Button.IsMouseOver" Value="True"> <Setter Property="Button.FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </Page.Resources>
13.12.18 vjj 46 multiple properties <Style TargetType="Button"> <Style.Triggers> <Trigger Property="Button.IsMouseOver" Value="True"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="FontSize" Value="28"/> <Setter Property="Cursor Value="Hand"/> </Trigger> </Style.Triggers> </Style>
13.12.18 vjj 47 multiple triggers <Style TargetType="Button"> <Style.Triggers> <Trigger Property="Button.IsPressed" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> <Trigger Property="Button.IsMouseOver" Value="True"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="FontSize" Value="28pt"/> </Trigger> </Style.Triggers> </Style>
13.12.18 vjj 48 <Style TargetType="Button"> <Style.Triggers> <MultiTrigger> MultiTriggers <MultiTrigger.Conditions> <Condition Property="Button.IsMouseOver" Value="True"/> <Condition Property="Button.Content" Value="HELLO"/> </MultiTrigger.Conditions> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontSize" Value="28pt"/> <Setter Property="FontWeight" Value="Bold"/> </MultiTrigger> </Style.Triggers> </Style>
13.12.18 vjj 49 EventTriggers + PropertyTrigger <Style TargetType="Button"> <Style.Triggers> <EventTrigger RoutedEvent="Button.MouseEnter"> <BeginStoryboard Name="ABCD" > <Storyboard... </EventTrigger> <EventTrigger RoutedEvent="Button.MouseLeave"> <StopStoryboard BeginStoryboardName="ABCD" > </EventTrigger> <Trigger Property="Button.IsMouseOver" Value="True"> <Setter Property="FontWeight" Value="Bold"/> </Trigger> </Style.Triggers> </Style>
13.12.18 vjj 50 Property Trigger w/events <Style TargetType="Button"> <Style.Triggers> <Trigger Property="Button.IsMouseOver" Value="True"> <Setter Property="FontWeight" Value="Bold"/> <Trigger.EnterActions> <BeginStoryboard Name="ABCD"> <Storyboard.... </Trigger.EnterActions> <Trigger.ExitActions> <StopStoryboard BeginStoryboardName="ABCD" /> </Trigger.ExitActions> </Trigger> </Style.Triggers> </Style>
prostředí code behind XAML důvod event změna hodnoty atributu způsob reakce přehled animace změna atributu handler ANO ANO Routed Event Trigger Property Trigger ANO NE EnterActions ANO ExitActions ANO NE animation ANO ANO Setter implicitní návrat k původní hodnotě NE AutoReverse ANO NE AutoReverse ANO ANO 13.12.18 vjj 51
13.12.2018 vjj 52 DataTrigger <TextBox Margin="10" Text="White" FontSize="42"> <TextBox.Style> <Style TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text}" /> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="disabled" > <Setter Property="IsEnabled" Value="False" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox>