2010-06-14 10 views

risposta

4

Il modo migliore è quello di andare avanti e implementare un comportamento che fa proprio questo -

public class EnumStateBehavior : Behavior<FrameworkElement> 
{ 
    public object EnumProperty 
    { 
     get { return (object)GetValue(EnumPropertyProperty); } 
     set { SetValue(EnumPropertyProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for EnumProperty. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty EnumPropertyProperty = 
     DependencyProperty.Register("EnumProperty", typeof(object), typeof(EnumStateBehavior), new UIPropertyMetadata(null, EnumPropertyChanged)); 

    static void EnumPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     if (e.NewValue == null) return; 

     EnumStateBehavior eb = sender as EnumStateBehavior; 

     VisualStateManager.GoToElementState(eb.AssociatedObject, e.NewValue.ToString(), true); 
    } 

} 

L'utilizzo è estremamente semplice - l'utilizzo come segue:

<i:Interaction.Behaviors> 
     <local:EnumStateBehavior EnumProperty="{Binding MyEnumProperty}" /> 
</i:Interaction.Behaviors> 
+0

penso che si può lasciare fuori l'override ... ed essenzialmente questo non sarebbe nemmeno bisogno di essere un comportamento –

+0

@Markus per l'override hai ragione. per quanto riguarda il comportamento - immagino che questa possa essere una proprietà associata, ma in questo modo è possibile (A) utilizzare da Blend, e (B) può essere applicata solo a FrameworkElement. –

+0

funziona bene, grazie! – thumbmunkeys

1

C'è una DataStateSwitchBehavior in SL che può essere convertito in WPF: Anyone have a DataStateSwitchBehavior for WPF4?

la sintassi è piuttosto semplice:

<is:DataStateSwitchBehavior Binding="{Binding Orientation}"> 
    <is:DataStateSwitchCase Value="Left" State="LeftState"/> 
    <is:DataStateSwitchCase Value="Right" State="RightState"/> 
    <is:DataStateSwitchCase Value="Down" State="DownState"/> 
    <is:DataStateSwitchCase Value="Up" State="UpState"/> 
<is:DataStateSwitchCase/> 
3

È possibile farlo in puro xaml utilizzando un DataTrigger per ogni valore enum con ogni trigger che chiama GoToStateAction con uno stato diverso. Vedi l'esempio qui sotto. Per maggiori dettagli dai un'occhiata a Enum driving a Visual State change via the ViewModel.

<i:Interaction.Triggers> 
     <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Unanswered"> 
      <ei:GoToStateAction StateName="UnansweredState" UseTransitions="False" /> 
     </ei:DataTrigger> 
     <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Correct"> 
      <ei:GoToStateAction StateName="CorrectlyAnsweredState" UseTransitions="True" /> 
     </ei:DataTrigger> 
     <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Incorrect"> 
      <ei:GoToStateAction StateName="IncorrectlyAnsweredState" UseTransitions="True" /> 
     </ei:DataTrigger> 
    </i:Interaction.Triggers> 
+0

Questo è in realtà ciò che ho fatto per la maggior parte delle cose. – Firoso

0

Si sono verificati problemi con la risposta EnumStateBehavior precedente.

Il gestore PropertyChanged si attiverà per la prima volta quando AssociatedObject è nullo (poiché l'associazione è stata impostata ma il comportamento non è ancora stato collegato). Inoltre, anche quando il comportamento viene collegato per la prima volta, gli elementi di destinazione dell'animazione VisualState potrebbero non esistere ancora poiché il comportamento potrebbe essere stato collegato prima di altre strutture visive secondarie.

La soluzione era utilizzare l'evento Loaded sull'oggetto associato per assicurarsi che lo stato iniziale dell'associazione fosse impostato.

public class EnumStateBehavior : Behavior<FrameworkElement> 
{ 
    public static readonly DependencyProperty BindingProperty = 
     DependencyProperty.Register(nameof(Binding), typeof(object), typeof(EnumStateBehavior), new UIPropertyMetadata(null, BindingPropertyChanged)); 

    public object Binding 
    { 
     get { return (object)GetValue(BindingProperty); } 
     set { SetValue(BindingProperty, value); } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     this.AssociatedObject.Loaded += AssociatedObject_Loaded; 
    } 

    protected override void OnDetaching() 
    { 
     this.AssociatedObject.Loaded -= AssociatedObject_Loaded; 
     base.OnDetaching(); 
    } 

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) 
    { 
     if (Binding != null) 
      GoToState(); 
    } 

    private void GoToState() 
    { 
     VisualStateManager.GoToElementState(this.AssociatedObject, Binding.ToString(), true); 
    } 

    private static void BindingPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var eb = (EnumStateBehavior)sender; 

     if (e.NewValue == null || eb.AssociatedObject == null || !eb.AssociatedObject.IsLoaded) 
      return; 

     eb.GoToState(); 
    } 
}