2010-06-14 22 views

Odpowiedz

4

Najlepszym sposobem jest po prostu iść do przodu i wdrożyć Zachowanie że właśnie to robi -

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

} 

Użycie jest bardzo proste - wykorzystanie w następujący sposób:

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

myślę, że może opuścić nadpisanie ... iw zasadzie to nawet nie trzeba być zachowanie –

+0

@Markus co do ręcznego masz rację. jeśli chodzi o zachowanie - myślę, że może to być dołączona właściwość, ale w ten sposób jest - (A) możliwa do wykorzystania z Blend, a (B) może być wymuszona, aby można ją było umieścić tylko w FrameworkElement. –

+0

działa ładnie, dzięki! – thumbmunkeys

1

Jest DataStateSwitchBehavior w SL, które można przenieść do WPF: Anyone have a DataStateSwitchBehavior for WPF4?

Składnia jest dość prosta:

<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

Możesz to zrobić w czystym Xaml przy użyciu DataTriggera na każdą możliwą wartość wyliczenia przy każdym wywołaniu wyzwalacza GoToStateAction z innym stanem. Zobacz przykład poniżej. Aby uzyskać więcej informacji, zobacz 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

To jest właśnie to, co zrobiłem dla większości rzeczy. – Firoso

0

Wystąpiły problemy z powyższą odpowiedzią EnumStateBehavior.

Obsługa właściwości PropertyChanged uruchamia się, gdy obiekt AssociatedObject ma wartość NULL (ponieważ powiązanie zostało skonfigurowane, ale zachowanie nie zostało jeszcze przyłączone). Ponadto, nawet jeśli zachowanie jest najpierw dołączone, docelowe elementy animacji VisualState mogą jeszcze nie istnieć, ponieważ zachowanie mogło zostać dołączone przed innymi potomnymi drzewami wizualnymi.

Rozwiązaniem było użycie zdarzenia Załadowano na powiązanym obiekcie, aby upewnić się, że ustawiono stan początkowy wiązania.

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(); 
    } 
} 
Powiązane problemy