Recherche…


Introduction

Les propriétés de dépendance sont un type de propriété qui étend une propriété CLR. Alors qu'une propriété CLR est lue directement à partir d'un membre de votre classe, une propriété de dépendance sera résolue dynamiquement lors de l'appel de la méthode GetValue () que votre objet gagne via l'héritage de la classe DependencyObject de base.

Cette section va décomposer les propriétés de dépendance et expliquer leur utilisation à la fois conceptuellement et à travers des exemples de code.

Syntaxe

  • DependencyProperty.Register (nom de la chaîne, type propertyType, type ownerType)
  • DependencyProperty.Register (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.Register (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttached (nom de la chaîne, type propertyType, type ownerType)
  • DependencyProperty.RegisterAttached (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttached (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterReadOnly (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterReadOnly (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttachedReadOnly (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttachedReadOnly (nom de la chaîne, type propertyType, type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)

Paramètres

Paramètre Détails
prénom La représentation sous forme de String du nom de la propriété
Type de propriété Le Type de la propriété, par exemple typeof(int)
propriétaireType Type de la classe dans laquelle la propriété est définie, par exemple typeof(MyControl) ou typeof(MyAttachedProperties) .
typeMetadata Instance de System.Windows.PropertyMetadata (ou de l'une de ses sous-classes) qui définit les valeurs par défaut, les callbacks de propriété modifiés, FrameworkPropertyMetadata permet de définir des options de liaison telles que System.Windows.Data.BindingMode.TwoWay .
ValiderValueCallback Rappel personnalisé qui renvoie true si la nouvelle valeur de la propriété est valide, sinon fausse.

Propriétés de dépendance standard

Quand utiliser

Pratiquement tous les contrôles WPF font un usage intensif des propriétés de dépendance. Une propriété de dépendance permet d'utiliser de nombreuses fonctionnalités WPF qui ne sont pas possibles avec les propriétés CLR standard uniquement, notamment la prise en charge des styles, des animations, de la liaison de données, de l'héritage des valeurs et des notifications de modification.

La propriété TextBox.Text est un exemple simple de la nécessité d'une propriété de dépendance standard. Ici, la liaison de données ne serait pas possible si Text était une propriété CLR standard.

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

Comment définir

Les propriétés de dépendance ne peuvent être définies que dans des classes dérivées de DependencyObject , telles que FrameworkElement , Control , etc.

L'un des moyens les plus rapides de créer une propriété de dépendance standard sans avoir à retenir la syntaxe consiste à utiliser l'extrait de code "propdp" en tapant propdp , puis en appuyant sur Tab . Un extrait de code sera inséré et pourra être modifié pour répondre à vos besoins:

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

Vous devez naviguer à travers les différentes parties de l'extrait de code pour effectuer les modifications nécessaires, y compris la mise à jour du nom de la propriété, type de propriété, contenant un type de classe, et la valeur par défaut.

Conventions importantes

Il existe quelques conventions / règles importantes à suivre ici:

  1. Créez une propriété CLR pour la propriété de dépendance. Cette propriété est utilisée dans le code-derrière de votre objet ou par d'autres consommateurs. Il devrait invoquer GetValue et SetValue pour que les consommateurs n'aient pas à le faire.

  2. Nommez correctement la propriété de dépendance. Le champ DependencyProperty doit être public static readonly . Il doit avoir un nom qui correspond au nom de la propriété CLR et se terminer par "Property", par exemple Text et TextProperty .

  3. N'ajoutez pas de logique supplémentaire au setter de la propriété CLR. Le système de propriété de dépendance (et spécifiquement XAML) n'utilise pas la propriété CLR. Si vous souhaitez effectuer une action lorsque la valeur de la propriété change, vous devez fournir un rappel via PropertyMetadata :

    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.
    }
    

Mode de liaison

Pour éliminer la nécessité de spécifier Mode=TwoWay dans les liaisons (similaire au comportement de TextBox.Text ), mettez à jour le code pour utiliser FrameworkPropertyMetadata au lieu de PropertyMetadata et spécifiez l'indicateur approprié:

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

Propriétés de dépendance attachées

Quand utiliser

Une propriété attachée est une propriété de dépendance qui peut être appliquée à n'importe quel DependencyObject pour améliorer le comportement de divers contrôles ou services qui connaissent l'existence de la propriété.

Certains cas d'utilisation pour les propriétés jointes incluent:

  1. Avoir un élément parent itérer à travers ses enfants et agir sur les enfants d'une certaine manière. Par exemple, le contrôle Grid utilise les Grid.Row Grid.Column Grid.Row , Grid.Column , Grid.RowSpan et Grid.ColumnSpan pour organiser les éléments en lignes et en colonnes.
  2. Ajouter des éléments visuels aux contrôles existants à l'aide de modèles personnalisés, par exemple en ajoutant des filigranes à des zones de texte vides dans toute l'application sans avoir à sous- TextBox .
  3. Fournir un service ou une fonctionnalité générique à certains ou à tous les contrôles existants, par exemple ToolTipService ou FocusManager . Ceux-ci sont communément appelés comportements attachés .
  4. Lorsque l'héritage de l'arborescence visuelle est requis, par exemple, similaire au comportement de DataContext .

Cela démontre davantage ce qui se passe dans le cas d'utilisation de la Grid :

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

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

Grid.Column n'est pas une propriété existant sur Label ou TextBox . Le contrôle Grid examine plutôt ses éléments enfants et les organise en fonction des valeurs des propriétés attachées.

Comment définir

Nous continuerons à utiliser la Grid pour cet exemple. La définition de Grid.Column est indiquée ci-dessous, mais DependencyPropertyChangedEventHandler est exclu pour des raisons de concision.

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

Les propriétés attachées pouvant être associées à une grande variété d'éléments, elles ne peuvent pas être implémentées en tant que propriétés CLR. Une paire de méthodes statiques est introduite à la place.

Par conséquent, contrairement aux propriétés de dépendance standard, les propriétés attachées peuvent également être définies dans des classes non dérivées de DependencyObject .

Les mêmes conventions de dénomination qui s'appliquent aux propriétés de dépendance normales s'appliquent également ici: la propriété de dépendance RowProperty a les méthodes correspondantes GetRow et SetRow .

Mises en garde

Comme documenté sur MSDN :

Bien que l'héritage des valeurs de propriété puisse sembler fonctionner pour les propriétés de dépendance non attachées, le comportement d'héritage pour une propriété non attachée via certaines limites d'éléments dans l'arborescence d'exécution n'est pas défini. Utilisez toujours RegisterAttached pour enregistrer les propriétés dans lesquelles vous spécifiez Inherits dans les métadonnées.

Propriétés de dépendance en lecture seule

Quand utiliser

Une propriété de dépendance en lecture seule est similaire à une propriété de dépendance normale, mais elle est structurée pour ne pas permettre que sa valeur soit définie en dehors du contrôle. Cela fonctionne bien si vous avez une propriété purement informative pour les consommateurs, par exemple IsMouseOver ou IsKeyboardFocusWithin .

Comment définir

Tout comme les propriétés de dépendance standard, une propriété de dépendance en lecture seule doit être définie sur une classe dérivée de 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); }
    }
}

Les mêmes conventions qui s'appliquent aux propriétés de dépendance régulières s'appliquent également ici, mais avec deux différences principales:

  1. Le DependencyProperty provient d'un DependencyPropertyKey private .
  2. Le setter de propriétés CLR est protected ou private au lieu de public .

Notez que le poseur passe MyPropertyPropertyKey et non MyPropertyProperty à la SetValue méthode. Étant donné que la propriété a été définie en lecture seule, toute tentative d'utilisation de SetValue sur la propriété doit être utilisée avec une surcharge qui reçoit DependencyPropertyKey ; sinon, une InvalidOperationException sera lancée.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow