Suche…


Einführung

Abhängigkeitseigenschaften sind ein Eigenschaftstyp, der eine CLR-Eigenschaft erweitert. Während eine CLR-Eigenschaft direkt von einem Member Ihrer Klasse gelesen wird, wird eine Dependency-Eigenschaft beim Aufrufen der GetValue () - Methode, die Ihr Objekt durch Vererbung von der Basisklasse DependencyObject erhält, dynamisch aufgelöst.

In diesem Abschnitt werden die Abhängigkeitseigenschaften aufgeschlüsselt und deren Verwendung sowohl konzeptionell als auch anhand von Codebeispielen erläutert.

Syntax

  • DependencyProperty.Register (Zeichenfolgenname, Typ propertyType, Type ownerType)
  • DependencyProperty.Register (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.Register (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttached (Zeichenfolgenname, Typ propertyType, Type ownerType)
  • DependencyProperty.RegisterAttached (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttached (Stringname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterReadOnly (Name der Zeichenfolge, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterReadOnly (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttachedReadOnly (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttachedReadOnly (Zeichenfolgenname, Typ propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)

Parameter

Parameter Einzelheiten
Name Die String Darstellung des Namens der Eigenschaft
Art der Immobilie Der Type der Eigenschaft, zB typeof(int)
ownerType Der Type der Klasse, in der die Eigenschaft definiert wird, z. B. typeof(MyControl) oder typeof(MyAttachedProperties) .
typeMetadata Instanz von System.Windows.PropertyMetadata (oder einer ihrer Unterklassen), die Standardwerte definiert, die Eigenschaft geänderter Callbacks. Mit FrameworkPropertyMetadata können Bindungsoptionen wie System.Windows.Data.BindingMode.TwoWay .
validateValueCallback Benutzerdefinierter Rückruf, der true zurückgibt, wenn der neue Wert der Eigenschaft gültig ist, andernfalls false.

Standardabhängigkeitseigenschaften

Wann verwenden?

Praktisch alle WPF-Steuerelemente nutzen die Abhängigkeitseigenschaften stark. Eine Abhängigkeitseigenschaft ermöglicht die Verwendung vieler WPF-Funktionen, die mit den Standard-CLR-Eigenschaften allein nicht möglich sind, einschließlich der Unterstützung für Stile, Animationen, Datenbindung, Wertvererbung und Änderungsbenachrichtigungen.

Die TextBox.Text Eigenschaft ist ein einfaches Beispiel dafür, wo eine Standardabhängigkeitseigenschaft benötigt wird. Hier wäre eine Datenbindung nicht möglich, wenn Text eine CLR-Standardeigenschaft war.

<TextBox Text="{Binding FirstName}" />

Wie zu definieren

Abhängigkeitseigenschaften können nur in von DependencyObject abgeleiteten Klassen wie FrameworkElement , Control usw. definiert werden.

Eine der schnellsten Methoden zum Erstellen einer Standardabhängigkeitseigenschaft, ohne sich an die Syntax zu erinnern, besteht darin, den "propdp" -Schnipsel zu verwenden, indem Sie propdp und dann die Tabulatortaste drücken. Ein Code-Snippet wird eingefügt, der dann an Ihre Bedürfnisse angepasst werden kann:

public class MyControl : Control
{
    public int MyProperty
    {
        get { return (int)GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyProperty.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
            new PropertyMetadata(0));
}

Sie sollten Tab durch die verschiedenen Teile des Code - Schnipsel , die notwendigen Änderungen vorzunehmen, einschließlich den Namen der Eigenschaft zu aktualisieren, Objekttyp, Klassentyp enthält, und den Standardwert.

Wichtige Konventionen

Hier sind einige wichtige Konventionen / Regeln zu beachten:

  1. Erstellen Sie eine CLR-Eigenschaft für die Abhängigkeitseigenschaft. Diese Eigenschaft wird im Code-Behind Ihres Objekts oder von anderen Konsumenten verwendet. Es sollte GetValue und SetValue damit die Verbraucher dies nicht tun müssen.

  2. Benennen Sie die Abhängigkeitseigenschaft richtig. Das DependencyProperty Feld sollte public static readonly . Es sollte einen Namen haben, der dem Namen der CLR-Eigenschaft entspricht und mit "Property" endet, z. B. Text und TextProperty .

  3. Fügen Sie dem Einsteller der CLR-Eigenschaft keine zusätzliche Logik hinzu. Das Abhängigkeitseigenschaftssystem (und insbesondere XAML) verwendet die CLR-Eigenschaft nicht. Wenn Sie eine Aktion ausführen möchten, wenn sich der Wert der Eigenschaft ändert, müssen Sie einen Rückruf über PropertyMetadata bereitstellen:

    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
            new PropertyMetadata(0, MyPropertyChangedHandler));
    
    private static void MyPropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        // Use args.OldValue and args.NewValue here as needed.
        // sender is the object whose property changed.
        // Some unboxing required.
    }
    

Bindungsmodus

Um die Notwendigkeit der Angabe von Mode=TwoWay in Bindungen (ähnlich dem Verhalten von TextBox.Text ) zu TextBox.Text aktualisieren Sie den Code, um FrameworkPropertyMetadata anstelle von PropertyMetadata und geben Sie das entsprechende Flag an:

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl), 
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Angehängte Abhängigkeitseigenschaften

Wann verwenden?

Eine angefügte Eigenschaft ist eine Abhängigkeitseigenschaft, die auf jedes DependencyObject angewendet werden kann, um das Verhalten verschiedener Steuerelemente oder Dienste zu verbessern, die sich der Existenz der Eigenschaft bewusst sind.

Einige Anwendungsfälle für angefügte Eigenschaften umfassen:

  1. Ein Elternelement iteriert durch seine Kinder und wirkt auf eine bestimmte Weise auf die Kinder ein. Das Grid Steuerelement verwendet beispielsweise die angefügten Eigenschaften Grid.Row , Grid.Column , Grid.RowSpan und Grid.ColumnSpan , um Elemente in Zeilen und Spalten anzuordnen.
  2. Hinzufügen von Visuals zu vorhandenen Steuerelementen mit benutzerdefinierten Vorlagen, z. B. Hinzufügen von Wasserzeichen zu leeren Textfeldern, ohne dass TextBox Unterklasse verwendet werden TextBox .
  3. Bereitstellung eines generischen Services oder Features für einige oder alle vorhandenen Steuerelemente, z. B. ToolTipService oder FocusManager . Diese werden im Allgemeinen als angefügte Verhaltensweisen bezeichnet .
  4. Wenn die Vererbung nach unten erfolgt, ist der visuelle Baum erforderlich, z. B. ähnlich dem Verhalten von DataContext .

Dies zeigt weiter, was im Grid Anwendungsfall passiert:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Label Grid.Column="0" Content="Your Name:" />
    <TextBox Grid.Column="1" Text="{Binding FirstName}" />
</Grid>

Grid.Column ist keine Eigenschaft, die in Label oder TextBox . Das Grid Steuerelement durchsucht die untergeordneten Elemente und ordnet sie gemäß den Werten der angefügten Eigenschaften an.

Wie zu definieren

Wir werden Grid für dieses Beispiel verwenden. Die Definition von Grid.Column wird unten gezeigt, der DependencyPropertyChangedEventHandler ist jedoch der Kürze Grid.Column ausgeschlossen.

public static readonly DependencyProperty RowProperty =
    DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid),
        new FrameworkPropertyMetadata(0, ...));

public static void SetRow(UIElement element, int value)
{
    if (element == null)
        throw new ArgumentNullException("element");

    element.SetValue(RowProperty, value);
}

public static int GetRow(UIElement element)
{
    if (element == null)
        throw new ArgumentNullException("element");

    return ((int)element.GetValue(RowProperty));
}

Da die angefügten Eigenschaften an eine Vielzahl von Elementen angehängt werden können, können sie nicht als CLR-Eigenschaften implementiert werden. Stattdessen wird ein Paar statischer Methoden eingeführt.

Im Gegensatz zu Standardabhängigkeitseigenschaften können angefügte Eigenschaften auch in Klassen definiert werden, die nicht von DependencyObject abgeleitet sind.

Die gleichen Namenskonventionen gelten auch für reguläre Abhängigkeitseigenschaften: Die Abhängigkeitseigenschaft RowProperty verfügt über die entsprechenden Methoden GetRow und SetRow .

Vorsichtsmaßnahmen

Wie auf MSDN dokumentiert :

Obwohl die Vererbung von Eigenschaftswerten für nicht angefügte Abhängigkeitseigenschaften zu funktionieren scheint, ist das Vererbungsverhalten für eine nicht angefügte Eigenschaft über bestimmte Elementgrenzen in der Laufzeitstruktur nicht definiert. Verwenden Sie immer RegisterAttached, um Eigenschaften zu registrieren, in denen Sie Inherits in den Metadaten angeben.

Schreibgeschützte Abhängigkeitseigenschaften

Wann verwenden?

Eine schreibgeschützte Abhängigkeitseigenschaft ähnelt einer normalen Abhängigkeitseigenschaft. Sie ist jedoch so strukturiert, dass ihr Wert nicht außerhalb des Steuerelements festgelegt werden kann. Dies funktioniert gut, wenn Sie über eine Eigenschaft verfügen, die rein informativ für Verbraucher ist, z. B. IsMouseOver oder IsKeyboardFocusWithin .

Wie zu definieren

Genau wie Standardabhängigkeitseigenschaften muss eine schreibgeschützte Abhängigkeitseigenschaft für eine Klasse definiert werden, die von DependencyObject .

public class MyControl : Control
{
    private static readonly DependencyPropertyKey MyPropertyPropertyKey = 
        DependencyProperty.RegisterReadOnly("MyProperty", typeof(int), typeof(MyControl),
            new FrameworkPropertyMetadata(0));

    public static readonly DependencyProperty MyPropertyProperty = MyPropertyPropertyKey.DependencyProperty;

    public int MyProperty
    {
        get { return (int)GetValue(MyPropertyProperty); }
        private set { SetValue(MyPropertyPropertyKey, value); }
    }
}

Die gleichen Konventionen, die für reguläre Abhängigkeitseigenschaften gelten, gelten auch hier, jedoch mit zwei Hauptunterschieden:

  1. Die DependencyProperty wird von einem private DependencyPropertyKey .
  2. Der CLR-Eigenschaftssetzer ist protected oder private anstelle von public .

Beachten Sie, dass der Setter MyPropertyPropertyKey und nicht MyPropertyProperty an die SetValue Methode SetValue . Da die Eigenschaft als schreibgeschützt definiert wurde, muss jeder Versuch, SetValue für die Eigenschaft zu verwenden, mit Überladung verwendet werden, die DependencyPropertyKey empfängt. Andernfalls wird eine InvalidOperationException ausgelöst.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow