Desencadenadores
Los desencadenadores de interfaz de usuario de aplicaciones multiplataforma (.NET MAUI) de .NET permiten expresar acciones declarativamente en XAML que cambian la apariencia de los controles en función de eventos o cambios de datos. Además, los desencadenadores de estado, que son un grupo especializado de desencadenadores, definen cuándo se debe aplicar la clase VisualState.
Puede asignar un desencadenador directamente a la colección de Triggers un control o agregarlo a un diccionario de recursos de nivel de página o de aplicación que se aplicará a varios controles.
Desencadenadores de propiedad
Trigger representa un desencadenador que aplica valores de propiedad o realiza acciones cuando la propiedad especificada cumple una condición especificada.
En el ejemplo siguiente se muestra un Trigger que cambia un Entry color de fondo cuando recibe el foco:
<Entry Placeholder="Enter name">
<Entry.Triggers>
<Trigger TargetType="Entry"
Property="IsFocused"
Value="True">
<Setter Property="BackgroundColor"
Value="Yellow" />
<!-- Multiple Setter elements are allowed -->
</Trigger>
</Entry.Triggers>
</Entry>
La declaración del desencadenador especifica lo siguiente:
TargetType: el tipo de control al que se aplica el desencadenador.Property: la propiedad del control que se supervisa.Value: el valor, cuando se produce para la propiedad supervisada, lo que hace que el desencadenador se active.Setter: una colección deSetterelementos que se aplican cuando se cumple la condición del desencadenador.
Además, se pueden especificar colecciones opcionales EnterActions y ExitActions . Para obtener más información, vea EnterActions y ExitActions.
Aplicar un desencadenador mediante un estilo
Los desencadenadores también se pueden agregar a una declaración Style en un control, en una página o una aplicación ResourceDictionary. En el ejemplo siguiente se declara un estilo implícito para todos los Entry controles de la página:
<ContentPage.Resources>
<Style TargetType="Entry">
<Style.Triggers>
<Trigger TargetType="Entry"
Property="IsFocused"
Value="True">
<Setter Property="BackgroundColor"
Value="Yellow" />
<!-- Multiple Setter elements are allowed -->
</Trigger>
</Style.Triggers>
</Style>
</ContentPage.Resources>
Desencadenadores de datos
DataTrigger representa un desencadenador que aplica valores de propiedad o realiza acciones cuando los datos enlazados cumplen una condición especificada. La Binding extensión de marcado se usa para supervisar la condición especificada.
En el ejemplo siguiente se muestra un DataTrigger que deshabilita cuando ButtonEntry está vacío:
<Entry x:Name="entry"
Text=""
Placeholder="Enter text" />
<Button Text="Save">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding Source={x:Reference entry},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled"
Value="False" />
<!-- Multiple Setter elements are allowed -->
</DataTrigger>
</Button.Triggers>
</Button>
En este ejemplo, cuando la longitud de Entry es cero, se activa el desencadenador.
Sugerencia
Al evaluar Path=Text.Length, proporcione siempre un valor predeterminado para la propiedad de destino (p. ej., Text=""> porque, de lo contrario, será null y el desencadenador no funcionará como espera.
Además, se pueden especificar colecciones opcionales EnterActions y ExitActions . Para obtener más información, vea EnterActions y ExitActions.
Desencadenadores de eventos
EventTrigger Representa un desencadenador que aplica un conjunto de acciones en respuesta a un evento. A diferencia Triggerde , EventTrigger no tiene ningún concepto de terminación del estado, por lo que las acciones no se deshacerán una vez que la condición que generó el evento ya no sea verdadera.
Un EventTrigger solo requiere que se establezca una Event propiedad:
<EventTrigger Event="TextChanged">
<local:NumericValidationTriggerAction />
</EventTrigger>
En este ejemplo, no hay elementos Setter . En su lugar, hay un NumericalValidationTriggerAction objeto .
Nota
Los desencadenadores de eventos no admiten EnterActions y ExitActions.
Una implementación de acción de desencadenador debe:
- Implementar la clase genérica
TriggerAction<T>, con el parámetro genérico correspondiente al tipo de control al que se va a aplicar el desencadenador. Puede usar clases comoVisualElementpara escribir acciones de desencadenador que funcionen con una variedad de controles o especificar un tipo de control comoEntry. - Invalide el método
Invoke. Se llama a este método cada vez que se produce el evento de desencadenador. - Opcionalmente, exponga las propiedades que se pueden establecer en XAML cuando se declara el desencadenador.
En el ejemplo siguiente se muestra la NumericValidationTriggerAction clase :
public class NumericValidationTriggerAction : TriggerAction<Entry>
{
protected override void Invoke(Entry entry)
{
double result;
bool isValid = Double.TryParse(entry.Text, out result);
entry.TextColor = isValid ? Colors.Black : Colors.Red;
}
}
Advertencia
Tenga cuidado al compartir desencadenadores en .ResourceDictionary Una instancia se compartirá entre los controles, por lo que cualquier estado configurado una vez se aplicará a todos ellos.
Desencadenadores múltiples
MultiTrigger representa un desencadenador que aplica valores de propiedad o realiza acciones cuando se cumple un conjunto de condiciones. Todas las condiciones deben ser verdaderas antes de que se apliquen los Setter objetos.
En el ejemplo siguiente se muestra un MultiTrigger objeto que se enlaza a dos Entry objetos:
<Entry x:Name="email"
Text="" />
<Entry x:Name="phone"
Text="" />
<Button Text="Save">
<Button.Triggers>
<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>
</Button.Triggers>
</Button>
Además, la MultiTrigger.Conditions colección también puede contener PropertyCondition objetos:
<PropertyCondition Property="Text"
Value="OK" />
EnterActions y ExitActions
Un enfoque alternativo para implementar los cambios cuando se produce un desencadenador es especificar y ExitActions colecciones EnterActions y crear TriggerAction<T> implementaciones.
La EnterActions colección, de tipo IList<TriggerAction>, define una colección que se invocará cuando se cumpla la condición del desencadenador. La ExitActions colección, de tipo IList<TriggerAction>, define una colección que se invocará después de que ya no se cumpla la condición del desencadenador.
Nota
La clase EventTrigger omite los objetos TriggerAction definidos en las colecciones EnterActions y ExitActions.
En el ejemplo siguiente se muestra un desencadenador de propiedad que especifica y EnterAction :ExitAction
<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>
</Trigger>
</Entry.Triggers>
</Entry>
Una implementación de acción de desencadenador debe:
- Implementar la clase genérica
TriggerAction<T>, con el parámetro genérico correspondiente al tipo de control al que se va a aplicar el desencadenador. Puede usar clases comoVisualElementpara escribir acciones de desencadenador que funcionen con una variedad de controles o especificar un tipo de control comoEntry. - Invalide el método
Invoke. Se llama a este método cada vez que se produce el evento de desencadenador. - Opcionalmente, exponga las propiedades que se pueden establecer en XAML cuando se declara el desencadenador.
En el ejemplo siguiente se muestra la FadeTriggerAction clase :
public class FadeTriggerAction : TriggerAction<VisualElement>
{
public int StartsFrom { get; set; }
protected override void Invoke(VisualElement sender)
{
sender.Animate("FadeTriggerAction", new Animation((d) =>
{
var val = StartsFrom == 1 ? d : 1 - d;
sender.BackgroundColor = Color.FromRgb(1, val, 1);
}),
length: 1000, // milliseconds
easing: Easing.Linear);
}
}
Nota
Puede proporcionar EnterActions y así como Setter objetos en un desencadenador, pero tenga en cuenta que los Setter objetos se llaman inmediatamente (no esperan a que se EnterAction complete o ExitActionExitActions ).
Desencadenadores de estado
Los desencadenadores de estado son un conjunto especializado de desencadenadores que definen las condiciones en las que se debe aplicar VisualState.
Los desencadenadores de estado se agregan a la colección StateTriggers de una clase VisualState. Esta colección puede contener un único desencadenador de estado o varios desencadenadores de estado. Se aplicará una clase VisualState cuando cualquier desencadenador de estado de la colección esté activo.
Al usar desencadenadores de estado para controlar los estados visuales, .NET MAUI usa las siguientes reglas de precedencia para determinar qué desencadenador (y correspondiente VisualState) estarán activos:
- Cualquier desencadenador derivado de
StateTriggerBase. - Una clase
AdaptiveTriggeractivada debido a que se cumple la condiciónMinWindowWidth. - Una clase
AdaptiveTriggeractivada debido a que se cumple la condiciónMinWindowHeight.
Si hay varios desencadenadores activos simultáneamente (por ejemplo, dos desencadenadores personalizados), tiene prioridad el primer desencadenador declarado en el marcado.
Nota
Los desencadenadores de estado se pueden establecer en una clase Style o directamente en los elementos.
Para obtener más información sobre los estados visuales, vea Estados visuales.
Desencadenador de estado
La clase StateTrigger, que se deriva de la clase StateTriggerBase, tiene una propiedad enlazable IsActive. Un elemento StateTrigger desencadena un cambio de VisualState cuando cambia el valor de la propiedad IsActive.
La clase StateTriggerBase, que es la clase base de todos los desencadenadores de estado, tiene una propiedad IsActive y un evento IsActiveChanged. Este evento se desencadena cuando se produce un cambio de VisualState. Además, la clase StateTriggerBase tiene métodos OnAttached y OnDetached que se pueden invalidar.
Importante
La propiedad enlazable StateTrigger.IsActive oculta la propiedad StateTriggerBase.IsActive heredada.
En el siguiente ejemplo de XAML, se muestra una clase Style que incluye objetos StateTrigger:
<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>
En este ejemplo, la clase Style implícita se destina a objetos Grid. Cuando la propiedad IsToggled del objeto enlazado es true, el color de fondo de Grid se establece en negro. Cuando la propiedad IsToggled del objeto enlazado se convierte en false, se desencadena un cambio de VisualState, y el color de fondo de Grid cambia a blanco.
Además, cada vez que se produce un VisualState cambio, se genera el IsActiveChanged evento de .VisualState Cada VisualState registra un controlador de eventos para este evento:
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}");
}
En este ejemplo, cuando se genera un controlador para el IsActiveChanged evento, el controlador genera si está VisualState activo o no. Por ejemplo, los mensajes siguientes aparecen en la ventana de la consola cuando cambian del estado visual Checked al estado visual Unchecked:
Checked state active: False
Unchecked state active: True
Nota
Para crear desencadenadores de estado personalizados, derive de la clase StateTriggerBase e invalide los métodos OnAttached y OnDetached para realizar cualquier registro y limpieza necesarios.
Desencadenador adaptable
Una clase AdaptiveTrigger desencadena un cambio de VisualState cuando la ventana tiene un alto o un ancho especificado. Este desencadenador tiene dos propiedades enlazables:
MinWindowHeight, de tipodouble, que indica la altura mínima de la ventana a la que debe aplicarseVisualState.MinWindowWidth, de tipodouble, que indica la anchura mínima de la ventana a la que debe aplicarseVisualState.
Nota
AdaptiveTrigger deriva de la clase StateTriggerBase y, por tanto, puede adjuntar un controlador de eventos al evento IsActiveChanged.
En el siguiente ejemplo de XAML, se muestra una clase Style que incluye objetos AdaptiveTrigger:
<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>
En este ejemplo, la clase Style implícita se destina a objetos StackLayout. Cuando el ancho de la ventana tiene entre 0 y 800 unidades independientes del dispositivo, los objetos StackLayout a los que se aplica la clase Style tendrán una orientación vertical. Cuando el ancho de la ventana es >= 800 unidades independientes del dispositivo, se desencadena el VisualState cambio y la StackLayout orientación cambia a horizontal.
Las propiedades MinWindowHeight y MinWindowWidth se pueden utilizar de forma independiente o combinándolas entre sí. En el siguiente ejemplo de XAML se muestra la configuración de ambas propiedades:
<AdaptiveTrigger MinWindowWidth="800"
MinWindowHeight="1200"/>
En este ejemplo, AdaptiveTrigger indica que se aplicará el correspondiente VisualState cuando el ancho de la ventana actual sea >= 800 unidades independientes del dispositivo y el alto de la ventana actual sea >= 1200 unidades independientes del dispositivo.
Comparación del desencadenador de estado
CompareStateTrigger desencadena un cambio de VisualState cuando una propiedad es igual a un valor específico. Este desencadenador tiene dos propiedades enlazables:
Property, de tipoobject, que indica la propiedad comparada por el desencadenador.Value, de tipoobject, que indica el valor al que debe aplicarseVisualState.
Nota
CompareStateTrigger deriva de la clase StateTriggerBase y, por tanto, puede adjuntar un controlador de eventos al evento IsActiveChanged.
En el siguiente ejemplo de XAML, se muestra una clase Style que incluye objetos CompareStateTrigger:
<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>
En este ejemplo, la clase Style implícita se destina a objetos Grid. Cuando la propiedad IsChecked de CheckBox es false, el color de fondo de Grid se establece en blanco. Cuando la CheckBox.IsChecked propiedad se convierte en true, se desencadena un VisualState cambio y el color de fondo de Grid se convierte en negro.
Desencadenador de estado de dispositivos
DeviceStateTrigger desencadena un cambio de VisualState basado en la plataforma del dispositivo en que se ejecuta la aplicación. Este desencadenador tiene una única propiedad enlazable:
Device, de tipostring, que indica la plataforma del dispositivo en la que debe aplicarseVisualState.
Nota
DeviceStateTrigger deriva de la clase StateTriggerBase y, por tanto, puede adjuntar un controlador de eventos al evento IsActiveChanged.
En el siguiente ejemplo de XAML, se muestra una clase Style que incluye objetos DeviceStateTrigger:
<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>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
En este ejemplo, la clase Style explícita se destina a objetos ContentPage. ContentPage objetos que consumen el estilo establecen su color de fondo en plata en iOS y en azul pálido en Android.
Desencadenador de estado de orientación
OrientationStateTrigger desencadena un cambio de VisualState cuando varía la orientación del dispositivo. Este desencadenador tiene una única propiedad enlazable:
Orientation, de tipoDeviceOrientation, que indica la orientación a la que debe aplicarseVisualState.
Nota
OrientationStateTrigger deriva de la clase StateTriggerBase y, por tanto, puede adjuntar un controlador de eventos al evento IsActiveChanged.
En el siguiente ejemplo de XAML, se muestra una clase Style que incluye objetos OrientationStateTrigger:
<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>
En este ejemplo, la clase Style explícita se destina a objetos ContentPage. Los objetos ContentPage que usan el estilo definen su color de fondo en plateado cuando la orientación es vertical y en blanco cuando la orientación es horizontal.
Examinar el ejemplo