2010-06-14 5 views

Antwort

4

Der beste Weg ist, einfach weiter gehen und ein Verhalten zu implementieren, die genau das tut -

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); 
    } 

} 

Die Nutzung ist denkbar einfach - Verwendung wie folgt:

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

Ich glaube, Sie die Überschreibung auslassen können ... und im Wesentlichen würde dies nicht einmal ein Verhalten –

+0

@Markus in Bezug auf die Überschreibung, du hast Recht sein muß. Was das Verhalten angeht - ich denke, das könnte eine angehängte Eigenschaft sein, aber so ist es - (A) verwendbar von Blend, und (B) kann erzwungen werden, nur auf FrameworkElement gesetzt zu werden. –

+0

funktioniert gut, danke! – thumbmunkeys

3

Sie können dies in reinem XAML tun, indem Sie einen DataTrigger pro möglichem Enum-Wert verwenden, wobei jeder Trigger GoToStateAction mit einem anderen Status aufruft. Siehe das Beispiel unten. Für weitere Details werfen Sie einen Blick auf 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

Dies ist tatsächlich, was ich für die meisten Dinge getan habe. – Firoso

0

Ich hatte Probleme mit der obigen EnumStateBehavior Antwort.

Der PropertyChanged-Handler wird zuerst ausgelöst, wenn das AssociatedObject null ist (da die Bindung eingerichtet wurde, aber das Verhalten noch nicht angefügt wurde). Auch wenn das Verhalten zum ersten Mal angefügt wird, sind die Zielelemente der VisualState-Animation möglicherweise noch nicht vorhanden, da das Verhalten möglicherweise vor anderen untergeordneten visuellen Bäumen angehängt wurde.

Die Lösung bestand darin, das Loaded-Ereignis für das zugeordnete Objekt zu verwenden, um sicherzustellen, dass der Anfangszustand der Bindung festgelegt ist.

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(); 
    } 
}