Visão geral dos conversores de tipo para XAML

Os conversores de tipo fornecem lógica para um gravador de objetos que converte de uma cadeia de caracteres na marcação XAML em objetos específicos em um gráfico de objeto. Nos Serviços XAML do .NET, o conversor de tipo deve ser uma classe derivada de TypeConverter. Alguns conversores também oferecem suporte ao caminho de salvamento XAML e podem ser usados para serializar um objeto em um formulário de cadeia de caracteres na marcação de serialização. Este tópico descreve como e quando os conversores de tipo em XAML são chamados e fornece conselhos de implementação para as substituições de método do TypeConverter.

Conceitos de conversão de tipos

As seções a seguir explicam conceitos básicos sobre como o XAML usa cadeias de caracteres e como os escritores de objetos nos Serviços XAML do .NET usam conversores de tipo para processar alguns dos valores de cadeia de caracteres encontrados em uma fonte XAML.

XAML e valores de cadeia de caracteres

Quando você define um valor de atributo em um arquivo XAML, o tipo inicial desse valor é uma cadeia de caracteres em um sentido geral e um valor de atributo de cadeia de caracteres em um sentido XML. Mesmo outras primitivas, como Double são inicialmente cadeias de caracteres para um processador XAML.

Na maioria dos casos, um processador XAML precisa de duas informações para processar um valor de atributo. A primeira informação é o tipo de valor da propriedade que está sendo definido. Qualquer cadeia de caracteres que define um valor de atributo e que é processada em XAML deve, por fim, ser convertida ou resolvida para um valor desse tipo. Caso o valor seja um primitivo compreendido pelo analisador XAML (como um valor numérico), será tentada uma conversão direta da cadeia de caracteres. Se o valor do atributo fizer referência a uma enumeração, a cadeia de caracteres fornecida será verificada para uma correspondência de nome com uma constante nomeada nessa enumeração. Se o valor não for uma primitiva compreendida pelo analisador ou um nome constante de uma enumeração, o tipo aplicável deverá ser capaz de fornecer um valor ou referência baseado em uma cadeia de caracteres convertida.

Observação

As diretivas de linguagem XAML não usam conversores de tipo.

Conversores de tipo e extensões de marcação

Os usos da extensão de marcação devem ser manipulados por um processador XAML antes que ele verifique o tipo de propriedade e outras considerações. Por exemplo, se uma propriedade que está sendo definida como um atributo normalmente tem uma conversão de tipo, mas em um caso específico é definida por um uso de extensão de marcação, o comportamento da extensão de marcação é processado primeiro. Uma situação comum em que uma extensão de marcação é necessária é fazer uma referência a um objeto que já existe. Para esse cenário, um conversor de tipo sem monitoração de estado só pode gerar uma nova instância, o que pode não ser desejável. Para obter mais informações sobre extensões de marcação, consulte Visão geral sobre extensões de marcação para XAML.

Conversores de tipos nativos

Nas implementações de serviços Windows Presentation Foundation (WPF) e .NET XAML, há determinados tipos de CLR que têm manipulação de conversão de tipo nativo. No entanto, esses tipos de CLR não são convencionalmente considerados primitivos. Um exemplo desse tipo é DateTime. Uma razão para isso é como a arquitetura do .NET Framework funciona: o tipo DateTime é definido em mscorlib, a biblioteca mais básica do .NET. DateTime não tem permissão para ser atribuído a um atributo que vem de outro assembly que introduz uma dependência (TypeConverterAttribute é do sistema). Portanto, o mecanismo de descoberta do conversor de tipo usual atribuindo não pode ser suportado. Em vez disso, o analisador XAML tem uma lista de tipos que precisam de processamento nativo e processa esses tipos de forma semelhante a como as primitivas verdadeiras são processadas. No caso do DateTime, esse processamento envolve uma chamada para Parse.

Implementando um conversor de tipos

As seções a seguir discutem a TypeConverter API da classe.

TypeConverter

Em Serviços XAML do .NET, todos os conversores de tipo usados para fins XAML são classes derivadas da classe TypeConverterbase . A TypeConverter classe existia em versões do .NET Framework antes da existência do XAML, um dos cenários originais TypeConverter era fornecer conversão de cadeia de caracteres para editores de propriedades em designers visuais.

Para XAML, a função de TypeConverter é expandida. Para fins de XAML, TypeConverter é a classe base para fornecer suporte a determinadas conversões de cadeia de caracteres e de cadeia de caracteres. From-string permite analisar um valor de atributo de cadeia de caracteres de XAML. A cadeia de caracteres pode habilitar o processamento de um valor de tempo de execução de uma propriedade de objeto específica de volta para um atributo em XAML para serialização.

TypeConverter define quatro membros que são relevantes para converter em string e from-string para fins de processamento XAML:

Desses membros, o método mais importante é ConvertFrom, que converte a cadeia de caracteres de entrada para o tipo de objeto necessário. O ConvertFrom método pode ser implementado para converter uma gama mais ampla de tipos no tipo de destino pretendido do conversor. Portanto, ele pode servir a propósitos que vão além do XAML, como dar suporte a conversões em tempo de execução. No entanto, para uso em XAML, somente o caminho de código que pode processar uma String entrada é importante.

O segundo método mais importante é ConvertToo . Se um aplicativo for convertido em uma representação de marcação (por exemplo, se for salvo em XAML como um arquivo), ConvertTo estará envolvido no cenário maior de um gravador de texto XAML para produzir uma representação de marcação. Nesse caso, o caminho de código importante para XAML é quando o chamador passa um destinationType de String.

CanConvertTo e CanConvertFrom são métodos de suporte usados quando um serviço consulta os recursos da TypeConverter implementação. Esses métodos devem ser implementados para retornar o true para casos específicos de tipo aos quais os métodos de conversão equivalentes do seu conversor dão suporte. Para fins XAML, isso geralmente significa o String tipo.

Informações de cultura e conversores de tipos para XAML

Cada TypeConverter implementação pode interpretar exclusivamente o que é uma cadeia de caracteres válida para uma conversão, e também pode usar ou ignorar a descrição do tipo que é passada como parâmetros. Uma consideração importante para a cultura e a conversão de tipo XAML é o seguinte: embora o uso de cadeias de caracteres localizáveis como valores de atributo seja suportado pelo XAML, você não pode usar essas cadeias de caracteres localizáveis como entrada de conversor de tipo com requisitos de cultura específicos. Essa limitação ocorre porque os conversores de tipo para valores de atributo XAML envolvem um comportamento de processamento XAML necessariamente de linguagem fixa que usa en-US cultura. Para obter mais informações sobre os motivos de design para essa restrição, consulte a especificação de linguagem XAML ([MS-XAML]) ou Visão geral de globalização e localização do WPF.

Como um exemplo em que a cultura pode ser um problema, algumas culturas usam uma vírgula em vez de um ponto como o delimitador de ponto decimal para números em forma de cadeia de caracteres. Esse uso colide com o comportamento que muitos conversores de tipo existentes têm, que é usar uma vírgula como um delimitador. Passar uma cultura no xml:lang XAML ao redor não resolve o problema.

Implementando ConvertFrom

Para ser utilizável como uma implementação que ofereça suporte a XAML, o ConvertFrom método para esse conversor deve aceitar uma TypeConverter cadeia de caracteres como parâmetrovalue. Se a cadeia de caracteres estiver em um formato válido e puder ser convertida pela implementação, o objeto retornado deverá oferecer suporte a uma conversão para o tipo esperado pela TypeConverter propriedade. Caso contrário, a ConvertFrom implementação deve retornar null.

Cada TypeConverter implementação pode interpretar exclusivamente o que constitui uma cadeia de caracteres válida para uma conversão, e também pode usar ou ignorar a descrição do tipo ou os contextos de cultura que são passados como parâmetros. No entanto, o processamento XAML do WPF pode não passar valores para o contexto de descrição do tipo em todos os casos e também pode não passar a cultura com base no xml:lang.

Observação

Não use as chaves (), especificamente a chave de abertura ({}{), como um elemento do formato da cadeia de caracteres. Esses caracteres são reservados como entrada e saída para uma sequência de extensão de marcação.

É apropriado lançar uma exceção quando o conversor de tipos deve ter acesso a um serviço XAML do gravador de objeto do .NET XAML Services, mas a GetService chamada feita no contexto não retorna esse serviço.

Implementando ConvertTo

ConvertTo é potencialmente usado para suporte à serialização. O suporte à serialização para ConvertTo seu tipo personalizado e seu conversor de tipo não é um requisito absoluto. No entanto, se você estiver implementando um controle ou usando a serialização de como parte dos recursos ou design de sua classe, você deve implementar ConvertTo.

Para ser utilizável como uma implementação que ofereça suporte a XAML, o ConvertTo método para esse conversor deve aceitar uma TypeConverter instância do tipo (ou um valor) com suporte como parâmetrovalue. Quando o parâmetro é do tipo String, o destinationType objeto retornado deve ser capaz de ser convertido como String. A cadeia de caracteres retornada deve representar um valor serializado de value. Idealmente, o formato de serialização escolhido deve ser capaz de gerar o mesmo valor como se essa cadeia de caracteres fosse passada para a ConvertFrom implementação do mesmo conversor, sem perda significativa de informações.

Se o valor não puder ser serializado ou o conversor não oferecer suporte à serialização, a ConvertTo implementação deverá retornar null e poderá lançar uma exceção. No entanto, se você lançar exceções, deverá relatar a incapacidade de usar essa conversão como parte de sua CanConvertTo implementação para que a prática recomendada de verificar com CanConvertTo primeiro para evitar exceções seja suportada.

Se o destinationType parâmetro não for do tipo String, você pode escolher seu próprio manuseio do conversor. Normalmente, você reverte para o tratamento de implementação de base, que na base ConvertTo gera uma exceção específica.

É apropriado lançar uma exceção quando o conversor de tipos deve ter acesso a um serviço XAML do gravador de objeto do .NET XAML Services, mas a GetService chamada feita no contexto não retorna esse serviço.

Implementando CanConvertFrom

Sua CanConvertFrom implementação deve retornar true para o tipo String e, caso contrário, adiar para sourceType a implementação base. Não lance exceções de CanConvertFrom.

Implementando CanConvertTo

Sua CanConvertTo implementação deve retornar true para o tipo Stringe, caso contrário, adiar para destinationType a implementação base. Não lance exceções de CanConvertTo.

Aplicando o TypeConverterAttribute

Para que seu conversor de tipo personalizado seja usado como o conversor de tipo de atuação para uma classe personalizada pelos Serviços XAML do .NET, você deve aplicar o à sua definição de TypeConverterAttribute classe. O ConverterTypeName que você especificar por meio do atributo deve ser o nome do tipo do conversor de tipo personalizado. Se você aplicar esse atributo, quando um processador XAML manipula valores em que o tipo de propriedade usa seu tipo de classe personalizado, ele pode inserir cadeias de caracteres e retornar instâncias de objeto.

Também é possível fornecer um conversor de tipos por propriedade. Em vez de aplicar um TypeConverterAttribute à definição de classe, aplique-a a uma definição de propriedade (a definição principal, não as get/set implementações dentro dela). O tipo da propriedade deve corresponder ao tipo que é processado pelo conversor de tipos personalizado. Com esse atributo aplicado, quando um processador XAML manipula valores dessa propriedade, ele pode processar cadeias de caracteres de entrada e instâncias de objeto de retorno. A técnica de conversor de tipo por propriedade é útil se você optar por usar um tipo de propriedade do Microsoft .NET Framework ou de alguma outra biblioteca em que você não pode controlar a definição de classe e não pode aplicar um TypeConverterAttribute lá.

Para fornecer um comportamento de conversão de tipo para um membro anexado personalizado, aplique TypeConverterAttribute ao Get método de acessador do padrão de implementação para o membro anexado.

Acessando o contexto do provedor de serviços a partir de uma implementação de extensão de marcação

Os serviços disponíveis são os mesmos para qualquer conversor de valor. A diferença está em como cada conversor de valor recebe o contexto de serviço. O acesso aos serviços e aos serviços disponíveis está documentado no tópico Conversores de tipo e extensões de marcação para XAML.

Conversores de tipo no fluxo de nó XAML

Se você estiver trabalhando com um fluxo de nó XAML, a ação ou o resultado final de um conversor de tipo ainda não foi executado. Em um caminho de carregamento, a cadeia de caracteres de atributo que eventualmente precisa ser convertida em tipo para carregar permanece como um valor de texto dentro de um membro inicial e membro final. O conversor de tipo que é eventualmente necessário para esta operação pode ser determinado usando a XamlMember.TypeConverter propriedade. No entanto, obter um valor válido de depende de ter um contexto de esquema XAML, que pode acessar essas informações por meio do membro subjacente ou do tipo do valor de XamlMember.TypeConverter objeto que o membro usa. Invocar o comportamento de conversão de tipo também requer o contexto do esquema XAML, pois isso requer mapeamento de tipo e criação de uma instância do conversor.

Confira também