Propriedades de dependência do WPF: Por que preciso especificar um tipo de proprietário?

StackOverflow https://stackoverflow.com/questions/868768

  •  22-08-2019
  •  | 
  •  

Pergunta

É assim que eu registro um DependencyProperty:

    public static readonly DependencyProperty UserProperty = 
        DependencyProperty.Register("User", typeof (User), 
             typeof (NewOnlineUserNotifier));                                                                                                                 


    public User User
    {
        get
        {
            return (User)GetValue(UserProperty);
        }
        set
        {
            SetValue(UserProperty, value);
        }
    }

O terceiro parâmetro do DependencyProperty.Register O método exige que você especifique o tipo de controle em que a propriedade de dependência reside (neste caso, meu controle do usuário é chamado NewOnlineUserNotifier).

Minha pergunta é, Por que você realmente especifica o tipo de proprietário e o que acontece se você especificar um tipo diferente do proprietário real?

Foi útil?

Solução

O tipo que você chama de método de registro não é o proprietário de fato da propriedade; portanto, você não pode especificar um tipo diferente do proprietário real, pois o tipo que você especifica é o proprietário real.

Um exemplo em que isso pode ser útil é quando você cria um controle personalizado que contém outros controles. Anteriormente, com o WinForms, se você tivesse algumas informações extras que eram úteis apenas para esse contêiner, mas pertenciam semanticamente à criança, o melhor que você poderia fazer era colocar essas informações na propriedade "tag" de retenção. Isso removeu a segurança do tipo e você nunca tinha certeza de que outra classe não tentaria armazenar outra coisa na tag. Agora, com as propriedades de dependência do WPF, permitem vincular valores a objetos sem que o próprio objeto precise manter o valor. Um exemplo trivial:

public class ButtonContainer : Control
{
    public Button ChildButton { get; set; }

    public static readonly DependencyProperty FirstOwnerProperty =
    DependencyProperty.Register("FirstOwner", typeof(ButtonContainer),
         typeof(Button));

    public ButtonContainer()
    {
        ChildButton = new Button();
        ChildButton.SetValue(FirstOwnerProperty, this);
    }

}

Agora, o botão possui uma propriedade extra que só faz sentido no contexto do ButtonContainer e só pode ser acessado no contexto do ButtonContainer - como uma tag TypeAfe e encapsulada.

Usando a nova classe da seguinte maneira:

ButtonContainer container1 = new ButtonContainer();

ButtonContainer container2 = new ButtonContainer();
container2.ChildButton = container1.ChildButton;

À medida que o parto é movido de um contêiner para outro, o valor de sua FirstOwnerProperty viaja com ele como se fosse um membro real da classe de botões. O contêiner2 pode ligar para o cherbutton.getValue (FirstOwnerProperty) e descobrir qual o ButtonContainer criou originalmente o botão (por que ele pode querer fazer isso é deixado como um exercício para o leitor ...). Tudo isso é possível sem a necessidade de subclasse o botão a uma especialidade estreita.

Outras dicas

Isso ocorre porque a mesma dependênciaProperty pode ser definida de maneira diferente (com diferentes metadados) para vários tipos

Em poucas palavras, quando você está registrando um DP, está adicionando um objeto (DP) a uma lista anexada a uma classe (proprietário). Esta operação apenas "vive" na classe onde é declarada e muitas vezes não está relacionada a ela.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top