Condividi tramite


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 Normalstati di visualizzazione , DisabledFocused, 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:

Screenshot dei tre stati di visualizzazione definiti nella voce.

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 VisualStateGroupListe 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, PreviousItemNextItem 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, FocusedPointerOver 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:

Screenshot dello stato Premuto per un pulsante.

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 è Invalide 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:

Screenshot dell'esempio di convalida dello stato di visualizzazione.

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.GoToStatequindi , 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:

  1. Qualsiasi trigger che derivi da StateTriggerBase.
  2. AdaptiveTrigger attivato perché la condizione MinWindowWidth è soddisfatta.
  3. 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.