Partilhar via


Propriedades de dependência somente leitura (WPF .NET)

Você pode usar propriedades de dependência somente leitura para impedir que os valores de propriedade sejam definidos de fora do código. Este artigo discute as propriedades de dependência somente leitura existentes e os cenários e técnicas para criar uma propriedade de dependência somente leitura personalizada.

Pré-requisitos

O artigo pressupõe um conhecimento básico das propriedades de dependência e que você leu visão geral das propriedades de dependência. Para seguir os exemplos neste artigo, ele ajuda se você estiver familiarizado com XAML (Extensible Application Markup Language) e saber como escrever aplicativos WPF.

Propriedades de dependência somente leitura existentes

As propriedades de dependência somente leitura normalmente relatam o estado e não devem ser modificáveis por meio de um acessador public. Por exemplo, a estrutura do Windows Presentation Foundation (WPF) implementa a propriedade IsMouseOver como somente leitura, pois seu valor só deve ser determinado pela entrada do mouse. Se IsMouseOver permitir outras entradas, seu valor poderá se tornar inconsistente com a entrada do mouse. Embora não possam ser configuradas por meio de um acessador public, muitas propriedades de dependência somente leitura existentes têm valores determinados por várias entradas.

Usos de propriedades de dependência somente leitura

As propriedades de dependência somente leitura não se aplicam a vários cenários nos quais as propriedades de dependência normalmente oferecem uma solução. Cenários não aplicáveis incluem associação de dados, aplicação de um estilo a um valor, validação, animação e herança. No entanto, uma propriedade de dependência somente leitura pode ser usada como um gatilho de propriedade em um estilo. Por exemplo, IsMouseOver geralmente é usado para disparar alterações na tela de fundo, em primeiro plano ou em outra propriedade visível de um controle quando o mouse está sobre ele. O sistema de propriedades do WPF detecta e informa alterações nas propriedades de dependência somente de leitura, dando suporte à funcionalidade de gatilho de propriedade. As propriedades de dependência somente leitura também são úteis ao implementar uma propriedade de dependência do tipo coleção, em que apenas os elementos da coleção precisam ser graváveis, mas não o objeto de coleção em si. Para obter mais informações, consulte propriedades de dependência do tipo 'coleção'.

Nota

Somente as propriedades de dependência, não as propriedades regulares do common language runtime, podem ser usadas como gatilhos de propriedade em um estilo.

Criando propriedades de dependência somente leitura personalizadas

Antes de criar uma propriedade de dependência somente leitura, verifique os cenários não aplicáveis .

O processo de criação de uma propriedade de dependência somente leitura é, em muitos aspectos, semelhante à criação de propriedades de dependência de leitura e gravação, com estas distinções:

  • Ao registrar sua propriedade somente leitura, chame RegisterReadOnly em vez de Register.

  • Certifique-se de que ao implementar o wrapper de propriedade CLR, ele não tenha um acessor público set.

  • RegisterReadOnly retorna DependencyPropertyKey em vez de DependencyProperty. Armazene o DependencyPropertyKey em um membro de classe não público.

Você pode determinar o valor da propriedade de dependência somente leitura usando qualquer lógica que você escolher. A maneira recomendada de definir o valor da propriedade, inicialmente ou como parte da lógica de runtime, é usar a sobrecarga de SetValue que aceita um parâmetro do tipo DependencyPropertyKey. Usar SetValue é preferível para contornar o sistema de propriedades e definir o campo de backup diretamente.

Como e onde você define o valor de uma propriedade de dependência somente leitura em seu aplicativo afetará o nível de acesso que você atribui ao membro da classe que armazena o DependencyPropertyKey. Se você definir apenas o valor da propriedade de dentro da classe que registra a propriedade de dependência, poderá usar um modificador de acesso private. Para cenários em que os valores das propriedades de dependência afetam uns aos outros, você pode usar callbacks emparelhados PropertyChangedCallback e CoerceValueCallback para disparar alterações de valor. Para obter mais informações, consulte metadados da propriedade de dependência.

Caso você precise alterar o valor de uma propriedade de dependência somente leitura de fora da classe que a registra, poderá usar um modificador de acesso internal para o DependencyPropertyKey. Por exemplo, você pode chamar SetValue de um manipulador de eventos no mesmo conjunto. O exemplo a seguir define uma Classe Aquarium que chama RegisterReadOnly para criar a propriedade de dependência somente de leitura FishCount. O DependencyPropertyKey é atribuído a um campo internal static readonly, de modo que o código no mesmo assembly possa alterar o valor da propriedade de dependência somente leitura.

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

Como o sistema de propriedades do WPF não propaga o DependencyPropertyKey fora do código, as propriedades de dependência somente leitura têm melhor segurança de gravação do que as propriedades de dependência de leitura/gravação. Use uma propriedade de dependência somente leitura quando você deseja limitar o acesso à escrita àqueles que têm uma referência ao DependencyPropertyKey.

Por outro lado, o identificador de propriedade de dependência para propriedades de dependência de leitura/gravação é acessível por meio do sistema de propriedades, não importa qual modificador de acesso você atribuí-lo. Para mais informações, consulte Segurança da propriedade de dependência.

Consulte também