poniedziałek, 7 maja 2012

70-511 Rozdział 1 - Tworzenie interfejsu użytwkownika - Style i triggery

W tej części zostaną omówione style oraz triggery.

Style
Style w WPF są podobne do stylów w HTML - CSS. Definiując style, łatwiej wpływać na wygląd całej aplikacji. Klasa Style posiada następujące właściwości:
  • BasedOn - pozwala na "dziedziczenie" z innego stylu
  • Resources - kolekcja lokalnych zasobów dla stylu
  • Setters - kolekcja Setterów dla właściwości bądź zdarzeń
  • TargetType - typ elementu który ma przyjąć styl
  • Triggers - kolekcja triggerów, pozwalająca na zaprojektowanie zmian w interfejsie użytkownika w przypadku zmiany wartości którejś z właściwości

Settery
Można je podzielić na dwie kategorie:
  • settery dla właściwości - ustawiają wartości właściwości
  • settery dla zdarzeń - ustawiają uchwyty dla zdarzeń
Dwie ważne właściwości:
  • Property - określa która właściwość ma być ustawiona
  • Value - wartość, którą ma przyjąć właściwość
Setter ma następującą składnię:


Code:
<Setter Property="Element.PropertyName" Value="Red" />

Przykład:


Code:
<Style>
<Setter Property="Control.Background" Value="Red" />
</Style>



EventSetter
Podobnie jak setter dla właściwości, posiada dwie ważne właściwości:
  • Event - typ zdarzenia któemu chcemy nadać wartość
  • Handler - uchwyt
Właściwość Event ma następującą składnię: Element.EventName


Code:
<EventSetter Event="Button.MouseEnter" Handler="Button_MouseEnter" />


Style można przypisywać bezpośrednio do kontrolki:


Code:
<Button Height="25" Name="Button1" Width="100">
<Button.Style>
<Style>
<Setter Property="Button.Content" Value="Style set directly" />
<Setter Property="Button.Background" Value="Red" />
</Style>
</Button.Style>
</Button>

bądź pisać je jako zasoby:


Code:
<Window.Resources>
<Style x:Key="StyleOne">
<Setter Property="Button.Content" Value="Style defined in resources" />
<Setter Property="Button.Background" Value="Red" />
</Style>
</Window.Resources>

Przypisanie stylu do przycisku:


Code:
<Button Name="Button1" Style="{StaticResource StyleOne}" Height="30" Width="200" />

Styl można przypisać do wszystkich kontrolek danego typu ustawiając właściwość TargetType:


Code:
<Window.Resources>
<Style TargetType="Button">
<Setter Property=" Content" Value="Style set for all buttons" />
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>

Taki zabieg dodatkowo spowoduje że nie trzeba używać pełnego kwalifikatora dla właściwości której przypisujemy wartość


Ustawianie stylów z poziomu kodu:
Style dużo łatwiej definiuje się w XAML, jednak czasami zachodzi konieczność dynamicznego ich tworzenia np. w wypadku aplikacji w której użytkownik chce sam ustalić wygląd aplikacji. Przykładowy kod:


Code:
Style aStyle = new Style();
Setter aSetter = new Setter();
aSetter.Property = Button.BackgroundProperty;
aSetter.Value = Brushes.Red;
aStyle.Setters.Add(aSetter);
Setter bSetter = new Setter();
bSetter.Property = Button.ContentProperty;
bSetter.Value = "Style set programmatically";
aStyle.Setters.Add(bSetter);
Button1.Style = aStyle;

Można także zdefiniować styl w XAML i dynamicznie go przypisać do kontrolki:


Code:
<Window.Resources>
<Style x:Key="StyleOne">
<Setter Property="Button.Content" Value="Style applied in code" />
<Setter Property="Button.Background" Value="Red" />
</Style>
</Window.Resources>


Style aStyle;
aStyle = (Style)this.Resources["StyleOne"];
Button1.Style = aStyle;


Dziedziczenie stylów:
Jeżeli mamy zdefiniowany jeden styl dla przycisków, a chcemy aby na formatce jeden z nich się odróżniał, możemy dziedziczyć styl i np. zmienić tylko dla niego kolor np.




Triggery
Triggery pozwalają na zmianę wartości kontrolek w reakcji na zmianę innej wartości. Wyróżniamy 5 rodzai triggerów:
  • Property trigger (Trigger) - w momencie gdy wartość właściwości przyjmuje wartość Value zostaje aktywowany
  • Multi-trigger (MultiTrigger) - sprawdza na raz kilka wartości; zostaje aktywowany w momencie kiedy wszystkie są zgodne z wartością Value
  • Data trigger (DataTrigger) - sprawdza zbindowane pola, aktywuje się gdy wartość pola ma wartość równą polu Value
  • Multi-data trigger (MultDataTrigger) - to samo co wyżej tylko że dla kilku pól
  • Event trigger (EventTrigger) - wykonuje akcje w momencie gdy dane zdarzenie ma miejsce
Trigery inne niż EventTrigger mogą być definiowane tylko w kodzie stylu, w innym przypadku dostaniemy błąd w czasie wykonania.


Property Triggers
Najczęściej wykorzystywany rodzaj triggerów. Ważne właściwości tego rodzaju triggerów:
  • EnterActions - kolekcja obiektów typu Akcja. Akcje są wykonane w momencie, gdy trigger zostaje aktywowany
  • ExitActions - kolekcja akcji, które są wykonywane w momencie gdy trigger przestaje być aktywny
  • Property - właściwość, która ma być monitorowana
  • Setters - kolekcja setterów, które są aplikowane w momencie gdy trigger się aktywuje
  • Value - wartość do porównania z właściwością Property
Prosty przykład zmiany czcionki, gdy myszką najedziemy na przycisk:


Code:
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>


Multi-triggers
Sprawdzanych jest kilka właściwości jednocześnie. W momencie gdy wszystkie warunki zajdą, nadawana jest odpowiednia wartość wyspecyfikowanym właściwością. Przykład:


Code:
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Button.IsMouseOver" Value="True" />
<Condition Property="Button.IsFocused" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Button.FontWeight" Value="Bold" />
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>

W tym przypadku kolor czcionki przycisku zostanie pogrubiony kiedy myszka znajduje się nad przyciskiem i jest ustawiony na nim focus.


Data Triggers i Multi-data Triggers
Są bardzo podobne do Triggerów, z tym że sprawdzają zmiany w polach które są bindowane. Przykład:


Code:
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CustomerName}" Value="Fabrikam">
<Setter Property="Label.Background" Value="Red" />
</DataTrigger>
</Style.Triggers>

Multi-data triggers są podobne do Multi-triggers, tak samo posiadają kolekcję warunków oraz setterów, jednak nasłuchują pól zbindowanych:


Code:
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=CustomerName}" Value="Fabrikam" />
<Condition Binding="{Binding Path=OrderSize}" Value="500" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Label.Background" Value="Red" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>



Event Triggers
Są wywoływanie w momencie, gdy wyspecyfikowane zdarzenie ma miejsce. Wykorzystywane są przede wszystkim w przypadku animacji. Dwa proste przykłady:

Code:
<EventTrigger RoutedEvent="Button.Click">
<SoundPlayerAction Source="C:\myFile.wav" />
</EventTrigger>

W momencie naciśnięcia przycisku zostanie odtworzony utwór. Drugi przykład:


Code:
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:5"
Storyboard.TargetProperty="Height" To="200" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>

W momencie gdy przycisk zostanie kliknięty, jego wysokość zostanie zwiększona do 200 jednostek.


Kolejność w jakiej jest ustalana wartość właściwości. Najniższy numer oznacza najwyższy priorytet:
  1. Ustawienie przez system coerci.
  2. Ustawione przez animacje
  3. W kodzie C#, XAML, bądź bindowanie
  4. Szablon
  5. Niejawny styl
  6. Triggery Stylu
  7. Triggery Szablonu
  8. Domyślny styl
  9. Dziedziczenie
  10. Metadata

Brak komentarzy:

Prześlij komentarz