C'è un modo semplice in WPF per associare i VisualState ai valori enum? Un po 'come DataStateBehavior, ma per un Enum?DataStateBehavior per Enum anziché bool? Stringa?
risposta
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>
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/>
È 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>
Questo è in realtà ciò che ho fatto per la maggior parte delle cose. – Firoso
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();
}
}
- 1. Restituisce enum anziché bool dalla funzione per chiarezza?
- 2. Perché utilizzare enum anziché costanti?
- 3. Parse stringa enum tipo
- 4. .NET: bool vs enum come parametro metodo
- 5. Stringa per enum in C++
- 6. Enum anziché le solite classi in Java
- 7. Convertire complessa condizione bool da stringa a bool in .NET
- 8. Utilizza per l'attributo [Obsoleto (stringa, bool)] per .NET
- 9. Get enum come stringa
- 10. Stringa di mappa per enum con Automapper
- 11. Converti bool? per bool in Visualizza
- 12. costruendo enum con sottostante il tipo "bool" di un booleano?
- 13. come convertire una stringa in un bool
- 14. TypeScript: Converti un valore bool in stringa
- 15. Overloaded Bool/String Ambiguity
- 16. Enum e stringa di corrispondenza
- 17. C# esplicita fusione stringa enum
- 18. Typescript `enum` dalla stringa JSON
- 19. C: Mappa stringa da ENUM
- 20. Dozer Stringa da enum mappatura
- 21. C++ BOOL (typedef int) vs bool per prestazioni
- 22. Utilizzare String.Replace() con un indice anziché una stringa per l'argomento?
- 23. Passaggio di una condizione in Func <bool> di una tupla <stringa, stringa, Func <bool>>
- 24. espressione regolare su stream anziché stringa?
- 25. Qual è il modo migliore per convertire enum in stringa?
- 26. Cercando di analizzare un enum bandiera per stringa
- 27. Utilizzando automapper per mappare una stringa in un enum
- 28. Vincolo percorso MVC per bool
- 29. override bool() per classe personalizzata
- 30. boost :: bimap per enum
penso che si può lasciare fuori l'override ... ed essenzialmente questo non sarebbe nemmeno bisogno di essere un comportamento –
@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. –
funziona bene, grazie! – thumbmunkeys