La valeur par défaut de l'attribut peut garantir la validité de l'attribut.
La validité de la vérification des attributs peut être utilisée pour vérifier les attributs d'entrée et les rappels obligatoires des attributs, c'est-à-dire que les notifications doivent être effectuées, que les attributs aient changé ou non.
Notification de changement d'attribut, lorsqu'un attribut change, le programme peut être averti pour effectuer une série de processus.
Il n'y a rien de mal avec WPF ici, voyons comment les propriétés de dépendance résolvent les problèmes ci-dessus.
Le résumé du contenu définit le premier et le plus simple attribut de dépendance, la valeur de l'attribut de dépendance, les métadonnées de l'attribut de wrapper d'attribut d'opération de base (PropertyMetadata)
Comportement de base des métadonnées d'attribut
Bien que les mots originaux de MSDN soient directs, leur exactitude ne fait aucun doute. Une fois que vous les aurez compris, vous vivrez une expérience différente lorsque vous les regarderez.
1. Définissez le premier et le plus simple attribut de dépendance
Mots originaux MSDN : Windows Présentation Foundation (WPF) fournit un ensemble de services qui peuvent être utilisés pour étendre les fonctionnalités des propriétés du Common Language Runtime (CLR). Ces services sont souvent collectivement appelés système de propriété WPF. Les propriétés prises en charge par le système de propriétés WPF sont appelées propriétés de dépendance.
Définissons un attribut de dépendance Age, comme suit :
classe publique DPCustomPeople
{
public statique en lecture seule DependencyProperty AgeProperty =
DependencyProperty.Register("Âge", typeof(int), typeof(DPCustomPeople));
public vide DisplayAgeProperty()
{
Console.WriteLine("DPName:" + DPCustomPeople.AgeProperty.Name);
Console.WriteLine("DPPropertyType:" + DPCustomPeople.AgeProperty.PropertyType);
Console.WriteLine("DPOWnerType:" + DPCustomPeople.AgeProperty.OwnerType);
}
}
Appelez ensuite le résultat de sortie
Programme de classe
{
static void Main(string[] arguments)
{
Personnes DPCustomPeople = new DPCustomPeople();
people.DisplayAgeProperty();
}
}
Vous n'êtes peut-être pas familier avec la classe DependencyProperty. La classe DependencyProperty fournit certaines caractéristiques de base des propriétés de dépendance.
La façon d'enregistrer une propriété de dépendance consiste à appeler la méthode statique Register de DependencyProperty, qui fournit plusieurs méthodes surchargées, mais les trois étapes suivantes sont nécessaires une fois l'enregistrement terminé, il s'agit d'une propriété statique.
Fournissez le nom enregistré (Nom) "Âge"
Enregistrer le type de propriété (PropertyType) typeof (int)
Enregistrez le type de propriétaire de l'attribut de dépendance (OwnerType) typeof (DPCustomPeople)
Remarque : Le nom de l'attribut, le type d'attribut et le type de propriétaire de l'attribut ne peuvent pas être modifiés une fois enregistrés.
Voici le résultat de sortie
2. Opérations de base des valeurs d'attributs dépendantes (acquisition et affectation de valeurs)
Après avoir défini la propriété de dépendance Age, nous devrions être en mesure d'effectuer des opérations d'acquisition et d'affectation de valeur sur la propriété. DependencyProperty lui-même ne fournit pas ces opérations, mais est géré par DependencyObject.
DependencyObject représente un objet qui participe au système de propriétés de dépendance.
Par conséquent, il est nécessaire que la classe définie hérite de DependencyObject, puis réécrive DPCustomPeople
classe publique DPCustomPeople:System.Windows.DependencyObject
{
}
Opérations d'attribution de valeur de base, méthodes GetValue et SetValue
public void DPPropertyBasicOperator()
{
Console.WriteLine("Âge :" + this.GetValue(DPCustomPeople.AgeProperty));
this.SetValue(DPCustomPeople.AgeProperty, 24);
Console.WriteLine("ChangedAge:" + this.GetValue(DPCustomPeople.AgeProperty));
}
Résultats de sortie
3. Le wrapper d'attribut utilise les méthodes GetValue et SetValue pour opérer sur les valeurs, afin que nous puissions l'envelopper et définir l'attribut Age.
public int Âge
{
obtenir { return (int) GetValue (AgeProperty });
set { SetValue (AgeProperty, valeur })
}
Remarque : La convention de dénomination pour l'empaquetage des propriétés dépendantes consiste à supprimer la propriété suivante
public void DPPropertyBasicOperatorUsingProperty()
{
Console.WriteLine("Âge :" + this.Age);
this.Age=24 ;
Console.WriteLine("ChangedAge:" + this.Age);
}
Le code ci-dessus semble-t-il plus concis ?
4. Métadonnées de propriété (PropertyMetadata)
Original MSDN : le système de propriétés Windows Presentation Foundation (WPF) comprend un système de reporting de métadonnées qui ne se limite pas à ce qui peut être signalé sur une propriété via la réflexion ou les fonctionnalités régulières du Common Language Runtime (CLR).
En parlant de métadonnées d'attribut, la première chose qui me vient à l'esprit est l'attribut de .net.
Personne de classe publique
{
[Valeur par défaut(200),Catégorie("Mise en page")]
public int Largeur { obtenir ;
}
Attribute doit utiliser la puissance de Visual Studio pour rendre l'IDE compatible avec Attribute, ou s'appuyer sur la réflexion pour attribuer des valeurs.
Mais sans ces technologies, new crée une nouvelle instance via les canaux normaux, et l'ajout d'attributs n'a aucun effet. Nous ne pouvons pas nous fier à ces attributs pour garantir certaines caractéristiques de base des attributs (telles que les valeurs par défaut). attributs. Différent des métadonnées décrites ci-dessus.
Métadonnées pour les propriétés de dépendance
Peut être spécifié de manière unique par la classe dans laquelle la propriété de dépendance est définie. Peut être modifié lorsque la propriété de dépendance est ajoutée à une autre classe. Peut être explicitement remplacé par toutes les classes dérivées qui héritent de la propriété de dépendance de la classe de base de définition. Le langage ci-dessus est brutal, mais Mais cela explique l'intention. Mais nous ne pouvons pas toujours comprendre les pensées du concepteur du premier coup. Connaissons d'abord l'existence de ce concept.
5. Comportement de base des métadonnées d'attribut Le comportement de base des métadonnées d'attribut fournit trois fonctions pour les attributs dépendants. C'est également le problème qui vient d'être soulevé dans cet article.
Rappel obligatoire de la propriété de notification de propriété par défaut Examinons d'abord le constructeur d'un PropertyMetadata complet. Si le PropertyMetadata par défaut n'est pas défini pour la propriété dépendante, un objet PropertyMetadata sera automatiquement créé en interne pour la propriété dépendante.
public PropertyMetadata (objet defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback)
Les attributs dépendants empruntent le concept de métadonnées d'attribut pour compléter les valeurs par défaut des attributs, les notifications d'attribut, les rappels forcés et d'autres comportements.
1.Valeur par défaut de l'attribut
public statique en lecture seule DependencyProperty NameProperty =
DependencyProperty.Register("Nom", typeof(string), typeof(DPCustomPeople),
new PropertyMetadata (string.Empty));
La plupart des gens auront une question lorsqu'ils verront cela. Pourquoi utiliser PropertyMetadata pour définir une valeur par défaut ? Pourquoi ne pas l'enregistrer directement dans la méthode Register ?
public statique en lecture seule DependencyProperty NameProperty =
DependencyProperty.Register("Nom", typeof(string), typeof(DPCustomPeople),
chaîne.Vide);
Bien sûr, cette question me préoccupe depuis longtemps, et je ne peux rien faire si je ne parviens pas à la résoudre, alors je vais la laisser de côté pour le moment.
Remarque : Lors de l'attribution d'une valeur par défaut à une propriété dans PropertyMetadata, l'exactitude du type ne peut pas être détectée.
Une telle définition, car la valeur par défaut du segment de code dp dans vs est 0, cela mérite d'être noté
public statique en lecture seule DependencyProperty NameProperty =
DependencyProperty.Register("Nom", typeof(string), typeof(DPCustomPeople),
nouveau UIPropertyMetadata(0));
2. Opération de restauration de la valeur par défaut de l'attribut
Une fois que la propriété a reçu une valeur, vous pouvez restaurer la valeur par défaut via la méthode ClearValue de DependencyObject, comme indiqué dans le code suivant
chaîne publique Nom
{
get { return (string) GetValue (NameProperty });
set { SetValue (NomProperty, valeur })
}
public statique en lecture seule DependencyProperty NameProperty =
DependencyProperty.Register("Nom", typeof(string), typeof(DPCustomPeople),
new UIPropertyMetadata(string.Empty));
public void DPPropertyClearOperator()
{
Console.WriteLine("Nom:" + this.Name);
this.Name="Terry";
Console.WriteLine("ChangedName:" + this.Name);
this.ClearValue(NameProperty);
Console.WriteLine("Nom:" + this.Name);
}
Résultats de sortie
Remarque : Faites la distinction entre l'affectation par défaut et la valeur par défaut
L'affectation par défaut est généralement effectuée dans le constructeur, mais ce n'est pas la valeur par défaut (c'était le cas avant l'avènement des propriétés de dépendance), en particulier lorsque les classes dérivées remplacent les propriétés.
Étudiant de classe publique : DPCustomPeople
{
publicÉtudiant()
{
this.Name = "Ciel" ;
}
public void TestSubDefaultDpValue()
{
Console.WriteLine("Effacer avant :"+this.Name);
this.ClearValue(Student.NameProperty);
Console.WriteLine("Effacer après :" + this.Name);
}
}
Résultats de sortie
3.Notification des changements de propriété
Cette fonction est la plus couramment utilisée. Lorsque la valeur de la propriété change, le rappel PropertyChangedCallback est déclenché.
public bool IsBoy
{
obtenir { return (bool) GetValue (IsBoyProperty });
set { SetValue (IsBoyProperty, valeur })
}
public statique en lecture seule DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Étudiant),
new UIPropertyMetadata(false,new PropertyChangedCallback(IsBoyPropertyChangedCallback)));
public static void IsBoyPropertyChangedCallback (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Étudiant st = d comme étudiant ;
si (st.IsBoy)
{
Console.WriteLine("Bonjour, mon garçon");
}
autre
{
Console.WriteLine("Bonjour, ma fille");
}
}
public void TestPropertyChangedCallback()
{
this.IsBoy = false;
ceci.IsBoy = vrai; ceci.IsBoy = vrai;
}
Vous pouvez afficher les résultats de sortie de l'ancienne valeur et de la nouvelle valeur via DependencyPropertyChangedEventArgs
Note:
(1). Grâce aux résultats de sortie ci-dessus, avez-vous vu que la valeur par défaut des propriétés dépendantes ne déclenchera pas de notifications de changement de propriété ?
(2). Déclenchez manuellement les notifications de changement d'attribut.
Si vous souhaitez que la valeur par défaut déclenche un changement de propriété (en fait, cela est parfois vraiment nécessaire), vous n'avez pas besoin d'attendre et de le déclencher manuellement.
vide privé RaiseIsBoyPropertyChangedCallback()
{
IsBoyPropertyChangedCallback (this, nouveau DependencyPropertyChangedEventArgs
(Student.IsBoyProperty, Student.IsBoyProperty.DefaultMetadata.DefaultValue, null));
}
(3). Lorsqu'il y a une notification de changement d'attribut, assurez-vous de garantir l'exactitude du type de valeur par défaut de l'attribut.
Nous savons que les types valeur ont des valeurs par défaut, mais pas les types référence (c'est-à-dire qu'ils peuvent être attribués à null). Il est possible de vérifier si un type a un type par défaut à l'aide du mot-clé default .
Nous réécrivons la valeur par défaut de la propriété de dépendance définie ci-dessus à null. Elle peut bien fonctionner lorsqu'il n'y a pas de PropertyChangedCallback, mais lorsqu'il y a une notification de changement de propriété, un désastre se produit et le programme lèvera une exception indiquant que le type ne le fait pas. correspondre.
public statique en lecture seule DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Étudiant),
new UIPropertyMetadata(null,new PropertyChangedCallback(IsBoyPropertyChangedCallback)));
Regardons à nouveau le type de référence. Si la valeur par défaut est nulle, tout ira bien.
liste IL publique LovedGirl
{
obtenir { return (IList) GetValue (LovedGirlProperty });
set { SetValue (LovedGirlProperty, valeur })
}
public statique en lecture seule DependencyProperty LovedGirlProperty =
DependencyProperty.Register("LovedGirl", typeof(IList), typeof(Étudiant),
new UIPropertyMetadata(null, new PropertyChangedCallback(LovedGirlChangedCallback)));
public static void LovedGirlChangedCallback (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Étudiant st = d comme étudiant ;
foreach (élément var dans e.NewValue en tant que IList)
{
Console.WriteLine(élément);
}
}
public void TestReferenceDpType()
{
Liste<string> list = new List<string>();
list.Add("fille 1");
list.Add("fille 2");
this.LovedGirl = liste ;
}
4. Rappel d'attribut forcé
Tout d'abord, la valeur par défaut ne déclenche toujours pas la méthode de rappel.
La méthode de rappel forcé signifie que, que la valeur de l'attribut change ou non, la méthode de rappel sera saisie.
public int Score
{
obtenir { return (int) GetValue (ScoreProperty });
set { SetValue (ScoreProperty, valeur })
}
public statique en lecture seule DependencyProperty ScoreProperty =
DependencyProperty.Register("Score", typeof(int), typeof(Étudiant),
new UIPropertyMetadata(0,null,new CoerceValueCallback(ScoreCoerceValueCallback)));
objet statique public ScoreCoerceValueCallback (DependencyObject d, objet baseValue)
{
Console.WriteLine(baseValue);
retourner la valeur de base ;
}
public void TestCoerceValueCallback()
{
ceci.Score = 0 ;
ceci.Score = 0 ;
ceci.Score = 0 ;
}