Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico apresenta o conceito de extensões de marcação para XAML, incluindo suas regras de sintaxe, finalidade e o modelo de objeto de classe que as sustenta. As extensões de marcação são um recurso geral da linguagem XAML e da implementação .NET dos serviços XAML. Este tópico detalha especificamente as extensões de marcação para uso no WPF XAML.
Processadores XAML e extensões de marcação
De modo geral, um analisador XAML pode interpretar um valor de atributo como uma cadeia de caracteres literal que pode ser convertida em um primitivo ou convertê-lo em um objeto por alguns meios. Um desses meios é referenciando um conversor de tipo; isso está documentado no tópico TypeConverters e XAML. No entanto, há cenários em que diferentes comportamentos são necessários. Por exemplo, um processador XAML pode ser instruído de que um valor de um atributo não deve resultar em um novo objeto no grafo de objeto. Em vez disso, o atributo deve resultar em um grafo de objeto que faz referência a um objeto já construído em outra parte do grafo ou a um objeto estático. Outro cenário é que um processador XAML pode ser instruído a usar uma sintaxe que fornece argumentos não padrão para o construtor de um objeto. Esses são os tipos de cenários em que uma extensão de marcação pode fornecer a solução.
Sintaxe Básica de Extensão de Marcação
Uma extensão de marcação pode ser implementada para fornecer valores para propriedades ao utilizar um atributo, ao utilizar um elemento de propriedade ou ambos.
Quando usada para fornecer um valor de atributo, a sintaxe que distingue uma sequência de extensão de marcação para um processador XAML é a presença das chaves de abertura e fechamento ({ e }). O tipo de extensão de marcação é identificado pelo token de cadeia de caracteres imediatamente após a chave de abertura.
Quando usada na sintaxe de elemento de propriedade, uma extensão de marcação é visualmente semelhante a qualquer outro elemento usado para fornecer um valor ao elemento de propriedade: uma declaração de elemento XAML que faz referência à classe de extensão de marcação como um elemento, entre parênteses angulares (<>).
Extensões de marcação XAML-Defined
Existem várias extensões de marcação que não são específicas para a implementação do WPF de XAML, mas, em vez disso, são implementações de intrínsecos ou recursos de XAML como um idioma. Essas extensões de marcação são implementadas no assembly System.Xaml como parte dos serviços gerais de XAML do .NET Framework e estão dentro do namespace XAML da linguagem XAML. Em termos de uso comum de marcação, essas extensões de marcação normalmente são identificáveis pelo prefixo x:
no uso. A MarkupExtension classe base (também definida em System.Xaml) fornece o padrão que todas as extensões de marcação devem usar para ter suporte em leitores XAML e gravadores XAML, inclusive no WPF XAML.
x:Type
fornece o Type objeto para o tipo nomeado. Esse recurso é usado com mais frequência em estilos e modelos. Para obter detalhes, consulte x:Type Markup Extension.x:Static
produz valores estáticos. Os valores vêm de entidades de código de tipo de valor que não são diretamente o tipo do valor de uma propriedade de destino, mas podem ser avaliados para corresponder a esse tipo. Para obter detalhes, consulte x:Static Markup Extension.x:Null
especificanull
como um valor para uma propriedade e pode ser usado para atributos ou valores de elemento de propriedade. Para obter detalhes, consulte x:Null Markup Extension.x:Array
fornece suporte para a criação de matrizes gerais na sintaxe XAML, para casos em que o suporte à coleção fornecido por elementos base do WPF e modelos de controle não é usado deliberadamente. Para obter detalhes, consulte x:Array Markup Extension.
Observação
O prefix x:
é usado para o mapeamento de namespace XAML típico dos intrínsecos da linguagem XAML, no elemento raiz de um arquivo XAML ou documentação. Por exemplo, os modelos do Visual Studio para aplicativos WPF iniciam um arquivo XAML usando esse x:
mapeamento. Você pode escolher um token de prefixo diferente em seu próprio mapeamento de namespace XAML, mas essa documentação assumirá o mapeamento padrão x:
como um meio de identificar as entidades que são uma parte definida do namespace XAML para a linguagem XAML, em oposição ao namespace padrão do WPF ou a outros namespaces XAML não relacionados a uma estrutura específica.
WPF-Specific Extensões de marcação
As extensões de marcação mais comuns usadas na programação do WPF são aquelas que dão suporte a referências de recursos (StaticResource
e DynamicResource
) e aquelas que dão suporte à associação de dados (Binding
).
StaticResource
fornece um valor para uma propriedade substituindo o valor de um recurso já definido. UmaStaticResource
avaliação é feita no momento de carregamento do XAML e não tem acesso ao grafo de objetos em tempo de execução. Para obter detalhes, consulte StaticResource Markup Extension.DynamicResource
fornece um valor para uma propriedade, adiando esse valor para ser uma referência em tempo de execução para um recurso. Uma referência dinâmica de recurso força a realização de uma nova pesquisa sempre que tal recurso é acessado e tem acesso ao grafo de objetos durante o tempo de execução. Para obter esse acesso,DynamicResource
o conceito é apoiado por propriedades de dependência no sistema de propriedades do WPF e por expressões avaliadas. Portanto, você só pode usarDynamicResource
como alvo de uma propriedade de dependência. Para obter detalhes, consulte a Extensão de Marcação DynamicResource.Binding
fornece um valor associado a dados para uma propriedade, usando o contexto de dados que se aplica ao objeto pai em tempo de execução. Essa extensão de marcação é relativamente complexa, pois permite uma sintaxe embutida substancial para especificar uma associação de dados. Para obter detalhes, consulte a Extensão de Marcação de Vinculação.RelativeSource
fornece informações de origem para um Binding que pode navegar por várias relações possíveis na árvore de objetos em tempo de execução. Isso fornece fornecimento especializado para associações que são criadas em modelos de vários usos ou criadas em código sem conhecimento total da árvore de objetos ao redor. Para obter detalhes, consulte RelativeSource MarkupExtension.TemplateBinding
permite que um modelo de controle use valores para propriedades modeladas provenientes de propriedades definidas pelo modelo de objeto da classe que usará o modelo. Em outras palavras, a propriedade dentro da definição de modelo pode acessar um contexto que só existe quando o modelo é aplicado. Para obter detalhes, consulte a Extensão de Marcação TemplateBinding. Para obter mais informações sobre o uso prático doTemplateBinding
exemplo Estilo com ControlTemplates.ColorConvertedBitmap
dá suporte a um cenário de imagem relativamente avançado. Para obter detalhes, consulte a Extensão de Marcação ColorConvertedBitmap.ComponentResourceKey
eThemeDictionary
suporte a aspectos da pesquisa de recursos, especialmente para recursos e temas que são empacotados com controles personalizados. Para obter mais informações, consulte ComponentResourceKey Markup Extension, ThemeDictionary Markup Extension ou Control Authoring Overview.
*Classes de extensão
Para a linguagem XAML geral e extensões de marcação específicas do WPF, o comportamento de cada extensão de marcação é identificado para um processador XAML por meio de uma *Extension
classe que deriva de MarkupExtension, e fornece uma implementação do método ProvideValue. Esse método em cada extensão fornece o objeto retornado quando a extensão de marcação é avaliada. O objeto retornado normalmente é avaliado com base nos vários tokens de texto (sequências ou strings) que são passados para a extensão de marcação.
Por exemplo, a classe StaticResourceExtension fornece a implementação básica da pesquisa real de recursos, de modo que sua implementação ProvideValue retorne o objeto solicitado, com a entrada dessa implementação específica sendo uma string utilizada para buscar o recurso por seu x:Key
. Grande parte desse detalhe de implementação não é importante se você estiver usando uma extensão de marcação existente.
Algumas extensões de marcação não usam argumentos de token de cadeia de caracteres. Isso ocorre porque eles retornam um valor estático ou consistente ou porque o contexto para qual valor deve ser retornado está disponível por meio de um dos serviços passados pelo serviceProvider
parâmetro.
O *Extension
padrão de nomenclatura é para conveniência e consistência. Não é necessário que um processador XAML identifique essa classe como suporte para uma extensão de marcação. Desde que sua base de código inclua System.Xaml e use implementações do .NET Framework XAML Services, tudo o que é necessário para ser reconhecido como uma extensão de marcação XAML é derivar de MarkupExtension e oferecer suporte a uma sintaxe de construção. O WPF define classes habilitadoras de extensão de marcação que não seguem o *Extension
padrão de nomenclatura, por exemplo Binding. Normalmente, o motivo para isso é que a classe dá suporte a cenários além do suporte à extensão de marcação pura. No caso de Binding, essa classe dá suporte ao acesso em tempo de execução a métodos e propriedades do objeto para cenários que não têm nada a ver com XAML.
Interpretação do texto de inicialização da classe de extensão
Os tokens de sequência de caracteres que seguem o nome da extensão de marcação e ainda estão dentro das chaves são interpretados por um processador XAML de uma das seguintes maneiras:
Uma vírgula sempre representa o separador ou delimitador de tokens individuais.
Se os tokens separados individuais não contiverem sinais iguais, cada token será tratado como um argumento de construtor. Cada parâmetro de construtor deve ser fornecido como o tipo esperado por essa assinatura e na ordem adequada esperada por essa assinatura.
Observação
Um processador XAML deve chamar o construtor cuja contagem de argumentos corresponda ao número de pares. Por esse motivo, se você estiver implementando uma extensão de marcação personalizada, não forneça vários construtores com a mesma contagem de argumentos. O comportamento de um processador XAML quando mais de um caminho de construtor de extensão de marcação com o mesmo número de parâmetros existe não está definido, mas você deve prever que um processador XAML tem permissão para gerar uma exceção no uso se essa situação existir nas definições de tipo de extensão de marcação.
Se os tokens separados individuais contiverem sinais iguais, um processador XAML primeiro chamará o construtor sem parâmetros para a extensão de marcação. Em seguida, cada par name=value é interpretado como um nome de propriedade que existe na extensão de marcação e um valor a ser atribuído a essa propriedade.
Se houver um resultado paralelo entre o comportamento do construtor e o comportamento de configuração da propriedade em uma extensão de marcação, não importa qual comportamento você usa. É mais comum usar os pares propriedade
=
valor para extensões de marcação que possuem mais de uma propriedade configurável, principalmente porque isso torna sua marcação mais intencional e diminui a chance de transpor acidentalmente os parâmetros do construtor. (Quando você especifica pares property=value, essas propriedades podem estar em qualquer ordem.) Além disso, não há garantia de que uma extensão de marcação forneça um parâmetro de construtor que define cada uma de suas propriedades configuráveis. Por exemplo, Binding é uma extensão de marcação, com muitas propriedades que são configuráveis por meio da extensão no formato de propriedade=
valor, mas Binding só dá suporte a dois construtores: um construtor sem parâmetros e um que define um caminho inicial.Uma vírgula literal não pode ser passada para uma extensão de marcação sem escapamento.
Sequências de escape e extensões de marcação
O tratamento de atributos em um processador XAML usa as chaves como indicadores de uma sequência de extensão de marcação. Também é possível produzir um valor de atributo de caractere de chave literal, se necessário, inserindo uma sequência de escape usando um par de chaves vazia seguido pela chave literal. Ver: {} Sequência de Escape – Extensão de Marcação.
Aninhando extensões de marcação no uso de XAML
Há suporte para aninhamento de várias extensões de marcação e cada extensão de marcação será avaliada mais profundamente primeiro. Por exemplo, considere o seguinte uso:
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
Nesse uso, a instrução x:Static
é avaliada primeiro e retorna uma cadeia de caracteres. Essa cadeia de caracteres é usada como o argumento para DynamicResource
.
Extensões de marcação e sintaxe de elemento de propriedade.
Quando usado como um elemento de objeto que preenche um valor de elemento de propriedade, uma classe de extensão de marcação é visualmente indistinguível de um elemento de objeto com suporte de tipo típico que pode ser usado em XAML. A diferença prática entre um elemento de objeto típico e uma extensão de marcação é que a extensão de marcação é avaliada como um valor de tipo definido ou adiada para ser usada como uma expressão. Portanto, os mecanismos para possíveis erros de tipo de valores de propriedade para a extensão de marcação serão diferentes, semelhante à forma como uma propriedade com limite tardio é tratada em outros modelos de programação. Um elemento de objeto comum será avaliado para verificar a correspondência de tipo em relação à propriedade alvo que está sendo definida quando o XAML é analisado.
A maioria das extensões de marcação, quando usadas na sintaxe do elemento de objeto para preencher um elemento de propriedade, não teria conteúdo nem qualquer sintaxe de elemento de propriedade adicional dentro. Portanto, você fecharia a etiqueta do elemento de objeto e não incluiria elementos filho. Sempre que qualquer elemento de objeto é encontrado por um processador XAML, o construtor dessa classe é chamado, o que cria uma instância do objeto criado a partir do elemento analisado. Uma classe de extensão de marcação não é diferente: se você quiser que sua extensão de marcação seja utilizável na sintaxe do elemento de objeto, você deve fornecer um construtor sem parâmetros. Algumas extensões de marcação existentes têm pelo menos um valor de propriedade necessário que deve ser especificado para inicialização efetiva. Nesse caso, esse valor de propriedade normalmente é fornecido como um atributo de propriedade no elemento de objeto. No Namespace XAML (x:) Recursos de Linguagem e nas páginas de referência de Extensões XAML do WPF, as extensões de marcação que possuem propriedades necessárias (e os nomes das propriedades necessárias) serão destacadas. As páginas de referência também observarão se a sintaxe de elemento de objeto ou a sintaxe de atributo não são permitidas para extensões de marcação específicas. Um caso notável é a Extensão de Marcação x:Array, que não pode dar suporte à sintaxe de atributo porque o conteúdo dessa matriz deve ser especificado dentro da marcação como conteúdo. O conteúdo da matriz é tratado como objetos gerais, portanto, nenhum conversor de tipo padrão para o atributo é viável. Além disso, a Extensão de Marcação x:Array requer um type
parâmetro.
Consulte também
.NET Desktop feedback