Stati di visualizzazione
.NET Multi-platform App UI (.NET MAUI) Visual State Manager offre un modo strutturato per apportare modifiche visive all'interfaccia utente dal codice. Nella maggior parte dei casi, l'interfaccia utente di un'app viene definita in XAML e questo codice XAML può includere markup che descrivono in che modo Visual State Manager influisce sugli oggetti visivi dell'interfaccia utente.
Visual State Manager introduce il concetto di stati di visualizzazione. Una visualizzazione MAUI .NET, ad esempio , Button può avere diversi aspetti visivi a seconda dello stato sottostante, sia che sia disabilitato o premuto o abbia lo stato attivo per l'input. Questi sono gli stati del pulsante. Gli stati di visualizzazione vengono raccolti in gruppi di stati di visualizzazione. Tutti gli stati di visualizzazione all'interno di un gruppo di stati di visualizzazione si escludono a vicenda. Sia gli stati di visualizzazione che i gruppi di stati di visualizzazione sono identificati da stringhe di testo semplici.
.NET MAUI Visual State Manager definisce un gruppo di stati di visualizzazione denominato CommonStates
con gli stati di visualizzazione seguenti:
- Normale
- Disabled
- Focused
- Selected
- PointerOver
Gli Normal
stati di visualizzazione , Disabled
Focused
, e PointerOver
sono supportati in tutte le classi che derivano da VisualElement, ovvero la classe di base per View e Page. Inoltre, è anche possibile definire gruppi di stati di visualizzazione e stati di visualizzazione personalizzati.
Il vantaggio dell'uso di Visual State Manager per definire l'aspetto, anziché accedere agli elementi visivi direttamente dal code-behind, è che è possibile controllare il modo in cui gli elementi visivi reagiscono completamente allo stato diverso in XAML, che mantiene tutta la progettazione dell'interfaccia utente in un'unica posizione.
Nota
I trigger possono anche apportare modifiche agli oggetti visivi nell'interfaccia utente in base alle modifiche apportate alle proprietà di una visualizzazione o alla generazione di eventi. Tuttavia, l'uso di trigger per gestire varie combinazioni di queste modifiche può generare confusione. Con Visual State Manager, gli stati di visualizzazione all'interno di un gruppo di stati di visualizzazione si escludono sempre a vicenda. In qualsiasi momento, solo uno stato in ogni gruppo è lo stato corrente.
Stati di visualizzazione comuni
Visual State Manager consente di includere markup nel file XAML che può modificare l'aspetto visivo di una visualizzazione se la visualizzazione è normale, disabilitata, ha lo stato attivo di input, è selezionata o ha il cursore del mouse che passa sopra ma non viene premuto. Questi sono noti come stati comuni.
Si supponga, ad esempio, di avere una Entry visualizzazione nella pagina e di voler modificare l'aspetto visivo dell'oggetto Entry nei modi seguenti:
- L'oggetto Entry deve avere uno sfondo rosa quando l'oggetto Entry è disabilitato.
- L'oggetto Entry deve avere normalmente uno sfondo lime.
- L'oggetto Entry deve espandersi fino al doppio dell'altezza normale quando ha lo stato attivo per l'input.
- L'oggetto Entry deve avere uno sfondo blu chiaro quando ha il cursore del mouse che si posiziona sopra, ma non premuto.
È possibile collegare il markup di Visual State Manager a una singola visualizzazione oppure definirlo in uno stile se si applica a più visualizzazioni.
Definire gli stati di visualizzazione in una visualizzazione
La VisualStateManager
classe definisce una VisualStateGroups
proprietà associata utilizzata per associare gli stati di visualizzazione a una visualizzazione. La VisualStateGroups
proprietà è di tipo VisualStateGroupList
, che è una raccolta di VisualStateGroup
oggetti . Pertanto, l'elemento figlio della VisualStateManager.VisualStateGroups
proprietà associata è un VisualStateGroup
oggetto . Questo oggetto definisce un x:Name
attributo che indica il nome del gruppo. In alternativa, la VisualStateGroup
classe definisce una Name
proprietà che è possibile usare. Per altre informazioni sulle proprietà associate, vedere Proprietà associate.
La VisualStateGroup
classe definisce una proprietà denominata States
, che è una raccolta di VisualState oggetti . States
è la proprietà content della VisualStateGroups
classe in modo da poter includere gli VisualState oggetti come elementi figlio di VisualStateGroup
. Ogni VisualState oggetto deve essere identificato usando x:Name
o Name
.
La VisualState classe definisce una proprietà denominata Setters
, che è una raccolta di Setter oggetti . Si tratta degli stessi Setter oggetti usati in un Style oggetto . Setters
non è la proprietà del contenuto di VisualState, pertanto è necessario includere i tag degli elementi di proprietà per la Setters
proprietà . Setter Gli oggetti devono essere inseriti come elementi figlio di Setters
. Ogni Setter oggetto indica il valore di una proprietà quando lo stato è corrente. Qualsiasi proprietà a cui fa riferimento un Setter oggetto deve essere supportata da una proprietà associabile.
Importante
Affinché gli oggetti dello stato Setter di visualizzazione funzionino correttamente, un VisualStateGroup
oggetto deve contenere un VisualState oggetto per lo Normal
stato. Se questo stato di visualizzazione non contiene Setter oggetti, deve essere incluso come uno stato di visualizzazione vuoto (<VisualState Name="Normal" />
).
L'esempio seguente mostra gli stati di visualizzazione definiti in un oggetto Entry:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</Entry>
Lo screenshot seguente mostra in Entry quattro stati di visualizzazione definiti:
Quando l'oggetto Entry Normal
è nello stato, lo sfondo è lime. Quando ottiene lo stato attivo per l'input Entry , la dimensione del carattere raddoppia. Quando l'oggetto Entry diventa disabilitato, lo sfondo diventa rosa. L'oggetto Entry non mantiene lo sfondo lime quando ottiene lo stato attivo per l'input. Quando il puntatore del mouse passa sopra Entry, ma non viene premuto, lo Entry sfondo diventa blu chiaro. Quando Visual State Manager passa tra gli stati di visualizzazione, le proprietà impostate dallo stato precedente non vengono impostate. Pertanto, gli stati di visualizzazione si escludono a vicenda.
Se si desidera che l'oggetto Entry abbia uno sfondo lime nello Focused
stato, aggiungere un altro Setter allo stato di visualizzazione:
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Definire gli stati di visualizzazione in uno stile
Spesso è necessario condividere gli stessi stati di visualizzazione in due o più visualizzazioni. In questo scenario, gli stati di visualizzazione possono essere definiti in un oggetto Style. A tale scopo, è possibile aggiungere un Setter oggetto per la VisualStateManager.VisualStateGroups
proprietà . La proprietà content per l'oggetto Setter è la relativa Value
proprietà, che può quindi essere specificata come figlio dell'oggetto Setter . La VisualStateGroups
proprietà è di tipo VisualStateGroupList
e quindi l'elemento figlio dell'oggetto Setter è un VisualStateGroupList
oggetto a cui è possibile aggiungere un VisualStateGroup
oggetto che contiene VisualState oggetti .
L'esempio seguente mostra uno stile implicito per un oggetto Entry che definisce gli stati di visualizzazione comuni:
<Style TargetType="Entry">
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Quando questo stile è incluso in un dizionario risorse a livello di pagina, l'oggetto Style verrà applicato a tutti gli Entry oggetti nella pagina. Pertanto, tutti gli Entry oggetti nella pagina risponderanno nello stesso modo ai relativi stati di visualizzazione.
Stati di visualizzazione in .NET MAUI
La tabella seguente elenca gli stati di visualizzazione definiti in .NET MAUI:
Classe | Stati | Ulteriori informazioni |
---|---|---|
Button | Pressed |
Stati di visualizzazione pulsante |
CarouselView | DefaultItem , CurrentItem , PreviousItem NextItem |
Stati di visualizzazione CarouselView |
CheckBox | IsChecked |
Stati di visualizzazione CheckBox |
CollectionView | Selected |
Stati di visualizzazione CollectionView |
ImageButton | Pressed |
Stati di visualizzazione ImageButton |
RadioButton | Checked , Unchecked |
Stati di visualizzazione RadioButton |
Switch | On , Off |
Cambiare gli stati di visualizzazione |
VisualElement | Normal , Disabled , Focused PointerOver |
Stati comuni |
Impostare lo stato su più elementi
Negli esempi precedenti gli stati di visualizzazione sono stati collegati a e gestiti su singoli elementi. Tuttavia, è anche possibile creare stati di visualizzazione collegati a un singolo elemento, ma che impostano proprietà su altri elementi all'interno dello stesso ambito. In questo modo si evita di dover ripetere gli stati di visualizzazione in ogni elemento su cui operano gli stati.
Il Setter tipo ha una TargetName
proprietà di tipo string
, che rappresenta l'oggetto di destinazione che verrà Setter modificato da per uno stato di visualizzazione. Quando la TargetName
proprietà è definita, imposta Setter l'oggetto Property
dell'oggetto definito in TargetName
su Value
:
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
In questo esempio, un Label oggetto denominato label
avrà la relativa TextColor
proprietà impostata su Red
. Quando si imposta la TargetName
proprietà è necessario specificare il percorso completo della proprietà in Property
. Pertanto, per impostare la TextColor
proprietà in un Labeloggetto , Property
viene specificato come Label.TextColor
.
Nota
Qualsiasi proprietà a cui fa riferimento un Setter oggetto deve essere supportata da una proprietà associabile.
Nell'esempio seguente viene illustrato come impostare lo stato su più oggetti, da un singolo gruppo di stati di visualizzazione:
<StackLayout>
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
In questo esempio lo Normal
stato è attivo quando Button non viene premuto e una risposta può essere immessa in Entry. Lo Pressed
stato diventa attivo quando Button viene premuto e specifica che la relativa Scale
proprietà verrà modificata dal valore predefinito da 1 a 0,8. Inoltre, la Entry proprietà denominata entry
sarà Text
impostata su Parigi. Di conseguenza, il risultato è che quando viene premuto viene Button ridimensionato per essere leggermente più piccolo e le Entry visualizzazioni di Parigi:
Quindi, quando viene Button rilasciato, viene ridimensionato in base al valore predefinito 1 e Entry visualizza qualsiasi testo immesso in precedenza.
Importante
I percorsi delle proprietà non sono supportati negli Setter elementi che specificano la TargetName
proprietà .
Definire stati di visualizzazione personalizzati
Gli stati di visualizzazione personalizzati possono essere implementati definendoli come si definiscono gli stati di visualizzazione per gli stati comuni, ma con i nomi scelti e quindi chiamando il VisualStateManager.GoToState
metodo per attivare uno stato.
Nell'esempio seguente viene illustrato come usare Visual State Manager per la convalida dell'input:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmValidationPage"
Title="VSM Validation">
<StackLayout x:Name="stackLayout"
Padding="10, 10">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValidityStates">
<VisualState Name="Valid">
<VisualState.Setters>
<Setter TargetName="helpLabel"
Property="Label.TextColor"
Value="Transparent" />
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Invalid">
<VisualState.Setters>
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Pink" />
<Setter TargetName="submitButton"
Property="Button.IsEnabled"
Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Label Text="Enter a U.S. phone number:"
FontSize="18" />
<Entry x:Name="entry"
Placeholder="555-555-5555"
FontSize="18"
Margin="30, 0, 0, 0"
TextChanged="OnTextChanged" />
<Label x:Name="helpLabel"
Text="Phone number must be of the form 555-555-5555, and not begin with a 0 or 1" />
<Button x:Name="submitButton"
Text="Submit"
FontSize="18"
Margin="0, 20"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
In questo esempio, gli stati di visualizzazione sono collegati a StackLayoute sono presenti due stati che si escludono a vicenda e Valid
Invalid
. Se l'oggetto Entry non contiene un numero di telefono valido, lo stato corrente è Invalid
e quindi ha Entry uno sfondo rosa, il secondo Label è visibile e l'oggetto Button è disabilitato. Quando viene immesso un numero di telefono valido, lo stato corrente diventa Valid
. Ottiene Entry uno sfondo lime, il secondo Label scompare e ora Button è abilitato:
Il file code-behind è responsabile della gestione dell'evento TextChanged
da Entry. Il gestore usa un'espressione regolare per determinare se la stringa di input è valida o meno. Il GoToState
metodo nel file code-behind chiama il metodo statico VisualStateManager.GoToState
sull'oggetto StackLayout :
public partial class VsmValidationPage : ContentPage
{
public VsmValidationPage()
{
InitializeComponent();
GoToState(false);
}
void OnTextChanged(object sender, TextChangedEventArgs args)
{
bool isValid = Regex.IsMatch(args.NewTextValue, @"^[2-9]\d{2}-\d{3}-\d{4}$");
GoToState(isValid);
}
void GoToState(bool isValid)
{
string visualState = isValid ? "Valid" : "Invalid";
VisualStateManager.GoToState(stackLayout, visualState);
}
}
In questo esempio il GoToState
metodo viene chiamato dal costruttore per inizializzare lo stato. Dovrebbe esserci sempre uno stato corrente. Il file code-behind chiama VisualStateManager.GoToState
quindi , con un nome di stato, sull'oggetto che definisce gli stati di visualizzazione.
Trigger dello stato di visualizzazione
Gli stati di visualizzazione supportano i trigger di stato, ovvero un gruppo specializzato di trigger che definiscono le condizioni in cui deve essere applicato un oggetto VisualState .
I trigger di stato vengono aggiunti alla raccolta StateTriggers di VisualState. Questa raccolta può contenere un solo o più trigger di stato. VisualState viene applicato quando nella raccolta è attivo un qualsiasi trigger di stato.
Quando si usano trigger di stato per controllare gli stati di visualizzazione, .NET MAUI usa le regole di precedenza seguenti per determinare quale trigger (e corrispondente VisualState) sarà attivo:
- Qualsiasi trigger che derivi da StateTriggerBase.
- AdaptiveTrigger attivato perché la condizione MinWindowWidth è soddisfatta.
- AdaptiveTrigger attivato perché la condizione MinWindowHeight è soddisfatta.
Se sono attivi più trigger, ad esempio due trigger personalizzati, contemporaneamente, il primo trigger dichiarato nel markup ha la precedenza.
Per altre informazioni sui trigger di stato, vedere Trigger di stato.