Frage WPF: Kann ich eine angefügte Eigenschaft über einen Stil definieren / festlegen?


Gibt es eine Möglichkeit, eine angehängte Eigenschaft über einen Style festzulegen?

Ich habe z.B. eine Schaltfläche, auf der Interaction-Stuff gesetzt ist (aus System.Windows.Interactivity)

<Button>
  <i:Interaction.Triggers>
    ...
  </i:Interaction.Triggers>
</Button>

Jetzt möchte ich einen Stil erstellen, in dem diese Interaction.Triggers-Eigenschaft festgelegt ist, wodurch Redundanzen ersetzt werden, indem diese Eigenschaft für jede Button-Instanz angegeben werden muss. Ist das in WPF möglich?

<Style Target={x:Type Button}>
  <!-- ??? -->
  <Setter PropertyName="i.Interaction.Triggers">
  ...

Irgendwie kann ich nicht sehen, wie, aber ich habe andere Beispiele im Web gesehen, wo angefügte Eigenschaften scheinen, innerhalb eines Stils zugänglich zu sein ...

Aktualisieren


5
2018-02-02 14:54


Ursprung


Antworten:


Dies ist ein bekanntes Problem bei schreibgeschützten Auflistungseigenschaften (dasselbe gilt für die InputBindings-Auflistung). Um dieses Problem zu lösen, habe ich eine angehängte Eigenschaft erstellt:

public static StyleTriggerCollection GetTriggers(DependencyObject obj) {
    return (StyleTriggerCollection)obj.GetValue(TriggersProperty);
}

public static void SetTriggers(DependencyObject obj, StyleTriggerCollection value) {
    obj.SetValue(TriggersProperty, value);
}

public static readonly DependencyProperty TriggersProperty =
    DependencyProperty.RegisterAttached("Triggers", typeof(StyleTriggerCollection), typeof(ControlExtensions), new UIPropertyMetadata(null, OnTriggersChanged));

static void OnTriggersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var triggers = (StyleTriggerCollection) e.NewValue;

    if (triggers != null) {
        var existingTriggers = Interaction.GetTriggers(d);

        foreach (var trigger in triggers) {
            existingTriggers.Add((TriggerBase)trigger.Clone());
        }
    }
}

Diese Eigenschaft verwendet benutzerdefinierte StyleTriggerCollection, da die Standard-Trigger-Sammlung keinen öffentlichen Konstruktor hat:

public class StyleTriggerCollection : Collection<TriggerBase>
{
}

Im Style-Setter können Sie es wie folgt verwenden:

<Setter Property="my:ControlExtensions.Triggers">
    <Setter.Value>
        <my:StyleTriggerCollection>
            <!-- Put your triggers here -->
        </my:StyleTriggerCollection>
    </Setter.Value>
</Setter>

8
2018-02-02 15:29