Markieren Sie das Kontrollkästchen Englisch, um die englische Version dieses Artikels anzuzeigen. Sie können den englischen Text auch in einem Popup-Fenster einblenden, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

Übersicht über Abhängigkeitseigenschaften

 

Veröffentlicht: Juni 2016

Windows Presentation Foundation (WPF) stellt einen Satz von Diensten bereit, mit denen die Funktionalität einer Common Language Runtime (CLR)-Eigenschaft erweitert werden kann. Zusammen werden diese Dienste normalerweise als WPF-Eigenschaftensystem bezeichnet. Eine Eigenschaft, die vom WPF-Eigenschaftensystem unterstützt wird, wird als Abhängigkeitseigenschaft bezeichnet. In dieser Übersicht werden das WPF-Eigenschaftensystem und die Funktionen einer Abhängigkeitseigenschaft beschrieben. Dies beinhaltet auch die Verwendung vorhandener Abhängigkeitseigenschaften in XAML und Code. Außerdem werden spezielle Aspekte von Abhängigkeitseigenschaften behandelt, z. B. Abhängigkeitseigenschaft-Metadaten, sowie die Erstellung Ihrer eigenen Abhängigkeitseigenschaft ein einer benutzerdefinierten Klasse.

In diesem Thema wird vorausgesetzt, dass Sie über Grundkenntnisse der CLR und der objektorientierten Programmierung verfügen. Um den Beispielen in diesem Thema folgen zu können, sollten Sie außerdem mit der Verwendung von XAML und dem Schreiben von WPF-Anwendungen vertraut sein. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erste Schritte mit WPF.

In WPF werden Eigenschaften normalerweise als Common Language Runtime (CLR)-Eigenschaften offengelegt. Auf der Basisebene können Sie mit diesen Eigenschaften interagieren, ohne zu merken, dass sie als Abhängigkeitseigenschaften implementiert sind. Sie sollten jedoch mit einigen oder allen Features des WPF-Eigenschaftensystems vertraut sein, damit Sie diese Features nutzen können.

Der Zweck von Abhängigkeitseigenschaften besteht darin, den Wert einer Eigenschaft anhand des Werts anderer Eingaben zu berechnen. Diese Eingaben können Folgendes umfassen: Systemeigenschaften wie Designs und Benutzerpräferenzen, Just-In-Time-Mechanismen zur Ermittlung von Eigenschaften, z. B. Datenbindung und Animationen/Storyboards, Vorlagen zur mehrfachen Verwendung, z. B. Ressourcen und Stile, oder Werte, die aufgrund von Beziehungen mit anderen Elementen in der Elementstruktur bekannt sind (übergeordnete und untergeordnete Elemente). Außerdem kann eine Abhängigkeitseigenschaft implementiert werden, um eine unabhängige Validierung, Standardwerte, Rückrufe, die Änderungen von Eigenschaften überwachen, und ein System bereitzustellen, das Eigenschaftswerte basierend auf Laufzeitinformationen umwandeln kann. Abgeleitete Klassen können ebenfalls einige spezifische Merkmale einer vorhandenen Eigenschaft ändern, indem sie Abhängigkeitseigenschaft-Metadaten überschreiben, anstatt die eigentliche Implementierung vorhandener Eigenschaften zu überschreiben oder neue Eigenschaften zu erstellen.

In der SDK-Referenz sehen Sie, bei welcher Eigenschaft es sich um eine Abhängigkeitseigenschaft handelt, da diese auf ihren Referenzseiten jeweils über einen Abschnitt mit Informationen zur Abhängigkeitseigenschaft verfügen. Der Abschnitt mit den Informationen zur Abhängigkeitseigenschaft enthält einen Link zum DependencyProperty-Bezeichnerfeld für die jeweilige Abhängigkeitseigenschaft sowie eine Liste der Metadatenoptionen, die für die Eigenschaft festgelegt sind, Überschreibungsinformationen pro Klasse und andere Details.

Abhängigkeitseigenschaften und das WPF-Eigenschaftensystem erweitern die Eigenschaftenfunktionalität, indem ein Typ als Unterstützung für eine Eigenschaft bereitgestellt wird. Dies dient als alternative Implementierung zur standardmäßigen Vorgehensweise, bei der die Eigenschaft als Unterstützung über ein privates Feld verfügt. Der Name dieses Typs lautet DependencyProperty. Der andere wichtige Typ, der das WPF-Eigenschaftensystem definiert, ist DependencyObjectDependencyObject definiert die Basisklasse, die eine Abhängigkeitseigenschaft registrieren und besitzen kann.

Es folgt eine Zusammenfassung der Terminologie, die in dieser software development kit (SDK)-Dokumentation bei der Beschreibung der Abhängigkeitseigenschaften verwendet wird:

  • Abhängigkeitseigenschaft: Eine Eigenschaft, die als Unterstützung über eine DependencyProperty verfügt.

  • Abhängigkeitseigenschaftbezeichner: Eine DependencyProperty-Instanz, die als Rückgabewert beim Registrieren einer Abhängigkeitseigenschaft abgerufen und dann als statischer Member einer Klasse gespeichert wird. Dieser Bezeichner wird als Parameter für viele der APIs verwendet, die mit dem WPF-Eigenschaftensystem interagieren.

  • CLR-Wrapper: Die get- und set-Implementierungen für die Eigenschaft. Diese Implementierungen beziehen den Abhängigkeitseigenschaftbezeichner ein, indem sie ihn in den Aufrufen GetValue und SetValue verwenden. Auf diese Weise wird die Unterstützung für die Eigenschaft mithilfe des WPF-Eigenschaftensystems bereitgestellt.

Im folgenden Beispiel wird die IsSpinning-Abhängigkeitseigenschaft definiert und die Beziehung des DependencyProperty-Bezeichners mit der Eigenschaft gezeigt, die dieser unterstützt.

public static readonly DependencyProperty IsSpinningProperty = 
    DependencyProperty.Register(
    "IsSpinning", typeof(Boolean),
    );
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}

Die Namenskonvention der Eigenschaft und ihres unterstützenden DependencyProperty-Felds ist wichtig. Der Name des Felds muss immer der Name der Eigenschaft sein, an den das Suffix Property angehängt ist. Weitere Informationen zu dieser Konvention und die Gründe dafür finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

Sie können Eigenschaften in Code oder in XAML festlegen.

Im folgenden XAML-Beispiel wird die Hintergrundfarbe einer Schaltfläche auf Rot festgelegt. Dieses Beispiel zeigt einen Fall, bei dem der einfache Zeichenfolgenwert für ein XAML-Attribut im generierten Code vom WPF-XAML-Parser in einen WPF-Typ konvertiert wird (eine Color mithilfe eines SolidColorBrush).

<Button Background="Red" Content="Button!"/>

XAML unterstützt zum Festlegen von Eigenschaften eine Vielzahl von Syntaxformaten. Welche Syntax Sie für eine bestimmte Eigenschaft verwenden, hängt vom verwendeten Werttyp einer Eigenschaft ab, sowie von anderen Faktoren, z. B. dem Vorhandensein eines Typkonverters. Weitere Informationen zur XAML-Syntax zum Festlegen von Eigenschaften finden Sie unter Übersicht über XAML (WPF) und Ausführliche Erläuterung der XAML-Syntax.

Das folgende XAML-Beispiel zeigt einen anderen Schaltflächenhintergrund, der mithilfe einer Syntax ohne Attribute festgelegt wird. In diesem Fall wird keine einfache Füllfarbe festgelegt, sondern als Hintergrund wird ein Bild verwendet, wobei ein Element dieses Bild und die Quelle des Bilds darstellt, das als Attribut des geschachtelten Elements angegeben ist. Dies ist ein Beispiel für Eigenschaftenelementsyntax.

<Button Content="Button!">
  <Button.Background>
    <ImageBrush ImageSource="wavy.jpg"/>
  </Button.Background>
</Button>

Zum Festlegen der Werte von Abhängigkeitseigenschaften im Code ist normalerweise nur ein Aufruf an die festgelegte Implementierung erforderlich, die vom CLR-Wrapper offengelegt wird. 

Button myButton = new Button();
myButton.Width = 200.0;

Das Abrufen eines Eigenschaftswerts erfordert im Wesentlichen auch nur einen Aufruf an die Get-Wrapper-Implementierung:

double whatWidth;
whatWidth = myButton.Width;

Sie können die Eigenschaft-APIs GetValue und SetValue auch direkt aufrufen. Dies ist in der Regel nicht erforderlich, wenn Sie vorhandene Eigenschaften verwenden (Wrapper sind benutzerfreundlicher und bieten Entwicklertools eine bessere Zugänglichkeit zu Eigenschaften), aber das direkte Aufrufen von APIs ist in bestimmten Fällen notwendig.

Sie können Eigenschaften auch in XAML festlegen und dann per CodeBehind im Code später darauf zugreifen. Weitere Informationen finden Sie unter Code-Behind und XAML in WPF.

Eine Abhängigkeitseigenschaft stellt Funktionalität bereit, die die Funktionen einer Eigenschaft erweitert, anstatt eine Eigenschaft nur mit einem Feld zu unterstützen. Häufig umfassen diese Funktionalitäten ein bestimmtes Feature der gesamten Gruppe von Features von WPF:

Sie können den Wert einer Abhängigkeitseigenschaft festlegen, indem Sie auf eine Ressource verweisen. Ressourcen werden normalerweise als Resources-Eigenschaftswert eines Seitenstammelements oder der Anwendung angegeben (diese Positionen ermöglichen den einfachsten Zugriff auf die Ressource). Das folgende Beispiel zeigt, wie Sie eine SolidColorBrush-Ressource definieren.

<DockPanel.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>

Nachdem die Ressource definiert wurde, können Sie auf die Ressource verweisen und sie verwenden, um einen Eigenschaftswert anzugeben:

<Button Background="{DynamicResource MyBrush}" Content="I am gold" />

Auf diese Ressource wird als DynamicResource-Markuperweiterung verwiesen (in WPF-XAML können Sie einen statischen oder einen dynamischen Ressourcenverweis verwenden). Um einen dynamischen Ressourcenverweis zu verwenden, müssen Sie eine Abhängigkeitseigenschaft festlegen. Das WPF-Eigenschaftensystem aktiviert also die Verwendung von dynamischen Ressourcenverweisen. Weitere Informationen finden Sie unter XAML-Ressourcen.

System_CAPS_noteHinweis

Ressourcen werden als lokaler Wert behandelt. Dies bedeutet, dass Sie den Ressourcenverweis entfernen, wenn Sie einen anderen lokalen Wert festlegen. Weitere Informationen finden Sie unter Priorität von Abhängigkeitseigenschaftswerten.

Eine Abhängigkeitseigenschaft kann per Datenbindung auf einen Wert verweisen. Die Datenbindung kann mithilfe einer spezifischen Markuperweiterungssyntax in XAML oder mithilfe des Binding-Objekts im Code erfolgen. Bei der Datenbindung wird die endgültige Ermittlung des Eigenschaftswerts bis zur Laufzeit verzögert, wo der Wert dann aus einer Datenquelle abgerufen wird.

Im folgenden Beispiel wird die Content-Eigenschaft mit einer in XAML deklarierten Bindung für eine Button festgelegt. Die Bindung verwendet einen geerbten Datenkontext und eine XmlDataProvider-Datenquelle (nicht gezeigt). Die Bindung selbst gibt die gewünschte Quelleigenschaft mithilfe von XPath innerhalb der Datenquelle an.

<Button Content="{Binding XPath=Team/@TeamName}"/>
System_CAPS_noteHinweis

Bindungen werden als lokaler Wert behandelt. Dies bedeutet, dass Sie die Bindung entfernen, wenn Sie einen anderen lokalen Wert festlegen. Ausführliche Informationen finden Sie unter Priorität von Abhängigkeitseigenschaftswerten.

Abhängigkeitseigenschaften bzw. die DependencyObject-Klasse weisen keine systemeigene Unterstützung von INotifyPropertyChanged auf, die der Erstellung von Änderungsbenachrichtigungen im DependencyObject-Quelleigenschaftswert für Datenbindungsvorgänge dient. Weitere Informationen zur Erstellung von Eigenschaften für die Verwendung bei der Datenbindung, die Änderungen an ein Datenbindungsziel berichten können, finden Sie unter Übersicht über Datenbindung.

Stile und Vorlagen sind zwei Hauptgründe für die Verwendung von Abhängigkeitseigenschaften. Stile eignen sich besonders gut zum Festlegen von Eigenschaften, die eine Anwendungs-Benutzeroberfläche (User Interface, UI) definieren. Stile werden in XAML normalerweise als Ressourcen definiert. Stile interagieren mit dem Eigenschaftensystem, da sie in der Regel sog. "Setter" für bestimmte Eigenschaften enthalten, sowie "Trigger", die einen Eigenschaftswert basierend auf dem Echtzeitwert einer anderen Eigenschaft ändern.

Im folgenden Beispiel wird ein einfacher Stil erstellt (der in einem Resources-Wörterbuch definiert wird, nicht gezeigt), der direkt auf die Style-Eigenschaft für ein Button-Element angewendet wird. Der Setter im Stil legt die Background-Eigenschaft für ein formatiertes Button-Element auf Grün fest.


  <
  Style
   x:Key
  ="GreenButtonStyle"
  >
  <Setter Property="Control.Background" Value="Green"/>
</Style>

  <
  Button
   Style
  ="{StaticResource GreenButtonStyle}"
  >I am green!</Button>

Weitere Informationen finden Sie unter Erstellen von Formaten und Vorlagen.

Abhängigkeitseigenschaften können animiert werden. Wenn eine Animation angewendet wurde und ausgeführt wird, verfügt der animierte Wert über eine höhere Priorität in der Rangfolge als alle anderen Werte (z. B. ein lokaler Wert), die der Eigenschaft sonst noch zugeordnet sind.

Im folgenden Beispiel wird der Background einer Button-Eigenschaft animiert (eigentlich wird der Background animiert, indem mithilfe der Eigenschaftenelementsyntax ein leeres SolidColorBrush-Element als Background angegeben wird, und dann wird die Color-Eigenschaft dieses SolidColorBrush-Elements direkt animiert).

<Button>I am animated
  <Button.Background>
    <SolidColorBrush x:Name="AnimBrush"/>
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation
            Storyboard.TargetName="AnimBrush" 
            Storyboard.TargetProperty="(SolidColorBrush.Color)"
            From="Red" To="Green" Duration="0:0:5" 
            AutoReverse="True" RepeatBehavior="Forever" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Weitere Informationen zur Animation von Eigenschaften finden Sie unter Übersicht über Animationen und Übersicht über Storyboards.

Sie können bestimmte Verhalten einer Abhängigkeitseigenschaft ändern, indem Sie die Metadaten für diese Eigenschaft überschreiben, wenn Sie die Ableitung von der Klasse durchführen, die die Abhängigkeitseigenschaft ursprünglich registriert hat. Beim Überschreiben von Metadaten wird der DependencyProperty-Bezeichner verwendet. Das Überschreiben von Metadaten erfordert keine Neuimplementierung der Eigenschaft. Die Metadatenänderung wird vom Eigenschaftensystem selbst vorgenommen. Jede Klasse kann pro Typ individuelle Metadaten für alle Eigenschaften enthalten, die von den Basisklassen geerbt werden.

Im folgenden Beispiel werden Metadaten für den DefaultStyleKey einer Abhängigkeitseigenschaft überschrieben. Das Überschreiben dieser Abhängigkeitseigenschaft-Metadaten ist Teil eines Implementierungsmusters, bei dem Steuerelemente erstellt werden, die Standardstile aus Designs verwenden können.

public class SpinnerControl : ItemsControl
{
    static SpinnerControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(SpinnerControl), 
            new FrameworkPropertyMetadata(typeof(SpinnerControl))
        );
    }
}

Weitere Informationen über das Überschreiben oder Abrufen von Eigenschaftenmetadaten finden Sie unter Metadaten für Abhängigkeitseigenschaften.

Ein Element kann den Wert einer Abhängigkeitseigenschaft von seinem übergeordneten Element in der Objektstruktur erben.

System_CAPS_noteHinweis

Das Verhalten zur Vererbung von Eigenschaftswerten ist nicht global für alle Abhängigkeitseigenschaften aktiviert, da die Berechnungszeit für die Vererbung zu Leistungseinbußen führt. Die Vererbung von Eigenschaftswerten ist normalerweise nur für Eigenschaften aktiviert, bei denen ein bestimmtes Szenario es erfordert, dass die Vererbung von Eigenschaftswerten verwendet wird. Im Abschnitt mit den Informationen zur Abhängigkeitseigenschaft der SDK-Referenz für die Abhängigkeitseigenschaft können Sie feststellen, ob eine Abhängigkeitseigenschaft Elemente erbt.

Das folgende Beispiel zeigt eine Bindung und legt die DataContext-Eigenschaft fest, die die Quelle der Bindung angibt. Dies wurde im Bindungsbeispiel weiter oben nicht gezeigt. Alle nachfolgenden Bindungen in untergeordneten Objekten müssen die Quelle nicht angeben, sie können den geerbten Wert der DataContext-Eigenschaft im übergeordneten StackPanel-Objekt verwenden. (Alternativ könnte ein untergeordnetes Objekt eine eigene DataContext-Eigenschaft oder eine Source-Eigenschaft im Binding-Element angeben und den geerbten Wert für den Datenkontext seiner Bindungen absichtlich nicht verwenden.)

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
  <Button Content="{Binding XPath=Team/@TeamName}"/>
</StackPanel>

Weitere Informationen finden Sie unter Vererbung von Eigenschaftswerten.

Ein benutzerdefiniertes Steuerelement mit Eigenschaften, die als Abhängigkeitseigenschaften implementiert sind, erhält entsprechende WPF-Designer für Visual Studio-Unterstützung. Ein Beispiel hierfür ist die Fähigkeit, direkte und angefügte Abhängigkeitseigenschaften im Fenster Eigenschaften zu bearbeiten. Weitere Informationen finden Sie unter Übersicht über das Erstellen von Steuerelementen.

Wenn Sie den Wert einer Abhängigkeitseigenschaft abrufen, rufen Sie ggf. einen Wert ab, der für die Eigenschaft mithilfe von einer der anderen auf Eigenschaften basierenden Eingaben festgelegt wurde, die Teil des WPF-Eigenschaftensystems sind. Die Rangfolge von Abhängigkeitseigenschaftswerten wird verwendet, damit für verschiedene Szenarios zur Versorgung der Eigenschaften mit Werten Klarheit herrscht.

Betrachten Sie das folgende Beispiel. Das Beispiel enthält einen Stil, der für alle Schaltflächen und ihre Background-Eigenschaften gilt, aber es wird auch eine Schaltfläche mit einem lokal festgelegten Background-Wert angegeben.

System_CAPS_noteHinweis

In der SDK-Dokumentation werden die Begriffe "lokaler Wert" bzw. "lokal festgelegter Wert" gelegentlich verwendet, wenn Abhängigkeitseigenschaften beschrieben werden. Ein lokal festgelegter Wert ist ein Eigenschaftswert, der für eine Objektinstanz direkt im Code oder als Attribut eines Elements in XAML festgelegt ist.

Für die erste Schaltfläche wird die Eigenschaft grundsätzlich zweimal festgelegt, aber es gilt nur ein Wert: der Wert mit der höchsten Priorität in der Rangfolge. Ein lokal festgelegter Wert weist die höchste Priorität auf (gilt nicht für eine ausgeführte Animation, aber dieses Beispiel enthält keine Animation), und aus diesem Grund wird für den Hintergrund der ersten Schaltfläche der lokal festgelegte Wert verwendet, nicht der Wert des Setters für den Stil. Die zweite Schaltfläche weist keinen lokalen Wert auf (und auch keinen anderen Wert mit einer höheren Priorität als ein Stil-Setter), also wird für den Hintergrund der Schaltfläche der Wert des Stil-Setters verwendet.

<StackPanel>
  <StackPanel.Resources>
    <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
     <Setter Property="Background" Value="Red"/>
    </Style>
  </StackPanel.Resources>
  <Button Background="Green">I am NOT red!</Button>
  <Button>I am styled red</Button>
</StackPanel>

Normalerweise liegt es in Ihrem Interesse, dass Stile immer gelten und auch Vorrang vor einem lokal festgelegten Wert eines einzelnen Elements haben (andernfalls wäre es sehr schwierig, Stile oder Elemente überhaupt zu verwenden). Deshalb verfügen die Werte, die von Stilen stammen, über eine niedrigere Priorität als ein lokal festgelegter Wert. Eine ausführliche Liste der Abhängigkeitseigenschaften und der dazugehörigen geltenden Werte finden Sie unter Priorität von Abhängigkeitseigenschaftswerten.

System_CAPS_noteHinweis

Es gibt eine Reihe von Eigenschaften, die für WPF-Elemente definiert sind, bei denen es sich nicht um Abhängigkeitseigenschaften handelt. In der Regel werden Eigenschaften nur als Abhängigkeitseigenschaften implementiert, wenn es erforderlich ist, mindestens eines der vom Eigenschaftensystem bereitgestellten Szenarios zu unterstützen: Datenbindung, Stile, Animation, Standardwertunterstützung, Vererbung, angefügte Eigenschaften oder Ungültigkeit.

  • Eine angefügte Eigenschaft ist ein Eigenschaftentyp, der eine spezielle Syntax in XAML unterstützt. Eine angefügte Eigenschaft verfügt häufig nicht über eine 1:1-Beziehung mit einer Common Language Runtime (CLR)-Eigenschaft und ist nicht immer eine Abhängigkeitseigenschaft. Der Hauptzweck einer angefügten Eigenschaft besteht darin, es untergeordneten Elementen zu ermöglichen, Eigenschaftswerte an ein übergeordnetes Element zu berichten, sogar wenn das übergeordnete Element und das untergeordnete Element diese Eigenschaft nicht als Teil der Klassenmemberauflistungen enthalten. Ein Hauptszenario besteht darin, es untergeordneten Elementen zu ermöglichen, dem übergeordneten Element mitzuteilen, welche UI-Darstellung erforderlich ist. Ein Beispiel hierzu finden Sie unter Dock oder Left. Ausführliche Informationen finden Sie unter Übersicht über angefügte Eigenschaften.

  • Für Komponenten- oder Anwendungsentwickler kann es ratsam sein, eigene Abhängigkeitseigenschaften zu erstellen, um Funktionen wie Datenbindung oder Stilunterstützung zu ermöglichen oder um Unterstützung von Ungültigkeit und Wertkoersion bereitzustellen. Ausführliche Informationen finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

  • Abhängigkeitseigenschaften sollten in der Regel als öffentliche Eigenschaften angesehen werden, die für jeden Aufrufer zugänglich bzw. mindestens erkennbar sind, der über Zugriff auf eine Instanz verfügt. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften.

Anzeigen: