O valor padrão do atributo pode garantir a validade do atributo.
A validade de verificação de atributos pode ser utilizada para verificar os atributos de entrada e os retornos de chamada obrigatórios dos atributos, ou seja, as notificações devem ser feitas independentemente de os atributos terem sido alterados ou não.
Notificação de mudança de atributo, quando um atributo muda, o programa pode ser notificado para realizar uma série de processos.
Não há nada de errado com o WPF aqui, vamos ver como as propriedades de dependência resolvem os problemas acima.
O resumo do conteúdo define o primeiro e mais simples atributo de dependência valor do atributo de dependência operação básica atributo metadados do atributo wrapper (PropertyMetadata)
Atribuir comportamento básico de metadados
Embora as palavras originais do MSDN sejam contundentes, não há dúvidas sobre sua precisão. Depois de entendê-las, você terá uma experiência diferente ao observá-las.
1. Defina o primeiro e mais simples atributo de dependência
Palavras originais do MSDN: Windows Presentation Foundation (WPF) fornece um conjunto de serviços que podem ser usados para estender a funcionalidade das propriedades do Common Language Runtime (CLR). Esses serviços são frequentemente chamados coletivamente de sistema de propriedades WPF. As propriedades suportadas pelo sistema de propriedades WPF são chamadas de propriedades de dependência.
Vamos definir um atributo de dependência Idade, da seguinte forma:
classe pública DPCustomPeople
{
público estático somente leitura DependencyProperty AgeProperty =
DependencyProperty.Register("Idade", typeof(int), typeof(DPCustomPeople));
public void DisplayAgeProperty()
{
Console.WriteLine("DPNome:" + DPCustomPeople.AgeProperty.Name);
Console.WriteLine("DPPropertyType:" + DPCustomPeople.AgeProperty.PropertyType);
Console.WriteLine("DPOWNerType:" + DPCustomPeople.AgeProperty.OwnerType);
}
}
Em seguida, chame o resultado de saída
programa de aula
{
vazio estático principal(string[] args)
{
DPCustomPeople pessoas = new DPCustomPeople();
people.DisplayAgeProperty();
}
}
Você pode não estar familiarizado com a classe DependencyProperty. A classe DependencyProperty fornece algumas características básicas das propriedades de dependência.
A maneira de registrar uma propriedade de dependência é chamar o método estático Register de DependencyProperty, que fornece vários métodos sobrecarregados, mas as três etapas a seguir são necessárias. Depois que o registro for concluído, é uma propriedade estática.
Forneça o nome cadastrado (Nome) “Idade”
Registrar tipo de propriedade (PropertyType) typeof (int)
Registre o tipo de proprietário do atributo de dependência (OwnerType) typeof (DPCustomPeople)
Nota: O nome do atributo, o tipo de atributo e o tipo de proprietário do atributo não podem ser alterados depois de registrados.
A seguir está o resultado de saída
2. Operações básicas de valores de atributos dependentes (aquisição e atribuição de valor)
Depois de definir a propriedade de dependência Age, deveremos ser capazes de realizar operações de aquisição e atribuição de valor na própria propriedade DependencyProperty não fornece essas operações, mas é tratada por DependencyObject.
DependencyObject representa um objeto que participa do sistema de propriedades de dependência.
Portanto, é necessário que a classe definida herde de DependencyObject e, em seguida, reescreva DPCustomPeople
classe pública DPCustomPeople:System.Windows.DependencyObject
{
}
Operações básicas de atribuição de valor Métodos GetValue e SetValue
público vazio DPPropertyBasicOperator()
{
Console.WriteLine("Idade:" + this.GetValue(DPCustomPeople.AgeProperty));
this.SetValue(DPCustomPeople.AgeProperty, 24);
Console.WriteLine("ChangedAge:" + this.GetValue(DPCustomPeople.AgeProperty));
}
Resultados de saída
3. O wrapper de atributo usa os métodos GetValue e SetValue para operar em valores, para que possamos envolvê-lo e definir o atributo Age.
público int Idade
{
obter { return (int)GetValue(AgeProperty });
definir {SetValue(IdadePropriedade, valor });
}
Nota: A convenção de nomenclatura para empacotamento de propriedades dependentes é remover o seguinte Property
public void DPPropertyBasicOperatorUsingProperty()
{
Console.WriteLine("Idade:" + this.Idade);
esta.Idade=24;
Console.WriteLine("ChangedAge:" + this.Idade);
}
O código acima parece mais conciso?
4. Metadados de propriedade (PropertyMetadata)
Original do MSDN: O sistema de propriedades do Windows Presentation Foundation (WPF) inclui um sistema de relatório de metadados que não se limita ao que pode ser relatado sobre uma propriedade por meio de reflexão ou recursos regulares do Common Language Runtime (CLR).
Falando em metadados de atributos, a primeira coisa que vem à mente é o Atributo do .net
classe pública Pessoa
{
[Valor Padrão(200),Categoria("Layout")]
public int Largura {obter;
}
O atributo precisa usar o poder do Visual Studio para tornar o suporte amigável do IDE para o atributo ou contar com a reflexão para atribuir valores.
Mas sem essas tecnologias, new cria uma nova instância por meio de canais normais, e adicionar atributos não tem efeito. Não podemos confiar nesses atributos para garantir algumas características básicas dos atributos (como valores padrão). atributos Diferentes dos metadados descritos acima.
Metadados para propriedades de dependência
Pode ser especificado exclusivamente pela classe na qual a propriedade de dependência está definida Pode ser alterado quando a propriedade de dependência é adicionada a outra classe Pode ser explicitamente substituído por todas as classes derivadas que herdam a propriedade de dependência da classe base definidora A linguagem acima é direta, mas Mas isso explica a intenção Mas nem sempre conseguimos entender o pensamento do designer na primeira vez. Vamos primeiro saber a existência desse conceito.
5. Comportamento básico dos metadados de atributos O comportamento básico dos metadados de atributos fornece três funções para atributos dependentes. Esta também é a questão levantada neste artigo.
Propriedade padrão propriedade notificação propriedade retorno de chamada obrigatório Vamos primeiro dar uma olhada no construtor de um PropertyMetadata completo. Se o PropertyMetadata padrão não estiver definido para a propriedade dependente, um objeto PropertyMetadata será criado automaticamente internamente para a propriedade dependente.
PropertyMetadata público (objeto defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback)
Atributos dependentes emprestam o conceito de metadados de atributos para completar valores padrão de atributos, notificações de atributos, retornos de chamada forçados e outros comportamentos
1. Valor padrão do atributo
público estático somente leitura DependencyProperty NameProperty =
DependencyProperty.Register("Nome", typeof(string), typeof(DPCustomPeople),
novo PropertyMetadata(string.Empty));
A maioria das pessoas terá uma dúvida ao ver isso. Por que usar PropertyMetadata para definir um valor padrão? Por que não registrá-lo diretamente no método Register?
público estático somente leitura DependencyProperty NameProperty =
DependencyProperty.Register("Nome", typeof(string), typeof(DPCustomPeople),
string.Vazio);
Claro, essa questão está comigo há muito tempo e não há nada que eu possa fazer se não conseguir resolvê-la, então vou deixá-la de lado por enquanto.
Nota: Ao atribuir um valor padrão a uma propriedade em PropertyMetadata, a correção do tipo não pode ser detectada.
Tal definição, porque o valor padrão do segmento de código dp em vs é 0, isso é algo digno de nota
público estático somente leitura DependencyProperty NameProperty =
DependencyProperty.Register("Nome", typeof(string), typeof(DPCustomPeople),
novo UIPropertyMetadata(0));
2. Operação de restauração do valor padrão do atributo
Depois que um valor for atribuído à propriedade, você poderá restaurar o valor padrão por meio do método ClearValue de DependencyObject, conforme mostrado no código a seguir
nome da string pública
{
obter { return (string)GetValue(NomePropriedade });
definir {SetValue(NomePropriedade, valor});
}
público estático somente leitura DependencyProperty NameProperty =
DependencyProperty.Register("Nome", typeof(string), typeof(DPCustomPeople),
novo UIPropertyMetadata(string.Empty));
público vazio DPPropertyClearOperator()
{
Console.WriteLine("Nome:" + this.Nome);
this.Name="Terry";
Console.WriteLine("NomeAlterado:" + this.Nome);
this.ClearValue(NomePropriedade);
Console.WriteLine("Nome:" + this.Nome);
}
Resultados de saída
Nota: Distinguir entre atribuição padrão e valor padrão
A atribuição padrão geralmente é feita no construtor, mas esse não é o valor padrão (isso era verdade antes do advento das propriedades de dependência), especialmente quando as classes derivadas substituem as propriedades.
Aluno de classe pública: DPCustomPeople
{
estudante público()
{
this.Name = "Céu";
}
público vazio TestSubDefaultDpValue()
{
Console.WriteLine("Limpar Antes:"+this.Name);
this.ClearValue(Student.NameProperty);
Console.WriteLine("Limpar Depois:" + this.Name);
}
}
Resultados de saída
3.Notificação de alterações de propriedade
Esta função é a mais comumente usada. Quando o valor da propriedade é alterado, o retorno de chamada PropertyChangedCallback é acionado.
bool público IsBoy
{
obter { return (bool)GetValue(IsBoyProperty });
definir {SetValue(IsBoyProperty, valor});
}
público estático somente leitura DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Aluno),
novo UIPropertyMetadata(false,new PropertyChangedCallback(IsBoyPropertyChangedCallback)));
public static void IsBoyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Aluno st = d como Aluno;
se (st.IsBoy)
{
Console.WriteLine("Olá, garoto");
}
outro
{
Console.WriteLine("Olá,Garota");
}
}
público vazio TestPropertyChangedCallback()
{
this.IsBoy = falso;
isto.IsBoy = verdadeiro; isto.IsBoy = verdadeiro;
}
Você pode visualizar o valor antigo e os resultados de saída do novo valor por meio de DependencyPropertyChangedEventArgs
Observação:
(1). Através dos resultados de saída acima, você viu que o valor padrão das propriedades dependentes não acionará notificações de alteração de propriedade?
(2). Acionar manualmente notificações de alteração de atributos.
Se você deseja que o valor padrão acione uma alteração de propriedade (na verdade, às vezes é realmente necessário), não é necessário esperar e acioná-lo manualmente.
privado vazio RaiseIsBoyPropertyChangedCallback()
{
IsBoyPropertyChangedCallback(este, novo DependencyPropertyChangedEventArgs
(Student.IsBoyProperty, Student.IsBoyProperty.DefaultMetadata.DefaultValue, null));
}
(3). Quando houver uma notificação de alteração de atributo, certifique-se de garantir a exatidão do tipo de valor padrão do atributo.
Sabemos que os tipos de valor têm valores padrão, mas os tipos de referência não (ou seja, eles podem ser atribuídos a nulo). Se um tipo tem um tipo padrão, pode ser verificado usando a palavra-chave padrão, conforme mostrado abaixo.
Reescrevemos o valor padrão da propriedade de dependência definida acima para nulo. Ele pode funcionar bem quando não há PropertyChangedCallback, mas quando há uma notificação de alteração de propriedade, ocorre um desastre e o programa lançará uma exceção, dizendo que o tipo não. corresponder.
público estático somente leitura DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Aluno),
novo UIPropertyMetadata(null,new PropertyChangedCallback(IsBoyPropertyChangedCallback)));
Vejamos o tipo de referência novamente. Se o valor padrão for nulo, tudo ficará bem.
IList pública LovedGirl
{
obter { return (IList)GetValue(LovedGirlProperty);
definir {SetValue(LovedGirlProperty, valor});
}
público estático somente leitura DependencyProperty LovedGirlProperty =
DependencyProperty.Register("LovedGirl", typeof(IList), typeof(Student),
novo UIPropertyMetadata(nulo, novo PropertyChangedCallback(LovedGirlChangedCallback)));
public static void LovedGirlChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Aluno st = d como Aluno;
foreach (var item em e.NewValue como IList)
{
Console.WriteLine(item);
}
}
público vazio TestReferenceDpType()
{
Lista<string> lista = new Lista<string>();
list.Add("menina 1");
list.Add("menina 2");
this.LovedGirl = lista;
}
4. Retorno de chamada de atributo forçado
Primeiro de tudo, o valor padrão ainda não aciona o método de retorno de chamada.
O método de retorno de chamada forçado significa que, independentemente de o valor do atributo ser alterado ou não, o método de retorno de chamada será inserido.
Pontuação interna pública
{
obter { return (int)GetValue(ScoreProperty });
definir { SetValue(ScoreProperty, valor });
}
público estático somente leitura DependencyProperty ScoreProperty =
DependencyProperty.Register("Pontuação", typeof(int), typeof(Aluno),
novo UIPropertyMetadata(0,null,new CoerceValueCallback(ScoreCoerceValueCallback)));
objeto estático público ScoreCoerceValueCallback (DependencyObject d, objeto baseValue)
{
Console.WriteLine(baseValue);
return valorbase;
}
público vazio TestCoerceValueCallback()
{
esta.Pontuação = 0;
esta.Pontuação = 0;
esta.Pontuação = 0;
}