Propiedades de dependencia de solo lectura (WPF .NET)

Puede usar propiedades de dependencia de solo lectura para evitar que los valores de propiedad se establezcan desde fuera del código. En este artículo se abordan las propiedades de dependencia de solo lectura existentes y los escenarios y técnicas para crear una propiedad de dependencia personalizada de solo lectura.

Requisitos previos

En el artículo se da por supuesto un conocimiento básico de las propiedades de dependencia y que ha leído Información general sobre las propiedades de dependencia. Para seguir los ejemplos de este artículo, resultará útil que esté familiarizado con el lenguaje XAML y sepa cómo escribir aplicaciones WPF.

Propiedades de dependencia de solo lectura existentes

Normalmente, las propiedades de dependencia de solo lectura notifican el estado y no deben modificarse a través de un descriptor de acceso public. Por ejemplo, el marco de Windows Presentation Foundation (WPF) implementa la propiedad IsMouseOver como de solo lectura porque su valor solo debe determinarse por la entrada del mouse. Si IsMouseOver permitiera otras entradas, su valor podría ser incoherente con la entrada del mouse. Aunque no se pueden establecer mediante un descriptor de acceso public, muchas propiedades de dependencia de solo lectura existentes tienen valores determinados por varias entradas.

Usos de las propiedades de dependencia de solo lectura existentes

Las propiedades de dependencia de solo lectura no son aplicables en varios escenarios en los que las propiedades de dependencia suelen ofrecer una solución. Entre los escenarios no aplicables se incluyen el enlace de datos, la aplicación de un estilo a un valor, la validación, la animación y la herencia. Sin embargo, una propiedad de dependencia de solo lectura se puede usar como desencadenador de propiedad en un estilo. Por ejemplo, IsMouseOver se usa normalmente para desencadenar cambios en el fondo, primer plano u otra propiedad visible de un control cuando el mouse está sobre él. El sistema de propiedades de WPF detecta e informa de los cambios en las propiedades de dependencia de solo lectura, lo que admite la funcionalidad de desencadenador de propiedades. Las propiedades de dependencia de solo lectura también son útiles al implementar una propiedad de dependencia de tipo de colección donde solo es necesario escribir los elementos de la colección, no el propio objeto colección. Para obtener más información, consulte Propiedades de dependencia de tipo colección.

Nota:

Solo las propiedades de dependencia, no las propiedades normales de Common Language Runtime, se pueden usar como desencadenadores de propiedades en un estilo.

Crear propiedades de dependencia de solo lectura

Antes de crear una propiedad de dependencia que sea de solo lectura, compruebe los escenarios no aplicables.

El proceso de creación de una propiedad de dependencia de solo lectura es de muchas maneras similar a la creación de propiedades de dependencia de lectura y escritura, con estas diferencias:

  • Al registrar la propiedad de solo lectura, llame a RegisterReadOnly en lugar de a Register.

  • Al implementar el contenedor de propiedades CLR, asegúrese de que no tiene un descriptor de acceso público set.

  • RegisterReadOnly devuelve DependencyPropertyKey en lugar de DependencyProperty. Almacene el DependencyPropertyKey en un miembro de clase no pública.

Puede determinar el valor de la propiedad de dependencia de solo lectura mediante la lógica que elija. La manera recomendada de establecer el valor de propiedad, ya sea inicialmente o como parte de la lógica en tiempo de ejecución, es usar la sobrecarga de SetValue que acepta un parámetro de tipo DependencyPropertyKey. El uso de SetValue es preferible a sortear el sistema de propiedades y establecer el campo de respaldo directamente.

Cómo y dónde se establece el valor de una propiedad de dependencia de solo lectura dentro de la aplicación afectará al nivel de acceso que asigne al miembro de clase que almacena el DependencyPropertyKey. Si solo establece el valor de propiedad desde dentro de la clase que registra la propiedad de dependencia, puede usar un modificador de acceso private. En escenarios en los que los valores de las propiedades de dependencia se afectan entre sí, puede usar devoluciones de llamada emparejadas PropertyChangedCallback y CoerceValueCallback para desencadenar cambios de valor. Para obtener más información, consulte Metadatos de propiedad de dependencia.

Si necesita cambiar el valor de una propiedad de dependencia de solo lectura desde fuera de la clase que la registra, puede usar un modificador de acceso internal para el DependencyPropertyKey. Por ejemplo, puede llamar a SetValue desde un controlador de eventos en el mismo ensamblado. En el ejemplo siguiente se define una clase Aquarium que llama a RegisterReadOnly para crear la propiedad de dependencia de solo lectura FishCount. El DependencyPropertyKey se asigna a un campo internal static readonly para que el código del mismo ensamblado pueda cambiar el valor de la propiedad de dependencia de solo lectura.

public class Aquarium : DependencyObject
{
    // Register a dependency property with the specified property name,
    // property type, owner type, and property metadata.
    // Assign DependencyPropertyKey to a nonpublic field.
    internal static readonly DependencyPropertyKey FishCountPropertyKey =
        DependencyProperty.RegisterReadOnly(
          name: "FishCount",
          propertyType: typeof(int),
          ownerType: typeof(Aquarium),
          typeMetadata: new FrameworkPropertyMetadata());

    // Declare a public get accessor.
    public int FishCount =>
        (int)GetValue(FishCountPropertyKey.DependencyProperty);
}
Public Class Aquarium
    Inherits DependencyObject

    ' Register a dependency property with the specified property name,
    ' property type, owner type, And property metadata.
    ' Assign DependencyPropertyKey to a nonpublic field.
    Friend Shared ReadOnly FishCountPropertyKey As DependencyPropertyKey =
        DependencyProperty.RegisterReadOnly(
            name:="FishCount",
            propertyType:=GetType(Integer),
            ownerType:=GetType(Aquarium),
            typeMetadata:=New FrameworkPropertyMetadata())

    ' Declare a public get accessor.
    Public ReadOnly Property FishCount As Integer
        Get
            Return GetValue(FishCountPropertyKey.DependencyProperty)
        End Get
    End Property

End Class

Dado que el sistema de propiedades de WPF no propaga el DependencyPropertyKey fuera del código, las propiedades de dependencia de solo lectura tiene más seguridad de escritura que las propiedades de dependencia de lectura y escritura. Use una propiedad de dependencia de solo lectura cuando desee limitar el acceso de escritura a las que tienen una referencia al DependencyPropertyKey.

En cambio, el identificador de propiedad de dependencia para las propiedades de dependencia de lectura y escritura es accesible a través del sistema de propiedades, independientemente del modificador de acceso que asigne. Para obtener más información, consulte Seguridad de las propiedades de dependencia.

Vea también