Compartilhar via


Propriedades de dependência somente leitura

Você pode usar propriedades de dependência somente leitura para impedir que os valores das propriedades sejam definidos externamente ao 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 public acessador. Por exemplo, a estrutura WPF (Windows Presentation Foundation) implementa a IsMouseOver propriedade como somente leitura porque seu valor só deve ser determinado pela entrada do mouse. Se IsMouseOver permitisse outras entradas, seu valor poderia se tornar inconsistente com a entrada do mouse. Embora não sejam configuráveis por meio de um public acessador, muitas propriedades de dependência somente leitura existentes têm valores determinados por várias entradas.

Usos de propriedades de dependência de somente leitura

As propriedades de dependência somente leitura não são aplicáveis em vários cenários em que 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 relata alterações nas propriedades de dependência somente leitura, dando suporte à funcionalidade de disparador 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, não o próprio objeto de coleção. Para obter mais informações, consulte Propriedades de dependência do tipo coleção.

Observação

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 personalizadas de somente leitura

Antes de criar uma propriedade dependente 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 escrita, com as seguintes distinções:

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

  • Ao implementar o wrapper de propriedade CLR, verifique se ele não tem um set acessador público.

  • 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 escolhida. A maneira recomendada de definir o valor da propriedade, seja inicialmente ou como parte da lógica de tempo de execução, é usar a sobrecarga de SetValue que aceita um parâmetro do tipo DependencyPropertyKey. O uso 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 private modificador de acesso. Para cenários em que os valores das propriedades de dependência afetam uns aos outros, você pode usar callbacks PropertyChangedCallback e CoerceValueCallback emparelhados para disparar alterações de valor. Para obter mais informações, consulte metadados da propriedade de dependência.

Se você precisar alterar o valor de uma propriedade de dependência somente leitura fora da classe que a registra, poderá usar um internal modificador de acesso para o DependencyPropertyKey. Por exemplo, você pode chamar SetValue de um manipulador de eventos na mesma assemblagem. O exemplo a seguir define uma classe Aquarium que chama RegisterReadOnly para criar a propriedade FishCount de dependência somente leitura. DependencyPropertyKey é atribuído a internal static readonly campo para 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 código externo, 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 de somente leitura quando quiser limitar o acesso de gravação àqueles que têm uma referência ao DependencyPropertyKey.

Por outro lado, o identificador de propriedade de dependência para propriedades de leitura/gravação é acessível por meio do sistema de propriedades, independentemente do modificador de acesso que você atribuir. Para obter mais informações, consulte segurança da propriedade de dependência.

Consulte também