Compartilhar via


Conceitos e estruturas de fluxo de nó XAML

Leitores XAML e gravadores XAML, conforme implementado nos Serviços XAML do .NET, baseiam-se no conceito de design de um fluxo de nós XAML. O fluxo de nós XAML é uma conceitualização de um conjunto de nós XAML. Nessa conceitualização, um processador XAML percorre a estrutura das relações de nó no XAML uma de cada vez. A qualquer momento, apenas um registro atual ou posição atual existe em um fluxo de nó XAML aberto, e muitos aspectos da API relatam apenas as informações disponíveis nessa posição. O nó atual em um fluxo de nó XAML pode ser descrito como sendo um objeto, um membro ou um valor. Ao tratar o XAML como um fluxo de nó XAML, os leitores XAML podem se comunicar com gravadores XAML e habilitar um programa para exibir, interagir ou alterar o conteúdo de um fluxo de nó XAML durante um caminho de carga ou uma operação de salvar caminho que envolve XAML. O design da API de leitor e gravador XAML e o conceito de fluxo de nó XAML são semelhantes aos designs e conceitos de leitor e gravador relacionados anteriores, como o DOM (Modelo de Objeto de Documento XML) e as classes XmlReader e XmlWriter. Este tópico discute os conceitos de fluxo de nós XAML e descreve como você pode escrever rotinas que interagem com representações XAML no nível do nó XAML.

Carregando XAML em um leitor de XAML

A classe XamlReader base não declara uma técnica específica para carregar o XAML inicial em um leitor XAML. Em vez disso, uma classe derivada declara e implementa a técnica de carregamento, incluindo as características gerais e restrições de sua fonte de entrada para XAML. Por exemplo, um XamlObjectReader lê um grafo de objeto, começando pela fonte de entrada de um único objeto que representa a raiz ou a base. O XamlObjectReader produz um fluxo de nó XAML do grafo de objeto.

A subclasse de XamlReader definida pelos Serviços XAML do .NET mais proeminente é XamlXmlReader. XamlXmlReader carrega o XAML inicial, carregando um arquivo de texto diretamente por meio de um fluxo ou caminho de arquivo, ou indiretamente por meio de uma classe de leitor relacionada, como TextReader. A XamlReader pode ser considerada como contendo a totalidade da fonte de entrada XAML depois de carregada. No entanto, a API base XamlReader foi projetada para que o leitor interaja com um único nó do XAML. Quando carregado pela primeira vez, o primeiro nó único encontrado é a raiz do XAML e seu objeto inicial.

O conceito de fluxo de nó XAML

Se você estiver mais familiarizado com um DOM, uma metáfora de árvore ou uma abordagem baseada em consulta para acessar tecnologias baseadas em XML, uma maneira útil de conceituar um fluxo de nós XAML é a seguinte. Imagine que o XAML carregado é um DOM ou uma árvore em que todos os nós possíveis são expandidos até o fim e, em seguida, apresentados linearmente. À medida que você avança pelos nós, você pode estar atravessando "dentro" ou "fora" de níveis que seriam relevantes para um DOM, mas o fluxo de nós XAML não acompanha explicitamente porque esses conceitos de nível não são relevantes para um fluxo de nó. O fluxo de nós tem uma posição "atual", mas, a menos que você tenha armazenado outras partes do fluxo por conta própria como referências, todos os aspectos do fluxo de nós que não sejam a posição atual do nó estão fora de exibição.

O conceito de fluxo de nó XAML tem a vantagem notável de que, se você passar por todo o fluxo de nós, terá certeza de que processou toda a representação XAML; você não precisa se preocupar que uma consulta, uma operação DOM ou alguma outra abordagem não linear para informações de processamento tenha perdido alguma parte da representação XAML completa. Por esse motivo, a representação de fluxo de nó XAML é ideal tanto para conectar leitores XAML quanto gravadores XAML e para fornecer um sistema em que você pode inserir seu próprio processo que atua entre as fases de leitura e gravação de uma operação de processamento XAML. Em muitos casos, a ordenação de nós no fluxo de nós XAML é deliberadamente otimizada ou reordenada por leitores XAML versus como a ordem pode aparecer no texto de origem, binário ou grafo de objeto. Esse comportamento destina-se a impor uma arquitetura de processamento XAML pela qual os gravadores XAML nunca estão em uma posição em que eles precisam "voltar" no fluxo de nós. Idealmente, todas as operações de gravação XAML devem ser capazes de agir com base no contexto do esquema, além da posição atual do fluxo de nós.

Um loop de nó de leitura básico

Um loop de nó de leitura básico para examinar um fluxo de nó XAML consiste nos conceitos a seguir. Para fins de loops de nó, conforme discutido neste tópico, suponha que você esteja lendo um arquivo XAML baseado em texto e legível por humanos usando XamlXmlReader. Os links nesta seção referem-se à API de loop de nó XAML específica implementada pelo XamlXmlReader.

  • Verifique se você não está no final do fluxo de nó XAML (verifique IsEofou use o valor retornado Read). Se você estiver no final do fluxo, não haverá nenhum nó atual e você deverá sair.

  • Verifique que tipo de nó o fluxo de nós XAML expõe atualmente chamando NodeType.

  • Se você tiver um gravador de objeto XAML associado conectado diretamente, você geralmente chamará WriteNode neste momento.

  • Com base em qual XamlNodeType é relatado como o nó atual ou o registro atual, chame um dos seguintes para obter informações sobre o conteúdo do nó:

    • Para obter uma NodeType de StartMember ou EndMember, chame Member para obter informações XamlMember sobre um membro. O membro pode ser um XamlDirectivee, portanto, pode não ser necessariamente um membro convencional definido pelo tipo do objeto anterior. Por exemplo, x:Name aplicado a um objeto aparece como um membro XAML em que IsDirective é verdadeiro e o Name do membro é Name, com outras propriedades indicando que essa diretiva está no namespace XAML da linguagem XAML.

    • Para obter um NodeType de StartObject ou EndObject, chame Type para obter informações XamlType sobre um objeto.

    • Para um NodeType de Value, chame Value. Um nó é um valor somente se for a expressão mais simples de um valor para um membro ou o texto de inicialização de um objeto (no entanto, você deve estar ciente do comportamento de conversão de tipo, conforme documentado em uma próxima seção deste tópico).

    • Para um NodeType de NamespaceDeclaration, chame Namespace para obter informações de namespace para um nó de namespace.

  • Chame Read para avançar o leitor XAML para o próximo nó no fluxo de nó XAML e repita as etapas novamente.

O fluxo de nós XAML fornecido pelos leitores XAML dos Serviços XAML do .NET sempre fornece uma passagem completa e profunda de todos os nós possíveis. As técnicas típicas de controle de fluxo para um loop de nó XAML incluem definir um corpo dentro de while (reader.Read())e ativar NodeType em cada ponto do nó no loop do nó.

Se o fluxo do nó estiver no final do arquivo, o nó atual será nulo.

O loop mais simples que usa um leitor e um gravador se assemelha ao exemplo a seguir.

XamlXmlReader xxr = new XamlXmlReader(new StringReader(xamlStringToLoad));
//where xamlStringToLoad is a string of well formed XAML
XamlObjectWriter xow = new XamlObjectWriter(xxr.SchemaContext);
while (xxr.Read()) {
  xow.WriteNode(xxr);
}

Este exemplo básico de um loop de nó XAML de caminho de carga conecta de forma transparente o leitor XAML e o gravador XAML, não fazendo nada diferente do que se você tivesse usado XamlServices.Parse. Mas essa estrutura básica é então expandida para se aplicar ao seu cenário de leitura ou gravação. Alguns cenários possíveis são os seguintes:

  • Ativar NodeType. Execute ações diferentes dependendo de qual tipo de nó está sendo lido.

  • Não chame WriteNode em todos os casos. Chame apenas WriteNode em alguns casos NodeType.

  • Dentro da lógica de um tipo de nó específico, analise as especificidades desse nó e aja sobre eles. Por exemplo, você só poderia escrever objetos provenientes de um namespace XAML específico e, em seguida, remover ou adiar quaisquer objetos que não sejam desse namespace XAML. Ou você pode descartar ou reprocessar as diretivas XAML que seu sistema XAML não dá suporte como parte do processamento de membro.

  • Defina um XamlObjectWriter personalizado que substitui métodos Write*, possivelmente executando mapeamento de tipo que ignora o contexto do esquema XAML.

  • Construa o XamlXmlReader para usar um contexto de esquema XAML não padrão, de modo que diferenças personalizadas no comportamento XAML sejam usadas tanto pelo leitor quanto pelo gravador.

Acessando xaml além do conceito de loop de nó

Há potencialmente outras maneiras de trabalhar com uma representação XAML diferente de um loop de nó XAML. Por exemplo, pode haver um leitor XAML que pode ler um nó indexado ou, em particular, acessa nós diretamente por x:Name, por x:Uidou por meio de outros identificadores. Os Serviços XAML do .NET não fornecem uma implementação completa, mas fornecem um padrão sugerido por meio de serviços e tipos de suporte. Para obter mais informações, consulte IXamlIndexingReader e XamlNodeList.

Trabalhando com o nó atual

A maioria dos cenários que usam um loop de nó XAML não lê apenas os nós. A maioria dos cenários processa os nós atuais e passa cada nó um de cada vez para uma implementação de XamlWriter.

No cenário típico do caminho de carga, um XamlXmlReader produz um fluxo de nó XAML; os nós XAML são processados de acordo com sua lógica e contexto de esquema XAML; e os nós são passados para um XamlObjectWriter. Em seguida, integre o grafo de objeto resultante ao seu aplicativo ou estrutura.

Em um cenário de caminho de salvamento típico, um XamlObjectReader lê o grafo do objeto, nós XAML individuais são processados e um XamlXmlWriter gera o resultado serializado como um arquivo de texto XAML. A chave é que os caminhos e cenários envolvem trabalhar com exatamente um nó XAML de cada vez, e os nós XAML estão disponíveis para tratamento de forma padronizada definida pelo sistema de tipos XAML e the.NET APIs dos Serviços XAML.

Quadros e Escopo

Um loop de nó XAML percorre um fluxo de nó XAML de maneira linear. O fluxo de nós atravessa objetos, para membros que contêm outros objetos e assim por diante. Geralmente, é útil manter o controle do escopo dentro do fluxo de nós XAML implementando um conceito de quadro e pilha. Isso é particularmente verdadeiro se você estiver ajustando ativamente o fluxo de nós enquanto estiver nele. O suporte de quadro e pilha que você implementa como parte da lógica de loop de nó pode contar StartObject (ou GetObject) e EndObject escopos conforme você desce para uma estrutura de nó XAML se a estrutura for pensada de uma perspectiva do DOM.

Atravessando e inserindo nós de objeto

O primeiro nó em um fluxo de nó quando ele é aberto por um leitor XAML é o nó de objeto inicial do objeto raiz. Por definição, esse objeto é sempre um único nó de objeto e não tem pares. Em qualquer exemplo XAML do mundo real, o objeto raiz é definido para ter uma ou mais propriedades que contêm mais objetos e essas propriedades têm nós membros. Em seguida, os nós membros têm um ou mais nós de objeto ou também podem terminar em um nó de valor. O objeto raiz normalmente define namescopes XAML, que são atribuídos sintaticamente como atributos na marcação de texto XAML, mas mapeiam para um tipo de nó Namescope na representação de fluxo de nó XAML.

Considere o exemplo XAML a seguir (isso é XAML arbitrário, não apoiado por tipos existentes no .NET). Suponha que neste modelo de objeto, FavorCollection é List<T> de Favor, Balloon e NoiseMaker são atribuíveis a Favor, a propriedade Balloon.Color é apoiada por um objeto Color semelhante à forma como o WPF define cores como nomes de cores conhecidos e Color dá suporte a um conversor de tipo para sintaxe de atributo.

Marcação XAML Fluxo de nó XAML resultante
<Party Namespace nó para Party
xmlns="PartyXamlNamespace"> StartObject nó para Party
<Party.Favors> StartMember nó para Party.Favors
StartObject nó para FavorCollection implícito
StartMember nó para a propriedade de itens de FavorCollection implícito.
<Balloon StartObject nó para Balloon
Color="Red" StartMember nó para Color

Value nó para a cadeia de caracteres de valor de atributo "Red"

EndMember para Color
HasHelium="True" StartMember nó para HasHelium

Value nó para a cadeia de caracteres de valor de atributo "True"

EndMember para HasHelium
> EndObject para Balloon
<NoiseMaker>Loudest</NoiseMaker> StartObject nó para NoiseMaker

StartMember nó para _Initialization

Value nó para a cadeia de caracteres de valor de inicialização "Loudest"

EndMember nó para _Initialization

EndObject para NoiseMaker
EndMember nó para a propriedade de itens de FavorCollection implícito.
EndObject nó para FavorCollection implícito
</Party.Favors> EndMember para Favors
</Party> EndObject para Party

No fluxo de nós XAML, você pode contar com o seguinte comportamento:

  • Se houver um nó Namespace, ele será adicionado ao fluxo imediatamente antes do StartObject que declarou o namespace XAML com xmlns. Examine a tabela anterior com o XAML e o fluxo de nós de exemplo novamente. Observe como os nós StartObject e Namespace parecem ser transpostos versus suas posições de declaração na marcação de texto. Isso representa o comportamento em que os nós de namespace sempre aparecem antes do nó ao qual se aplicam no fluxo de nós. A finalidade desse design é que as informações do namespace são vitais para os gravadores de objetos e devem ser conhecidas antes que o gravador de objetos tente executar o mapeamento de tipo ou processar o objeto de outra forma. Colocar as informações do namespace XAML à frente de seu escopo de aplicativo no fluxo torna mais simples processar sempre o fluxo de nós em sua ordem apresentada.

  • Devido à consideração acima, é um ou mais nós Namespace que você lê primeiro na maioria dos casos de marcação do mundo real ao atravessar nós desde o início, não o StartObject da raiz.

  • Um nó StartObject pode ser seguido por StartMember, Valueou um EndObjectimediato. Ele nunca é seguido imediatamente por outro StartObject.

  • Um StartMember pode ser seguido por um StartObject, Valueou um EndMemberimediato. Ele pode ser seguido por GetObject, para membros em que o valor deve vir de um valor existente do objeto pai, em vez de um StartObject que instanciaria um novo valor. Ele também pode ser seguido por um nó Namespace, que se aplica a um próximo StartObject. Ele nunca é seguido imediatamente por outro StartMember.

  • Um nó Value representa o valor em si; não há nenhum "EndValue". Ele só pode ser seguido por um EndMember.

    • O texto de inicialização XAML do objeto como pode ser usado pela construção não resulta em uma estrutura Object-Value. Em vez disso, um nó de membro dedicado para um membro chamado _Initialization é criado. e esse nó de membro contém a cadeia de caracteres de valor de inicialização. Se existir, _Initialization sempre será o primeiro StartMember. _Initialization pode ser qualificado em algumas representações de serviços XAML com o namescope XAML da linguagem XAML, para esclarecer que _Initialization não é uma propriedade definida em tipos de backup.

    • Uma combinação de Member-Value representa uma configuração de atributo do valor. Eventualmente, pode haver um conversor de valor envolvido no processamento desse valor e o valor é uma cadeia de caracteres simples. No entanto, isso não será avaliado até que um gravador de objetos XAML processe esse fluxo de nós. O gravador de objetos XAML possui o contexto de esquema XAML necessário, o mapeamento do sistema de tipos e outros suportes necessários para conversões de valor.

  • Um nó EndMember pode ser seguido por um nó StartMember para um membro subsequente ou por um nó EndObject para o proprietário do membro.

  • Um nó EndObject pode ser seguido por um nó EndMember. Ele também pode ser seguido por um nó StartObject para casos em que os objetos são pares nos itens de uma coleção. Ou pode ser seguido por um nó Namespace, que se aplica a um próximo StartObject.

    • Para o caso exclusivo de fechamento do fluxo de nó inteiro, o EndObject da raiz não é seguido por nada; o leitor agora é o fim do arquivo e Read retorna false.

Conversores de valor e o fluxo de nós XAML

Um conversor de valor é um termo geral para uma extensão de marcação, um conversor de tipo (incluindo serializadores de valor) ou outra classe dedicada que é relatada como um conversor de valor por meio do sistema de tipos XAML. No fluxo de nós XAML, um uso de conversor de tipo e um uso de extensão de marcação têm representações muito diferentes.

Conversores de tipo no fluxo de nó XAML

Um conjunto de atributos que eventualmente resulta em um uso de conversor de tipo é relatado no fluxo de nós XAML como um valor de um membro. O fluxo de nó XAML não tenta produzir um objeto de instância do conversor de tipo e passa o valor para ele. Usar a implementação de conversão de um conversor de tipo requer invocar o contexto do esquema XAML e usá-lo para mapeamento de tipo. Até mesmo determinar qual classe de conversor de tipo deve ser usada para processar o valor requer o contexto de esquema XAML indiretamente. Quando você usa o contexto de esquema XAML padrão, essas informações estão disponíveis no sistema de tipos XAML. Se você precisar das informações de classe do conversor de tipo no nível de fluxo do nó XAML antes da conexão com um gravador XAML, poderá obtê-la das informações de XamlMember do membro que está sendo definido. Mas, caso contrário, a entrada do conversor de tipo deve ser preservada no fluxo de nó XAML como um valor simples até que o restante das operações que exigem o sistema de mapeamento de tipo e o contexto de esquema XAML sejam executados, por exemplo, a criação de objeto por um gravador de objeto XAML.

Por exemplo, considere a seguinte estrutura de tópicos de definição de classe e o uso de XAML para ela:

public class BoardSizeConverter : TypeConverter {
  //converts from string to an int[2] by splitting on an "x" char
}
public class GameBoard {
  [TypeConverter(typeof(BoardSizeConverter))]
  public int[] BoardSize; //2x2 array, initialization not shown
}
<GameBoard BoardSize="8x8"/>

Uma representação de texto do fluxo de nós XAML para esse uso pode ser expressa como o seguinte:

StartObject com XamlType representando GameBoard

StartMember com XamlMember representando BoardSize

Value nó, com a cadeia de caracteres de texto "8x8"

EndMember correspondências BoardSize

EndObject correspondências GameBoard

Observe que não há nenhuma instância de conversor de tipo neste fluxo de nós. Mas você pode obter informações de conversor de tipo chamando XamlMember.TypeConverter no XamlMember para BoardSize. Se você tiver um contexto de esquema XAML válido, também poderá invocar os métodos de conversor obtendo uma instância de ConverterInstance.

Extensões de marcação no fluxo de nó XAML

Um uso de extensão de marcação é relatado no fluxo de nó XAML como um nó de objeto dentro de um membro, em que o objeto representa uma instância de extensão de marcação. Portanto, um uso de extensão de marcação é apresentado mais explicitamente na representação de fluxo de nó do que um uso de conversor de tipo e carrega mais informações. XamlMember informações não poderiam ter informado nada sobre a extensão de marcação, pois o uso é situacional e varia em cada caso de marcação possível; não é dedicado e implícito por tipo ou membro, como é o caso dos conversores de tipo.

A representação de fluxo de nós de extensões de marcação como nós de objeto é o caso mesmo se o uso da extensão de marcação foi feito no formulário de atributo na marcação de texto XAML (que geralmente é o caso). Os usos de extensão de marcação que usaram um formulário de elemento de objeto explícito são tratados da mesma maneira.

Dentro de um nó de objeto de extensão de marcação, pode haver membros dessa extensão de marcação. A representação de fluxo de nó XAML preserva o uso dessa extensão de marcação, seja um uso de parâmetro posicional ou um uso com parâmetros nomeados explícitos.

Para um uso de parâmetro posicional, o fluxo de nós XAML contém uma propriedade definida pela linguagem XAML _PositionalParameters que registra o uso. Essa propriedade é uma List<T> genérica com restrição Object. A restrição é objeto e não cadeia de caracteres porque, concebivelmente, um uso de parâmetro posicional pode conter usos de extensão de marcação aninhados dentro dele. Para acessar os parâmetros posicionais do uso, você pode iterar pela lista e usar os indexadores para valores de lista individuais.

Para um uso de parâmetro nomeado, cada parâmetro nomeado é representado como um nó membro desse nome no fluxo de nós. Os valores de membro não são necessariamente cadeias de caracteres, pois pode haver um uso de extensão de marcação aninhado.

ProvideValue da extensão de marcação ainda não foi invocada. No entanto, ele será invocado se você conectar um leitor XAML e um gravador XAML para que WriteEndObject seja invocado no nó de extensão de marcação quando você o examinar no fluxo de nós. Por esse motivo, você geralmente precisa do mesmo contexto de esquema XAML disponível como seria usado para formar o grafo de objeto no caminho de carga. Caso contrário, ProvideValue de qualquer extensão de marcação podem gerar exceções aqui, porque ela não tem serviços esperados disponíveis.

Membros de Language-Defined XAML e XML no fluxo de nó XAML

Determinados membros são introduzidos em um fluxo de nó XAML devido a interpretações e convenções de um leitor XAML, em vez de por meio de uma pesquisa ou construção XamlMember explícita. Geralmente, esses membros são diretivas XAML. Em alguns casos, é o ato de ler o XAML que introduz a diretiva no fluxo de nós XAML. Em outras palavras, o texto XAML de entrada original não especificou explicitamente a diretiva de membro, mas o leitor XAML insere a diretiva para atender a uma convenção XAML estrutural e relatar informações no fluxo de nós XAML antes que essas informações sejam perdidas.

A lista a seguir observa todos os casos em que um leitor XAML deve introduzir um nó de membro XAML de diretiva e como esse nó de membro é identificado nas implementações dos Serviços XAML do .NET.

  • texto de inicialização para um nó de objeto: O nome desse nó membro é _Initialization, ele representa uma diretiva XAML e é definido no namespace XAML da linguagem XAML. Você pode obter uma entidade estática para ela de Initialization.

  • parâmetros posicionais para uma extensão de marcação: O nome desse nó membro é _PositionalParameterse é definido no namespace XAML da linguagem XAML. Ele sempre contém uma lista genérica de objetos, cada um deles um parâmetro posicional pré-separado pela divisão no caractere delimitador ,, conforme fornecido no XAML de entrada. Você pode obter uma entidade estática para a diretiva de parâmetros posicionais de PositionalParameters.

  • Conteúdo desconhecido: O nome desse nó de membro é _UnknownContent. Estritamente falando, é um XamlDirectivee é definido no namespace XAML da linguagem XAML. Essa diretiva é usada como sentinela para casos em que um elemento de objeto XAML contém conteúdo no XAML de origem, mas nenhuma propriedade de conteúdo pode ser determinada no contexto de esquema XAML atualmente disponível. Você pode detectar esse caso em um fluxo de nó XAML verificando se há membros chamados _UnknownContent. Se nenhuma outra ação for executada em um fluxo de nó XAML de caminho de carga, o XamlObjectWriter padrão será gerado na tentativa de WriteEndObject quando encontrar o membro _UnknownContent em qualquer objeto. O XamlXmlWriter padrão não é gerado e trata o membro como implícito. Você pode obter uma entidade estática para _UnknownContent de UnknownContent.

  • propriedade Collection de uma coleção: Embora o tipo CLR de suporte de uma classe de coleção usada para XAML geralmente tenha uma propriedade nomeada dedicada que contém os itens de coleção, essa propriedade não é conhecida por um sistema de tipos XAML antes de fazer backup da resolução de tipos. Em vez disso, o fluxo de nós XAML apresenta um espaço reservado Items como membro do tipo XAML da coleção. Na implementação dos Serviços XAML do .NET, o nome dessa diretiva ou membro no fluxo de nós é _Items. Uma constante para essa diretiva pode ser obtida de Items.

    Observe que um fluxo de nó XAML pode conter uma propriedade Items com itens que não podem ser analisados com base na resolução de tipo de backup e no contexto do esquema XAML. Por exemplo

  • membros definidos por XML: os membros xml:base, xml:lang e xml:space definidos por XML são relatados como diretivas XAML chamadas base, lange space em implementações do .NET XAML Services. O namespace para eles é o namespace XML http://www.w3.org/XML/1998/namespace. As constantes para cada uma delas podem ser obtidas de XamlLanguage.

Ordem do nó

Em alguns casos, XamlXmlReader altera a ordem dos nós XAML no fluxo de nós XAML, em comparação com a ordem em que os nós aparecem se exibidos na marcação ou se processados como XML. Isso é feito para ordenar os nós de modo que um XamlObjectWriter possa processar o fluxo de nó de maneira somente para encaminhamento. Nos Serviços XAML do .NET, o leitor XAML reordena nós em vez de deixar essa tarefa para o gravador XAML, como uma otimização de desempenho para consumidores de gravador de objetos XAML do fluxo de nós.

Determinadas diretivas se destinam especificamente a fornecer mais informações para a criação de um objeto de um elemento de objeto. Essas diretivas são: Initialization, PositionalParameters, TypeArguments, FactoryMethod, Arguments. Os leitores XAML dos Serviços XAML do .NET tentam colocar essas diretivas como os primeiros membros no fluxo de nós após a StartObjectde um objeto, por motivos explicados na próxima seção.

Comportamento e ordem de nó de XamlObjectWriter

StartObject a um XamlObjectWriter não é necessariamente um sinal para o gravador de objetos XAML construir imediatamente a instância do objeto. O XAML inclui vários recursos de linguagem que possibilitam a inicialização de um objeto com entrada adicional e não dependem inteiramente da invocação de um construtor sem parâmetros para produzir o objeto inicial e, somente depois, definir propriedades. Esses recursos incluem: XamlDeferLoadAttribute; texto de inicialização; x:TypeArguments; parâmetros posicionais de uma extensão de marcação; métodos de fábrica e x:Arguments nós associados (XAML 2009). Cada um desses casos atrasa a construção real do objeto e, como o fluxo do nó é reordenado, o gravador de objetos XAML pode contar com um comportamento de construir a instância sempre que um membro inicial é encontrado que não é especificamente uma diretiva de construção para esse tipo de objeto.

GetObject

GetObject representa um nó XAML em que, em vez de construir um novo objeto, um gravador de objeto XAML deve obter o valor da propriedade que contém o objeto. Um caso típico em que um nó GetObject é encontrado em um fluxo de nó XAML é para um objeto de coleção ou um objeto de dicionário, quando a propriedade que contém é deliberadamente somente leitura no modelo de objeto do tipo de backup. Nesse cenário, a coleção ou dicionário geralmente é criado e inicializado (geralmente vazio) pela lógica de inicialização de um tipo proprietário.

Consulte também