VisualStateManager.GoToState(Control, String, Boolean) Metodo

Definizione

Esegue la transizione di un controllo tra due stati, richiedendo un nuovo oggetto VisualState in base al nome.

public:
 static bool GoToState(Control ^ control, Platform::String ^ stateName, bool useTransitions);
 static bool GoToState(Control const& control, winrt::hstring const& stateName, bool const& useTransitions);
public static bool GoToState(Control control, string stateName, bool useTransitions);
function goToState(control, stateName, useTransitions)
Public Shared Function GoToState (control As Control, stateName As String, useTransitions As Boolean) As Boolean

Parametri

control
Control

Controllo che deve eseguire la transizione tra stati.

stateName
String

Platform::String

winrt::hstring

Stato finale della transizione.

useTransitions
Boolean

bool

true per usare visualTransition per eseguire la transizione tra stati. false per ignorare l'uso delle transizioni e passare direttamente allo stato richiesto. Il valore predefinito è false.

Restituisce

Boolean

bool

true se il controllo passa correttamente al nuovo stato o usa già tale stato; in caso contrario, false.

Esempio

In questo esempio viene illustrata la logica di controllo che usa il metodo GoToState per eseguire la transizione tra stati.

private void UpdateStates(bool useTransitions)
{
    if (Value >= 0)
    {
        VisualStateManager.GoToState(this, "Positive", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Negative", useTransitions);
    }

    if (isFocused)
    {
        VisualStateManager.GoToState(this, "Focused", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Unfocused", useTransitions);
    }

}
Private Sub UpdateStates(ByVal useTransitions As Boolean)
    If Value >= 0 Then
        VisualStateManager.GoToState(Me, "Positive", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Negative", useTransitions)
    End If

    If isFocused Then
        VisualStateManager.GoToState(Me, "Focused", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Unfocused", useTransitions)
    End If

End Sub
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:NumericUpDownCustomControl"
    >
    <Style TargetType="local:NumericUpDown">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:NumericUpDown">
                    <Grid  Margin="3" 
                Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ValueStates">
                                
                                <!--Make the Value property red when it is negative.-->
                                <VisualState x:Name="Negative">
                                    <Storyboard>
                                        <ColorAnimation To="Red"
                                    Storyboard.TargetName="TextBlock" 
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"/>
                                    </Storyboard>
                                </VisualState>
                                <!--Return the control to its initial state by
                    return the TextBlock Foreground to its 
                    original color.-->
                                <VisualState x:Name="Positive" />
                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">
                                <!--Add a focus rectangle to highlight the entire control
                    when it has focus.-->
                                <VisualState x:Name="Focused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" 
                                                   Storyboard.TargetProperty="Visibility" Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <!--Return the control to its initial state by
                    hiding the focus rectangle.-->
                                <VisualState x:Name="Unfocused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>

                            <Border BorderThickness="1" BorderBrush="Gray" 
                    Margin="7,2,2,2" Grid.RowSpan="2" 
                    Background="#E0FFFFFF"
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch">
                                <TextBlock x:Name="TextBlock" TextAlignment="Center" Padding="5"
                           Foreground="{TemplateBinding Foreground}"/>

                            </Border>

                            <RepeatButton Content="Up" Margin="2,5,5,0" 
                          x:Name="UpButton"
                          Grid.Column="1" Grid.Row="0"
                          Foreground="Green"/>
                            <RepeatButton Content="Down" Margin="2,0,5,5" 
                          x:Name="DownButton"
                          Grid.Column="1" Grid.Row="1" 
                          Foreground="Green"/>

                            <Rectangle Name="FocusVisual" Grid.ColumnSpan="2" Grid.RowSpan="2" 
                       Stroke="Red" StrokeThickness="1"  
                       Visibility="Collapsed"/>
                        </Grid>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
</ResourceDictionary>

Commenti

Questo metodo viene usato dalla logica di controllo. In genere è necessario solo se si scrive un controllo personalizzato o se si usa la logica a livello di app per gli stati di visualizzazione, ad esempio l'aggiornamento del contenuto dell'app per le modifiche apportate alle dimensioni o all'orientamento della finestra dell'app.

Quando si chiama questo metodo, è previsto che sia un oggetto VisualState con un valore x:Name corrispondente al valore stateName , in un punto del modello di controllo per il controllo identificato dal controllo o come risorsa per l'app. Se non è presente, non si ottengono eccezioni, ma il valore restituito sarà false. Lo stato denominato da stateName può essere in uno degli elementi VisualStateGroup nel modello per il controllo specificato. È consigliabile tenere traccia degli stati in cui VisualStateGroup e sapere quale stato viene scaricato quando si specifica un nuovo stato da tale gruppo.

In genere, ControlTemplate che contiene gli stati visivi a cui fa riferimento per nome quando si usa GoToState non è definito in modo specifico per tale istanza del controllo. Gli stati visivi sono invece dallo stile di controllo predefinito caricato come stile implicito per tutte le istanze di tale controllo. Per altre informazioni sul concetto di stile implicito, vedere Avvio rapido: Modelli di controllo.

VisualStateManager supporta due funzionalità importanti per gli autori di controlli e per gli sviluppatori di app che applicano un modello personalizzato a un controllo:

  • Gli autori di controlli o gli sviluppatori di app aggiungono elementi dell'oggetto VisualStateGroup all'elemento radice di una definizione del modello di controllo in XAML usando la proprietà associata VisualStateManager.VisualStateGroups . All'interno di un elemento VisualStateGroup, ogni Oggetto VisualState rappresenta uno stato visivo discreto di un controllo. Ogni oggetto VisualState ha un nome rappresentativo di uno stato dell'interfaccia utente che può essere modificato dall'utente o modificato dalla logica di controllo. VisualState è costituito principalmente da uno Storyboard. Questo storyboard è destinato a singoli valori delle proprietà di dipendenza che devono essere applicati ogni volta che il controllo si trova nello stato visivo.
  • Controllare gli autori o gli sviluppatori di app tra questi stati chiamando il metodo GoToState statico di VisualStateManager. Gli autori di controlli eseguono questa operazione ogni volta che la logica di controllo gestisce gli eventi che indicano una modifica dello stato o la logica di controllo avvia una modifica dello stato stessa. È più comune che il codice di definizione del controllo e non il codice dell'app, in modo che tutti gli stati visivi possibili e le relative transizioni e condizioni di trigger siano presenti per impostazione predefinita per il codice dell'app. In alternativa, è il codice dell'app che modifica gli stati visivi, per gestire gli stati di visualizzazione a livello di app in risposta alle modifiche guidate dall'utente alle dimensioni o all'orientamento della finestra dell'app principale.

Quando si chiama GoToState per modificare lo stato visivo di un controllo, VisualStateManager esegue queste azioni:

  • Prima di tutto viene determinato se esiste uno stato che corrisponde a stateName . In caso contrario, non accade nulla e il metodo restituisce false.
  • Se VisualState come denominato da stateName esiste e ha uno Storyboard, inizia lo storyboard.
  • Se VisualState usato dal controllo da tale oggetto VisualStateGroup prima dello stato appena richiesto ha uno Storyboard, tale storyboard si arresta. Oltre alle proprietà specifiche a cui il nuovo Oggetto VisualState applica un'animazione, il controllo ripristina gli stati inizialmente caricati dal modello di controllo e la relativa composizione.

Se il controllo è già presente nell'oggetto VisualState richiesto come stateName, GoToState restituisce true, ma non è presente alcuna azione (il storyboard non verrà riavviato).

Un modello di implementazione comune del controllo consiste nel definire un singolo metodo privato della classe di controllo che si occupa di tutte le possibili modifiche di VisualState per il controllo. Lo stato visivo da usare è determinato controllando le proprietà del controllo. Queste proprietà potrebbero essere pubbliche o private. I valori delle proprietà vengono regolati dai gestori nella logica di controllo per gli eventi come OnGotFocus e vengono controllati immediatamente prima di impostare lo stato visivo. L'esempio di codice in questo argomento usa questo modello di implementazione. In alternativa, è possibile chiamare GoToState per singoli stati dall'interno dei gestori eventi, dal gestore eventi di controllo (i metodi OnEvent ) o dai metodi helper chiamati da tutti gli impulsi possibili per modificare gli stati (eventi basati sull'utente, eventi di automazione, logica di inizializzazione).

È anche possibile chiamare GoToState dall'interno dell'implementazione PropertyChangedCallback per una proprietà di dipendenza personalizzata.

Stati visivi e transizioni

Oltre agli stati visivi, il modello di stato visivo include anche transizioni. Le transizioni sono azioni di animazione controllate da uno Storyboard che si verificano tra ogni stato visivo quando lo stato viene modificato. La transizione può essere definita in modo diverso per ogni combinazione di stato iniziale e stato finale, come definito dal set di stati visivi del controllo. Le transizioni vengono definite dalla proprietà Transizioni di VisualStateGroup e sono in genere definite in XAML. La maggior parte dei modelli di controllo predefiniti non definisce le transizioni e in questo caso le transizioni tra gli stati si verificano immediatamente. Per altre informazioni, vedere VisualTransition.

Un oggetto VisualTransition può essere definito anche in modo da produrre una transizione implicita. Qualsiasi proprietà di dipendenza specificamente destinata all'animazione negli stati visivi From oTo di un oggetto visivo VisualTransition e ha valori diversi tra le modifiche dello stato può essere animata con un'animazione di transizione implicita. Questa animazione generata passa tra il valore From state e il valore To state di tale proprietà usando l'interpolazione. L'animazione di transizione implicita dura per il tempo indicato dal valore GeneratedDuration di un oggetto VisualTransition. Le transizioni implicite si applicano solo alle proprietà che sono un valore Double, Color o Point . In altre parole, la proprietà deve essere possibile animare in modo implicito usando doubleAnimation, PointAnimation o ColorAnimation. Per altre informazioni, vedere GeneratedDuration.

Eventi per le modifiche dello stato visivo

CurrentStateChanging viene generato quando il controllo inizia a eseguire la transizione degli stati come richiesto dalla chiamata GoToState. Se viene applicato un oggetto VisualTransition alla modifica dello stato, questo evento si verifica all'inizio della transizione.

CurrentStateChanged viene attivato dopo che il controllo si trova nello stato richiesto dalla chiamata GoToState, proprio come inizia il nuovo Storyboard . Nessun evento viene attivato al completamento del nuovo storyboard.

Se un oggetto VisualTransition non viene applicato, CurrentStateChanging e CurrentStateChanged vengono attivati in successione rapida, ma sono garantiti in tale ordine se entrambi si verificano.

Tuttavia, se una transizione alla modifica dello stato viene interrotta da una nuova chiamata GoToState, l'evento CurrentStateChanged non viene mai generato per la prima transizione dello stato. Viene attivata una nuova serie di eventi per la modifica dello stato richiesta successiva.

OnApplyTemplate non viene richiamato per le modifiche dello stato visivo. OnApplyTemplate viene richiamato solo per il caricamento iniziale di un controllo in un'interfaccia utente XAML.

Attributi degli stati visivi denominati di un controllo personalizzato

Se si definisce un controllo personalizzato con stati visivi nel relativo codice XAML del modello di controllo, è consigliabile specificare la classe di controllo per indicare ai consumer quali stati visivi sono disponibili. A tale scopo, applicare uno o più attributi TemplateVisualState a livello di classe del codice di definizione del controllo. Ogni attributo deve specificare l'attributo x:Name dello stato, ovvero il valore stateName che un consumer di controllo passerà in una chiamata GoToState per usare tale stato visivo. Se VisualState fa parte di un Oggetto VisualStateGroup, deve essere indicato anche nella definizione dell'attributo.

Un concetto correlato è che gli autori di controlli devono attributi i nomi delle parti di controllo chiave usando TemplatePartAttribute. Questo è molto utile se i consumer di controllo vogliono accedere a parti denominate dall'ambito del modello dopo l'applicazione del modello. TemplateVisualStateAttribute e TemplatePartAttribute combinata definiscono il contratto di controllo per un controllo.

VisualStateManager personalizzato

Come scenario avanzato, è possibile derivare da VisualStateManager e modificare il comportamento predefinito di GoToState. La classe derivata deve eseguire l'override del metodo GoToStateCore protetto. Qualsiasi istanza di VisualStateManager personalizzata usa questa logica Core quando viene chiamato il metodo GoToState.

Stati visivi per gli stati di visualizzazione dell'app

Gli stati visivi non sono necessariamente per i controlli personalizzati. È possibile usare gli stati visivi dai nuovi modelli di controllo applicati a qualsiasi istanza di Control in cui si sostituisce il modello predefinito impostando la proprietà Template . Per configurare questa operazione, è necessario definire il modello di controllo e gli stati visivi che si prevede di usare come risorsa stile in Page.Resources o Application.Resources. È sempre consigliabile iniziare con una copia del modello predefinito e modificare solo alcuni aspetti del modello o anche solo modificare alcuni stati visivi e lasciare sola la composizione di base. Per altre info, vedi Guida introduttiva: Modelli di controllo.

Gli stati visivi possono essere usati per modificare le proprietà di una pagina o dei controlli all'interno della pagina per l'account per l'orientamento della finestra dell'app. La composizione o i valori delle proprietà correlate al layout del controllo possono cambiare a seconda che l'orientamento complessivo sia verticale o orizzontale. Per altre informazioni su questo scenario per GoToState, vedere Guida introduttiva: Progettazione di app per dimensioni di finestre diverse.

Stati visivi per gli elementi che non sono controlli

Gli stati visivi sono talvolta utili per gli scenari in cui si vuole modificare lo stato di un'area dell'interfaccia utente che non è immediatamente una sottoclasse Control . Non è possibile eseguire questa operazione direttamente perché il parametro di controllo del metodo GoToState richiede una sottoclasse Control , che fa riferimento all'oggetto su cui agisce VisualStateManager . Page è una sottoclasse Control ed è abbastanza raro che l'interfaccia utente venga visualizzata in un contesto in cui non si ha una pagina o la radice Window.Content non è una sottoclasse Control . È consigliabile definire un userControl personalizzato per essere la radice Window.Content o essere un contenitore per altri contenuti a cui si desidera applicare gli stati, ad esempio un pannello. È quindi possibile chiamare GoToState in UserControl e applicare gli stati indipendentemente dal fatto che il resto del contenuto sia un controllo. Ad esempio, è possibile applicare gli stati visivi all'interfaccia utente che in caso contrario è costituito da uno SwapChainPanel , purché sia stato inserito all'interno di UserControl e dichiarato stati denominati che si applicano alle proprietà dell'oggetto UserControl padre o della parte denominata SwapChainPanel del modello.

Si applica a

Vedi anche