2 avril 2014
3
02
/04
/avril
/2014
00:31
1-Définition des « VisualState »
Le squelette se présente ainsi
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="Normal" /> <VisualState x:Name="Loading"> <Storyboard> <!-- Animations --> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> |
2-Trigger ou Code-behind
Ajouter un référence à System.Windows.Interactivity et Microsoft.Expression.Interactions
Ajouter un référence à System.Windows.Interactivity et Microsoft.Expression.Interactions
Puis les namespaces :
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei=http://schemas.microsoft.com/expression/2010/interactions
Exemple :
Je suis bindé à CurrentState , une simple propriété de mon ViewModel .Il y a un état pour la valeur « Normal » du CurrentState et un état « Loading » (correspondant au chargement) .
public class ArticleMasterDetailsViewModel :ListViewModelBase<ArticleViewModel>
{
private string _currentState;
public string CurrentState
{
get { return _currentState; }
set
{
_currentState = value;
RaisePropertyChanged<string>(() => CurrentState);
}
}
// etc.
}
}
On peut changer la valeur de ce CurrentState à chaque chargement .Intéressant si on charge des données de manière asynchrone.
L’EventTrigger ayant EventName= »Loaded » s’exécute automatiquement au chargement du usercontrol/Window
<i:Interaction.Triggers> <ei:DataTrigger Binding="{Binding CurrentState}" Value="Normal"> <ei:GoToStateAction StateName="Normal"/> </ei:DataTrigger> <ei:DataTrigger Binding="{Binding CurrentState}" Value="Loading"> <ei:GoToStateAction StateName="Loading"/> </ei:DataTrigger> <i:EventTrigger EventName="Loaded"> <ei:GoToStateAction StateName="Loading"/> </i:EventTrigger> </i:Interaction.Triggers> |
Il est possible aussi de Changer l’état visuel depuis le code – behind
Si c’est un UserControl on utilisera GoToState
VisualStateManager.GoToState(control1, "Loading", true)
Sinon (LayoutRoot correspondant au nom de mon Grid principal)
VisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, "Loading", true);
3-Un exemple
Un exemple qui se contente de cacher une grille pour afficher une autre avec un message « Chargement » .
Blend est tout indiqué pour définir des animations.
<Grid x:Name="LayoutRoot" > <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="Normal" /> <VisualState x:Name="Loading"> <Storyboard> <!-- Cache mainGrid --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="mainGrid"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <!-- Affiche loadingGrid --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="loadingGrid"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid x:Name="loadingGrid" Opacity="1" Visibility="Collapsed" Background="Black"> <Label Content="Chargement ..." FontSize="25" Foreground="White" VerticalAlignment="Bottom" HorizontalAlignment="Center" /> </Grid> <Grid x:Name="mainGrid"> <!-- contrôles de la page(textbox,boutons,etc.) --> </Grid> </Grid> |
Après libre d’utiliser Trigger + binding sur propriété ou VisualStateManager dans le code-behind,ajouter des animations/Transformations