El valor predeterminado del atributo puede garantizar la validez del atributo.
La validez de la verificación de atributos se puede utilizar para verificar los atributos de entrada y las devoluciones de llamada obligatorias de atributos, es decir, las notificaciones deben realizarse independientemente de si los atributos han cambiado o no.
Notificación de cambio de atributo, cuando un atributo cambia, se puede notificar al programa para que realice una serie de procesos.
Aquí no hay nada de malo con WPF, veamos cómo las propiedades de dependencia resuelven los problemas anteriores.
El resumen de contenido define el primer y más simple atributo de dependencia, valor del atributo de dependencia, metadatos del atributo contenedor de atributo de operación básica (PropertyMetadata)
Comportamiento básico de los metadatos de atributos
Aunque las palabras originales de MSDN son contundentes, no hay duda de su exactitud. Una vez que las comprenda, tendrá una experiencia diferente cuando las mire.
1. Defina el primer y más simple atributo de dependencia.
Palabras originales de MSDN: Windows Presentation Foundation (WPF) proporciona un conjunto de servicios que se pueden utilizar para ampliar la funcionalidad de las propiedades de Common Language Runtime (CLR). Estos servicios a menudo se denominan colectivamente sistema de propiedad WPF. Las propiedades admitidas por el sistema de propiedades de WPF se denominan propiedades de dependencia.
Definamos un atributo de dependencia de edad, de la siguiente manera:
clase pública DPCustomPeople
{
pública estática de solo lectura DependencyProperty AgeProperty =
DependencyProperty.Register("Edad", tipo de (int), tipo de (DPCustomPeople));
DisplayAgeProperty público vacío()
{
Console.WriteLine("DPName:" + DPCustomPeople.AgeProperty.Name);
Console.WriteLine("DPPropertyType:" + DPCustomPeople.AgeProperty.PropertyType);
Console.WriteLine("DPOWnerType:" + DPCustomPeople.AgeProperty.OwnerType);
}
}
Luego llame al resultado de salida.
programa de clase
{
vacío estático principal (cadena [] argumentos)
{
Personas DPCustomPeople = nuevo DPCustomPeople();
personas.DisplayAgeProperty();
}
}
Es posible que no esté familiarizado con la clase DependencyProperty. La clase DependencyProperty proporciona algunas características básicas de las propiedades de dependencia.
La forma de registrar una propiedad de dependencia es llamar al método de registro estático de DependencyProperty, que proporciona múltiples métodos sobrecargados, pero se requieren los siguientes tres pasos: una vez que se completa el registro, es una propiedad estática.
Proporcione el nombre registrado (Nombre) "Edad"
Registrar tipo de propiedad (PropertyType) tipo de (int)
Registre el tipo de propietario del atributo de dependencia (OwnerType) tipo de (DPCustomPeople)
Nota: El nombre del atributo, el tipo de atributo y el tipo de propietario del atributo no se pueden cambiar una vez registrado.
El siguiente es el resultado de salida.
2. Operaciones básicas de valores de atributos dependientes (adquisición y asignación de valores)
Después de definir la propiedad de dependencia Age, deberíamos poder realizar operaciones de adquisición y asignación de valores en la propiedad. DependencyProperty en sí no proporciona estas operaciones, pero es manejado por DependencyObject.
DependencyObject representa un objeto que participa en el sistema de propiedades de dependencia.
Por lo tanto, es necesario que la clase definida herede de DependencyObject y luego reescriba DPCustomPeople
clase pública DPCustomPeople:System.Windows.DependencyObject
{
}
Operaciones básicas de asignación de valor: métodos GetValue y SetValue
público vacío DPPropertyBasicOperator()
{
Console.WriteLine("Edad:" + this.GetValue(DPCustomPeople.AgeProperty));
this.SetValue(DPCustomPeople.AgeProperty, 24);
Console.WriteLine("ChangedAge:" + this.GetValue(DPCustomPeople.AgeProperty));
}
Resultados de salida
3. El contenedor de atributos utiliza los métodos GetValue y SetValue para operar con valores, por lo que podemos envolverlo y definir el atributo Age.
edad int pública
{
obtener {return (int)GetValue(AgeProperty);
establecer { SetValue(EdadProperty, valor });
}
Nota: La convención de nomenclatura para el empaquetado de propiedades dependientes es eliminar la siguiente propiedad
público vacío DPPropertyBasicOperatorUsingProperty()
{
Console.WriteLine("Edad:" + this.Edad);
esta.Edad=24;
Console.WriteLine("EdadCambiada:" + esta.Edad);
}
¿El código anterior parece más conciso?
4. Metadatos de propiedad (PropertyMetadata)
Original de MSDN: el sistema de propiedades de Windows Presentation Foundation (WPF) incluye un sistema de informes de metadatos que no se limita a lo que se puede informar sobre una propiedad a través de la reflexión o las funciones habituales de Common Language Runtime (CLR).
Hablando de metadatos de atributos, lo primero que me viene a la mente es el atributo de .net.
persona de clase pública
{
[Valor predeterminado(200),Categoría("Diseño")]
ancho int público {obtener; establecer}
}
Attribute necesita usar el poder de Visual Studio para hacer que el IDE sea compatible con Attribute, o confiar en la reflexión para asignar valores.
Pero sin estas tecnologías, new crea una nueva instancia a través de canales normales y agregar Atributos no tiene ningún efecto. No podemos confiar en estos Atributos para garantizar algunas características básicas de los atributos (como los valores predeterminados). atributos. Diferente de los metadatos descritos anteriormente.
Metadatos para propiedades de dependencia
Puede ser especificado de forma única por la clase en la que se define la propiedad de dependencia. Puede cambiarse cuando la propiedad de dependencia se agrega a otra clase. Puede ser anulado explícitamente por todas las clases derivadas que heredan la propiedad de dependencia de la clase base que la define. El lenguaje anterior es contundente. Pero explica la intención. Pero no siempre podemos entender los pensamientos del diseñador la primera vez. Conozcamos primero la existencia de este concepto.
5. Comportamiento básico de los metadatos de atributos El comportamiento básico de los metadatos de atributos proporciona tres funciones para los atributos dependientes. Este es también el tema que se acaba de plantear en este artículo.
Propiedad predeterminada notificación de propiedad propiedad devolución de llamada obligatoria Primero echemos un vistazo al constructor de un PropertyMetadata completo. Si el PropertyMetadata predeterminado no está configurado para la propiedad dependiente, se creará automáticamente un objeto PropertyMetadata internamente para la propiedad dependiente.
PropertyMetadata pública (objeto defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback)
Los atributos dependientes toman prestado el concepto de metadatos de atributos para completar valores predeterminados de atributos, notificaciones de atributos, devoluciones de llamadas forzadas y otros comportamientos.
1.Valor predeterminado del atributo
pública estática de solo lectura DependencyProperty NameProperty =
DependencyProperty.Register("Nombre", tipo de (cadena), tipo de (DPCustomPeople),
nueva PropiedadMetadata(cadena.Empty));
La mayoría de la gente tendrá una pregunta cuando vea esto. ¿Por qué utilizar PropertyMetadata para establecer un valor predeterminado? ¿Por qué no registrarlo directamente en el método de Registro?
pública estática de solo lectura DependencyProperty NameProperty =
DependencyProperty.Register("Nombre", tipo de (cadena), tipo de (DPCustomPeople),
cadena.Vacío);
Por supuesto, esta pregunta ha estado conmigo durante mucho tiempo y no hay nada que pueda hacer si no puedo resolverla, así que la dejaré así por ahora.
Nota: Al asignar un valor predeterminado a una propiedad en PropertyMetadata, no se puede detectar la corrección del tipo.
Esta definición, debido a que el valor predeterminado del segmento de código dp en vs es 0, esto es algo que vale la pena señalar.
pública estática de solo lectura DependencyProperty NameProperty =
DependencyProperty.Register("Nombre", tipo de (cadena), tipo de (DPCustomPeople),
nuevo UIPropertyMetadata(0));
2. Operación de restauración del valor predeterminado del atributo
Después de asignar un valor a la propiedad, puede restaurar el valor predeterminado mediante el método ClearValue de DependencyObject, como se muestra en el siguiente código.
Nombre de cadena pública
{
obtener {return (cadena)GetValue(NameProperty);
establecer { EstablecerValor(NombrePropiedad, valor });
}
pública estática de solo lectura DependencyProperty NameProperty =
DependencyProperty.Register("Nombre", tipo de (cadena), tipo de (DPCustomPeople),
nuevo UIPropertyMetadata(string.Empty));
vacío público DPPropertyClearOperator()
{
Console.WriteLine("Nombre:" + this.Name);
this.Name="Terry";
Console.WriteLine("NombreCambiado:" + this.Name);
this.ClearValue(NombreProperty);
Console.WriteLine("Nombre:" + this.Name);
}
Resultados de salida
Nota: Distinga entre asignación predeterminada y valor predeterminado
La asignación predeterminada generalmente se realiza en el constructor, pero este no es el valor predeterminado (esto era cierto antes de la llegada de las propiedades de dependencia), especialmente cuando las clases derivadas anulan las propiedades.
Estudiante de clase pública: DPCustomPeople
{
públicoEstudiante()
{
this.Name = "Cielo";
}
vacío público TestSubDefaultDpValue()
{
Console.WriteLine("Borrar antes:"+this.Name);
this.ClearValue(Estudiante.NombreProperty);
Console.WriteLine("Borrar después de:" + this.Name);
}
}
Resultados de salida
3.Notificación de cambios de propiedad
Esta función es la más utilizada. Cuando el valor de la propiedad cambia, se activa la devolución de llamada PropertyChangedCallback.
bool público IsBoy
{
obtener {return (bool)GetValue(IsBoyProperty);
establecer { SetValue(IsBoyProperty, valor });
}
pública estática de solo lectura DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", tipo de (bool), tipo de (Estudiante),
nuevo UIPropertyMetadata (falso, nuevo PropertyChangedCallback (IsBoyPropertyChangedCallback)));
vacío estático público IsBoyPropertyChangedCallback (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Estudiante st = d como Estudiante;
si (st.IsBoy)
{
Console.WriteLine("Hola, chico");
}
demás
{
Console.WriteLine ("Hola, niña");
}
}
TestPropertyChangedCallback público vacío ()
{
this.IsBoy = falso;
esto.IsBoy = verdadero; esto.IsBoy = verdadero;
}
Puede ver los resultados de salida del valor anterior y del valor nuevo a través de DependencyPropertyChangedEventArgs
Nota:
(1). A través de los resultados anteriores, ¿ha visto que el valor predeterminado de las propiedades dependientes no activará notificaciones de cambio de propiedad?
(2). Activar manualmente notificaciones de cambio de atributos.
Si desea que el valor predeterminado active un cambio de propiedad (de hecho, a veces es realmente necesario), no tiene que esperar y activarlo manualmente.
vacío privado RaiseIsBoyPropertyChangedCallback()
{
IsBoyPropertyChangedCallback (este, nuevo DependencyPropertyChangedEventArgs
(Estudiante.IsBoyProperty, Estudiante.IsBoyProperty.DefaultMetadata.DefaultValue, nulo));
}
(3). Cuando haya una notificación de cambio de atributo, asegúrese de garantizar la exactitud del tipo de valor predeterminado del atributo.
Sabemos que los tipos de valor tienen valores predeterminados, pero los tipos de referencia no (es decir, se pueden asignar a nulo) Se puede verificar si un tipo tiene un tipo predeterminado usando la palabra clave predeterminada como se muestra a continuación.
Reescribimos el valor predeterminado de la propiedad de dependencia definida anteriormente a nulo. Puede ejecutarse bien cuando no hay PropertyChangedCallback, pero cuando hay una notificación de cambio de propiedad, ocurre un desastre y el programa generará una excepción, diciendo que el tipo no. fósforo.
pública estática de solo lectura DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", tipo de (bool), tipo de (Estudiante),
nuevo UIPropertyMetadata (nulo, nuevo PropertyChangedCallback (IsBoyPropertyChangedCallback)));
Veamos nuevamente el tipo de referencia. Si el valor predeterminado es nulo, todo estará bien.
IList pública ChicaAmada
{
obtener {return (IList)GetValue(LovedGirlProperty);
establecer { SetValue(LovedGirlProperty, valor });
}
pública estática de solo lectura DependencyProperty LovedGirlProperty =
DependencyProperty.Register("LovedGirl", tipo de (ILista), tipo de (Estudiante),
nuevo UIPropertyMetadata (nulo, nuevo PropertyChangedCallback (LovedGirlChangedCallback)));
vacío estático público LovedGirlChangedCallback (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Estudiante st = d como Estudiante;
foreach (elemento var en e.NewValue como IList)
{
Consola.WriteLine(elemento);
}
}
TestReferenceDpType() vacío público
{
Lista<cadena> lista = nueva Lista<cadena>();
list.Add("niña 1");
list.Add("niña 2");
this.LovedGirl = lista;
}
4. Devolución de llamada de atributo forzada
En primer lugar, el valor predeterminado todavía no activa el método de devolución de llamada.
El método de devolución de llamada forzada significa que independientemente de si el valor del atributo cambia o no, se ingresará el método de devolución de llamada.
puntuación pública int
{
obtener {return (int)GetValue(ScoreProperty);
establecer { EstablecerValor(PuntuaciónPropiedad, valor });
}
pública estática de solo lectura DependencyProperty ScoreProperty =
DependencyProperty.Register("Puntuación", tipo de (int), tipo de (Estudiante),
nuevo UIPropertyMetadata (0, nulo, nuevo CoerceValueCallback (ScoreCoerceValueCallback)));
objeto estático público ScoreCoerceValueCallback (DependencyObject d, objeto baseValue)
{
Consola.WriteLine(baseValue);
devolver valorbase;
}
vacío público TestCoerceValueCallback()
{
esta puntuación = 0;
esta puntuación = 0;
esta.Puntuación = 0;
}