Xamarin.Forms Spouště
Triggery umožňují deklarativní vyjádření akcí v xaml, které mění vzhled ovládacích prvků na základě událostí nebo změn vlastností. Kromě toho aktivační události stavu, které jsou specializovanou skupinou triggerů, definují, kdy VisualState
se má použít.
Trigger můžete přiřadit přímo ovládacímu prvku nebo ho přidat do slovníku prostředků na úrovni stránky nebo na úrovni aplikace, který se použije u více ovládacích prvků.
Triggery vlastností
Jednoduchý trigger lze vyjádřit čistě v XAML a přidat Trigger
prvek do kolekce triggerů ovládacího prvku.
Tento příklad ukazuje trigger, který změní Entry
barvu pozadí, když dostane fokus:
<Entry Placeholder="enter name">
<Entry.Triggers>
<Trigger TargetType="Entry"
Property="IsFocused" Value="True">
<Setter Property="BackgroundColor" Value="Yellow" />
<!-- multiple Setters elements are allowed -->
</Trigger>
</Entry.Triggers>
</Entry>
Důležité části deklarace triggeru jsou:
TargetType – typ ovládacího prvku, na který se aktivační událost vztahuje.
Vlastnost – vlastnost ovládacího prvku, který je monitorován.
Hodnota – hodnota, když dojde k monitorované vlastnosti, která způsobí aktivaci triggeru.
Setter – kolekci
Setter
prvků lze přidat a kdy je splněna podmínka triggeru. Musíte zadatProperty
aValue
nastavit.EnterActions a ExitActions (nezobrazují se) – jsou napsané v kódu a dají se použít kromě prvků (nebo místo)
Setter
prvků. Jsou popsány níže.
Použití triggeru pomocí stylu
Triggery lze také přidat do Style
deklarace ovládacího prvku, na stránce nebo v aplikaci ResourceDictionary
. Tento příklad deklaruje implicitní styl (tj. není Key
nastaveno), což znamená, že se použije u všech Entry
ovládacích prvků na stránce.
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Entry">
<Style.Triggers>
<Trigger TargetType="Entry"
Property="IsFocused" Value="True">
<Setter Property="BackgroundColor" Value="Yellow" />
<!-- multiple Setters elements are allowed -->
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
Triggery dat
Triggery dat používají datovou vazbu k monitorování jiného ovládacího prvku, který způsobí Setter
, že se zavolá. Místo atributu v triggeru Property
vlastnosti nastavte Binding
atribut tak, aby monitoroval zadanou hodnotu.
Následující příklad používá syntaxi datových vazeb. {Binding Source={x:Reference entry}, Path=Text.Length}
což je způsob, jakým odkazujeme na vlastnosti jiného ovládacího prvku. Pokud je délka entry
nuly, aktivuje se aktivační událost. V této ukázce trigger zakáže tlačítko, když je vstup prázdný.
<!-- the x:Name is referenced below in DataTrigger-->
<!-- tip: make sure to set the Text="" (or some other default) -->
<Entry x:Name="entry"
Text=""
Placeholder="required field" />
<Button x:Name="button" Text="Save"
FontSize="Large"
HorizontalOptions="Center">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding Source={x:Reference entry},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled" Value="False" />
<!-- multiple Setters elements are allowed -->
</DataTrigger>
</Button.Triggers>
</Button>
Tip
Při vyhodnocování Path=Text.Length
vždy zadejte výchozí hodnotu pro cílovou vlastnost (např. Text=""
), protože jinak bude null
a trigger nebude fungovat tak, jak očekáváte.
Kromě zadávání Setter
můžete také zadat EnterActions
a ExitActions
.
Aktivační události
Prvek EventTrigger
vyžaduje pouze Event
vlastnost, například "Clicked"
v příkladu níže.
<EventTrigger Event="Clicked">
<local:NumericValidationTriggerAction />
</EventTrigger>
Všimněte si, že neexistují žádné Setter
prvky, ale spíše odkaz na třídu definovanou, která local:NumericValidationTriggerAction
vyžaduje xmlns:local
, aby byla deklarována v XAML stránky:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"
Samotná třída implementuje TriggerAction
, což znamená, že by měla poskytnout přepsání metody Invoke
, která je volána při každé události triggeru.
Implementace akce triggeru by měla:
Implementujte obecnou
TriggerAction<T>
třídu s obecným parametrem odpovídajícím typu ovládacího prvku, na který se aktivační událost použije. Můžete použít supertřídy, jakoVisualElement
je zápis aktivačních akcí, které pracují s různými ovládacími prvky, nebo určit typ ovládacího prvku, jakoEntry
je .Přepsat metodu
Invoke
– volá se při splnění kritérií triggeru.Volitelně můžete vystavit vlastnosti, které lze nastavit v XAML při deklaraci triggeru. Příklad najdete
VisualElementPopTriggerAction
v doprovodné ukázkové aplikaci v třídě.
public class NumericValidationTriggerAction : TriggerAction<Entry>
{
protected override void Invoke (Entry entry)
{
double result;
bool isValid = Double.TryParse (entry.Text, out result);
entry.TextColor = isValid ? Color.Default : Color.Red;
}
}
Trigger události pak můžete využívat z XAML:
<EventTrigger Event="TextChanged">
<local:NumericValidationTriggerAction />
</EventTrigger>
Při sdílení triggerů v objektu ResourceDictionary
, bude jedna instance sdílena mezi ovládacími prvky, takže jakýkoli stav, který je nakonfigurovaný jednou, bude platit pro všechny.
Mějte na paměti, že triggery událostí nepodporují EnterActions
a ExitActions
nejsou popsány níže.
Více aktivačních událostí
Vypadá MultiTrigger
podobně jako Trigger
jedna nebo DataTrigger
s výjimkou jedné podmínky. Všechny podmínky musí být splněné, než Setter
se aktivuje.
Tady je příklad triggeru pro tlačítko, které se sváže se dvěma různými vstupy (email
a phone
):
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference email},
Path=Text.Length}"
Value="0" />
<BindingCondition Binding="{Binding Source={x:Reference phone},
Path=Text.Length}"
Value="0" />
</MultiTrigger.Conditions>
<Setter Property="IsEnabled" Value="False" />
<!-- multiple Setter elements are allowed -->
</MultiTrigger>
Kolekce Conditions
může také obsahovat PropertyCondition
prvky, jako je tato:
<PropertyCondition Property="Text" Value="OK" />
Sestavení více triggerů "vyžadovat vše"
Multi trigger aktualizuje svůj ovládací prvek pouze v případech, kdy jsou splněny všechny podmínky. Testování pro "všechny délky polí je nula" (například přihlašovací stránka, kde musí být dokončeny všechny vstupy), je složité, protože chcete podmínku "where Text.Length > 0", ale v XAML to nejde vyjádřit.
To lze provést pomocí .IValueConverter
Kód převaděče níže transformuje Text.Length
vazbu na bool
označující, zda je pole prázdné, nebo ne:
public class MultiTriggerConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if ((int)value > 0) // length > 0 ?
return true; // some data has been entered
else
return false; // input is empty
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotSupportedException ();
}
}
Pokud chcete tento převaděč použít ve více triggerech, nejprve ho přidejte do slovníku prostředků stránky (spolu s xmlns:local
vlastní definicí oboru názvů):
<ResourceDictionary>
<local:MultiTriggerConverter x:Key="dataHasBeenEntered" />
</ResourceDictionary>
XAML je znázorněno níže. Všimněte si následujících rozdílů od prvního příkladu více triggerů:
- Tlačítko je
IsEnabled="false"
nastavené ve výchozím nastavení. - Podmínky více aktivačních událostí používají převaděč k převodu
Text.Length
hodnoty naboolean
. - Pokud jsou
true
všechny podmínky , setter nastaví vlastnosttrue
tlačítkaIsEnabled
.
<Entry x:Name="user" Text="" Placeholder="user name" />
<Entry x:Name="pwd" Text="" Placeholder="password" />
<Button x:Name="loginButton" Text="Login"
FontSize="Large"
HorizontalOptions="Center"
IsEnabled="false">
<Button.Triggers>
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference user},
Path=Text.Length,
Converter={StaticResource dataHasBeenEntered}}"
Value="true" />
<BindingCondition Binding="{Binding Source={x:Reference pwd},
Path=Text.Length,
Converter={StaticResource dataHasBeenEntered}}"
Value="true" />
</MultiTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiTrigger>
</Button.Triggers>
</Button>
Tyto snímky obrazovky ukazují rozdíl mezi dvěma výše uvedenými příklady více triggerů. V horní části obrazovek stačí zadat text jenom v jedné Entry
části, aby se povolilo tlačítko Uložit .
V dolní části obrazovky zůstane tlačítko Přihlásit neaktivní, dokud obě pole neobsahují data.
EnterActions a ExitActions
Dalším způsobem implementace změn při výskytu triggeru je přidání EnterActions
a ExitActions
shromažďování a určení TriggerAction<T>
implementací.
Kolekce EnterActions
se používá k definování IList
TriggerAction
objektů, které budou vyvolány při splnění podmínky triggeru. Kolekce ExitActions
se používá k definování IList
TriggerAction
objektů, které budou vyvolány po splnění podmínky triggeru.
Poznámka:
Objekty TriggerAction
definované v kolekcích EnterActions
a ExitActions
třídy jsou ignorovány EventTrigger
.
V triggeru můžete zadat obojí EnterActions
i ExitActions
Setter
s, ale mějte na paměti, že Setter
se volají okamžitě (nečekají na dokončení EnterAction
nebo ExitAction
dokončení). Alternativně můžete provádět všechno v kódu a vůbec je nepoužíváte Setter
.
<Entry Placeholder="enter job title">
<Entry.Triggers>
<Trigger TargetType="Entry"
Property="Entry.IsFocused" Value="True">
<Trigger.EnterActions>
<local:FadeTriggerAction StartsFrom="0" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<local:FadeTriggerAction StartsFrom="1" />
</Trigger.ExitActions>
<!-- You can use both Enter/Exit and Setter together if required -->
</Trigger>
</Entry.Triggers>
</Entry>
Jako vždy platí, že pokud je třída odkazována v XAML, měli byste deklarovat obor názvů, jako xmlns:local
je znázorněno zde:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"
Kód FadeTriggerAction
je uvedený níže:
public class FadeTriggerAction : TriggerAction<VisualElement>
{
public int StartsFrom { set; get; }
protected override void Invoke(VisualElement sender)
{
sender.Animate("FadeTriggerAction", new Animation((d) =>
{
var val = StartsFrom == 1 ? d : 1 - d;
// so i was aiming for a different color, but then i liked the pink :)
sender.BackgroundColor = Color.FromRgb(1, val, 1);
}),
length: 1000, // milliseconds
easing: Easing.Linear);
}
}
Aktivační události stavu
Aktivační události stavu jsou specializovanou skupinou triggerů, které definují podmínky, za kterých VisualState
se má použít.
Aktivační události stavu se přidají do StateTriggers
kolekce objektu VisualState
. Tato kolekce může obsahovat jednu aktivační událost stavu nebo více aktivačních událostí stavu. A VisualState
se použije, když jsou aktivní všechny aktivační události stavu v kolekci.
Při použití aktivačních událostí stavu k řízení stavů Xamarin.Forms vizuálů používá následující pravidla priority k určení, která aktivační událost (a odpovídající VisualState
) bude aktivní:
- Jakákoli aktivační událost, která je odvozena od
StateTriggerBase
. - Aktivované
AdaptiveTrigger
z důvoduMinWindowWidth
splnění podmínky. - Aktivované
AdaptiveTrigger
z důvoduMinWindowHeight
splnění podmínky.
Pokud je více aktivačních událostí současně aktivních (například dva vlastní triggery), má přednost první aktivační událost deklarovaná v kódu.
Poznámka:
Aktivační události stavu lze nastavit v objektu Style
nebo přímo na elementy.
Další informace o vizuálních stavech najdete v tématu Xamarin.Forms Visual State Manager.
Aktivační událost stavu
Třída StateTrigger
, která je odvozena z StateTriggerBase
třídy, má IsActive
bindable vlastnost. A StateTrigger
aktivuje VisualState
změnu při IsActive
změně hodnoty vlastnosti.
Třída StateTriggerBase
, která je základní třídou pro všechny aktivační události stavu, má IsActive
vlastnost a IsActiveChanged
událost. Tato událost se aktivuje při každé VisualState
změně. Kromě toho třída StateTriggerBase
má přepsání OnAttached
a OnDetached
metody.
Důležité
Vlastnost StateTrigger.IsActive
bindable skryje zděděnou StateTriggerBase.IsActive
vlastnost.
Následující příklad XAML ukazuje Style
, že obsahuje StateTrigger
objekty:
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Checked">
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsToggled}"
IsActiveChanged="OnCheckedStateIsActiveChanged" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsToggled, Converter={StaticResource inverseBooleanConverter}}"
IsActiveChanged="OnUncheckedStateIsActiveChanged" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
V tomto příkladu implicitní Style
cíle Grid
objekty. IsToggled
Pokud je true
vlastnost vázaného objektu , barva pozadí objektu Grid
je nastavena na černou. Když se IsToggled
vlastnost vázaného objektu stane false
, VisualState
aktivuje se změna a barva pozadí se změní na bílou Grid
.
Kromě toho se při každé VisualState
změně IsActiveChanged
aktivuje událost.VisualState
Každá VisualState
zaregistruje obslužnou rutinu události pro tuto událost:
void OnCheckedStateIsActiveChanged(object sender, EventArgs e)
{
StateTriggerBase stateTrigger = sender as StateTriggerBase;
Console.WriteLine($"Checked state active: {stateTrigger.IsActive}");
}
void OnUncheckedStateIsActiveChanged(object sender, EventArgs e)
{
StateTriggerBase stateTrigger = sender as StateTriggerBase;
Console.WriteLine($"Unchecked state active: {stateTrigger.IsActive}");
}
Když se v tomto příkladu IsActiveChanged
aktivuje obslužná rutina události, obslužná rutina vypíše, jestli VisualState
je aktivní, nebo ne. Například následující zprávy jsou výstupem okna konzoly při změně ze stavu vizuálu Checked
na stav vizuálu Unchecked
:
Checked state active: False
Unchecked state active: True
Poznámka:
Aktivační události vlastního StateTriggerBase
stavu lze vytvořit odvozením z třídy a přepsáním OnAttached
metod a OnDetached
provedením požadovaných registrací a vyčištěním.
Adaptivní trigger
Když AdaptiveTrigger
je okno zadanou výškou VisualState
nebo šířkou, aktivuje se změna. Tento trigger má dvě vlastnosti s možností vytvoření vazby:
MinWindowHeight
, typudouble
, který označuje minimální výšku okna, na kterouVisualState
se má použít.MinWindowWidth
, typudouble
, který označuje minimální šířku okna, pro kterouVisualState
se má použít.
Poznámka:
Odvozena AdaptiveTrigger
z StateTriggerBase
třídy a proto může připojit obslužnou rutinu události k IsActiveChanged
události.
Následující příklad XAML ukazuje Style
, že obsahuje AdaptiveTrigger
objekty:
<Style TargetType="StackLayout">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Vertical">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="Orientation"
Value="Vertical" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Horizontal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="800" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="Orientation"
Value="Horizontal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
V tomto příkladu implicitní Style
cíle StackLayout
objekty. Pokud je šířka okna v rozmezí 0 až 800 jednotek nezávislých na zařízení, objekty, na které Style
se použije, StackLayout
budou mít svislou orientaci. Pokud je >šířka okna = 800 jednotek nezávislých na zařízení, VisualState
aktivuje se změna a StackLayout
orientace se změní na vodorovnou:
MinWindowWidth
Vlastnosti MinWindowHeight
lze použít nezávisle nebo ve spojení s ostatními. Následující XAML ukazuje příklad nastavení obou vlastností:
<AdaptiveTrigger MinWindowWidth="800"
MinWindowHeight="1200"/>
V tomto příkladu AdaptiveTrigger
označuje, že odpovídající VisualState
se použije, když je aktuální šířka >okna = 800 jednotek nezávislých na zařízení a aktuální výška okna je >= 1200 jednotek nezávislých na zařízení.
Porovnat aktivační událost stavu
VisualState
Aktivuje CompareStateTrigger
změnu, pokud je vlastnost rovna určité hodnotě. Tento trigger má dvě vlastnosti s možností vytvoření vazby:
Property
, typuobject
, který označuje vlastnost porovnávanou triggerem.Value
, typuobject
, který označuje hodnotu, pro kterouVisualState
se má použít.
Poznámka:
Odvozena CompareStateTrigger
z StateTriggerBase
třídy a proto může připojit obslužnou rutinu události k IsActiveChanged
události.
Následující příklad XAML ukazuje Style
, že obsahuje CompareStateTrigger
objekty:
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Checked">
<VisualState.StateTriggers>
<CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
Value="True" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.StateTriggers>
<CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
Value="False" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
...
<Grid>
<Frame BackgroundColor="White"
CornerRadius="12"
Margin="24"
HorizontalOptions="Center"
VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="checkBox"
VerticalOptions="Center" />
<Label Text="Check the CheckBox to modify the Grid background color."
VerticalOptions="Center" />
</StackLayout>
</Frame>
</Grid>
V tomto příkladu implicitní Style
cíle Grid
objekty. Pokud je IsChecked
false
vlastnost CheckBox
je , barva Grid
pozadí je nastavena na bílou. Když se CheckBox.IsChecked
vlastnost změní true
, VisualState
aktivuje se změna a barva pozadí se změní na Grid
černou:
Trigger stavu zařízení
VisualState
Aktivuje DeviceStateTrigger
změnu na základě platformy zařízení, na které je aplikace spuštěná. Tento trigger má jednu vlastnost s možností vytvoření vazby:
Device
, typustring
, který označuje platformu zařízení, na kteréVisualState
se má použít.
Poznámka:
Odvozena DeviceStateTrigger
z StateTriggerBase
třídy a proto může připojit obslužnou rutinu události k IsActiveChanged
události.
Následující příklad XAML ukazuje Style
, že obsahuje DeviceStateTrigger
objekty:
<Style x:Key="DeviceStateTriggerPageStyle"
TargetType="ContentPage">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="iOS">
<VisualState.StateTriggers>
<DeviceStateTrigger Device="iOS" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Silver" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Android">
<VisualState.StateTriggers>
<DeviceStateTrigger Device="Android" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="#2196F3" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="UWP">
<VisualState.StateTriggers>
<DeviceStateTrigger Device="UWP" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Aquamarine" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
V tomto příkladu explicitní Style
cíle ContentPage
objekty. ContentPage
objekty, které využívají styl, nastavují barvu pozadí na stříbro v iOSu, na bledě modrou v Androidu a na aquamarine na UPW. Následující snímky obrazovky ukazují výsledné stránky v iOSu a Androidu:
Aktivační událost stavu orientace
Když OrientationStateTrigger
se změní orientace zařízení, aktivuje VisualState
se změna. Tento trigger má jednu vlastnost s možností vytvoření vazby:
Orientation
, typuDeviceOrientation
, který označuje orientaci, na kterouVisualState
se má použít.
Poznámka:
Odvozena OrientationStateTrigger
z StateTriggerBase
třídy a proto může připojit obslužnou rutinu události k IsActiveChanged
události.
Následující příklad XAML ukazuje Style
, že obsahuje OrientationStateTrigger
objekty:
<Style x:Key="OrientationStateTriggerPageStyle"
TargetType="ContentPage">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Portrait">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Portrait" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Silver" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Landscape">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Landscape" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
V tomto příkladu explicitní Style
cíle ContentPage
objekty. ContentPage
objekty, které využívají styl, nastaví barvu pozadí na stříbro, když je orientace na výšku, a nastaví barvu pozadí na bílou, když je orientace na šířku.