TypeConverters e XAMLTypeConverters and XAML

Este tópico apresenta a finalidade da conversão de tipo de cadeia de caracteres como um recurso de linguagem XAML geral.This topic introduces the purpose of type conversion from string as a general XAML language feature. Na .NET Framework, a TypeConverter classe atende a uma finalidade específica como parte da implementação de uma classe personalizada gerenciada que pode ser usada como um valor de propriedade no uso do atributo XAML.In the .NET Framework, the TypeConverter class serves a particular purpose as part of the implementation for a managed custom class that can be used as a property value in XAML attribute usage. Se você escrever uma classe personalizada e desejar que as instâncias da sua classe sejam utilizáveis como valores de atributo configurável XAML, talvez seja necessário aplicar uma TypeConverterAttribute à sua classe, escrever uma classe personalizada TypeConverter ou ambas.If you write a custom class, and you want instances of your class to be usable as XAML settable attribute values, you might need to apply a TypeConverterAttribute to your class, write a custom TypeConverter class, or both.

Conceitos de conversão de tiposType Conversion Concepts

XAML e valores de cadeia de caracteresXAML and String Values

Quando um valor de atributo é definido em um arquivo XAML, o tipo inicial desse valor é uma cadeia de caracteres em texto simples.When you set an attribute value in a XAML file, the initial type of that value is a string in pure text. Mesmo outros primitivos como, Double por exemplo, são cadeias de caracteres de texto inicialmente para um processador XAML.Even other primitives such as Double are initially text strings to a XAML processor.

Um processador XAML precisa de duas informações para processar um valor de atributo.A XAML processor needs two pieces of information in order to process an attribute value. A primeira informação é o tipo de valor da propriedade que está sendo definido.The first piece of information is the value type of the property that is being set. 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.Any string that defines an attribute value and that is processed in XAML must ultimately be converted or resolved to a value of that type. 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.If the value is a primitive that is understood by the XAML parser (such as a numeric value), a direct conversion of the string is attempted. Se o valor for uma enumeração, a cadeia de caracteres será usada para verificar se há uma correspondência de nome com uma constante nomeada na enumeração.If the value is an enumeration, the string is used to check for a name match to a named constant in that enumeration. Se o valor não for um primitivo compreendido pelo analisador nem uma enumeração, o tipo em questão deverá ser capaz de fornecer uma instância do tipo ou um valor, com base em uma cadeia de caracteres convertida.If the value is neither a parser-understood primitive nor an enumeration, then the type in question must be able to provide an instance of the type, or a value, based on a converted string. Isso é feito por meio de indicação de uma classe de conversor de tipos.This is done by indicating a type converter class. O conversor de tipos é uma classe auxiliar para fornecer valores de outra classe, tanto para o cenário XAML quanto, potencialmente, para chamadas de código no código .NET.The type converter is effectively a helper class for providing values of another class, both for the XAML scenario and also potentially for code calls in .NET code.

Usando o comportamento de conversão de tipo existente em XAMLUsing Existing Type Conversion Behavior in XAML

Dependendo da sua familiaridade com os conceitos fundamentais de XAML, você pode já estar usando o comportamento de conversão de tipos no aplicativo básico XAML sem perceber.Depending on your familiarity with the underlying XAML concepts, you may already be using type conversion behavior in basic application XAML without realizing it. Por exemplo, o WPF define literalmente centenas de propriedades que usam um valor de Pointtipo.For instance, WPF defines literally hundreds of properties that take a value of type Point. Um Point é um valor que descreve uma coordenada em um espaço de coordenadas bidimensional e, na verdade, tem apenas duas X propriedades Yimportantes: e.A Point is a value that describes a coordinate in a two-dimensional coordinate space, and it really just has two important properties: X and Y. Quando você especifica um ponto no XAML, você o especifica como uma cadeia de caracteres com um delimitador (normalmente uma X vírgula Y ) entre os valores e fornecidos.When you specify a point in XAML, you specify it as a string with a delimiter (typically a comma) between the X and Y values you provide. Por exemplo: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.For example: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Mesmo esse simples tipo de Point e seu uso simples em XAML envolvem um conversor de tipo.Even this simple type of Point and its simple usage in XAML involve a type converter. Nesse caso, essa é a classe PointConverter.In this case that is the class PointConverter.

O conversor de tipo Point para definido no nível de classe simplifica os usos de marcação de todas as propriedades que Pointusam.The type converter for Point defined at the class level streamlines the markup usages of all properties that take Point. Sem um conversor de tipos aqui, você precisaria da marcação muito mais detalhada a seguir para o mesmo exemplo mostrado anteriormente:Without a type converter here, you would need the following much more verbose markup for the same example shown previously:

<LinearGradientBrush>
  <LinearGradientBrush.StartPoint>
    <Point X="0" Y="0"/>
  </LinearGradientBrush.StartPoint>
  <LinearGradientBrush.EndPoint>
    <Point X="1" Y="1"/>
  </LinearGradientBrush.EndPoint>
</LinearGradientBrush>

Usar a cadeia de caracteres de conversão de tipo ou uma sintaxe equivalente mais detalhada geralmente é uma opção de estilo de codificação.Whether to use the type conversion string or a more verbose equivalent syntax is generally a coding style choice. O fluxo de trabalho das ferramentas XAML também pode influenciar a forma como os valores são definidos.Your XAML tooling workflow might also influence how values are set. Algumas ferramentas XAML tendem a emitir a forma mais detalhada da marcação, porque é mais fácil ir e voltar de modos de exibição de designer ou do próprio mecanismo de serialização.Some XAML tools tend to emit the most verbose form of the markup because it is easier to round-trip to designer views or its own serialization mechanism.

Os conversores de tipo existentes geralmente podem ser descobertos no WPF e tipos de .NET Framework, verificando uma classe (ou Propriedade) TypeConverterAttributepara a presença de um aplicado.Existing type converters can generally be discovered on WPF and .NET Framework types by checking a class (or property) for the presence of an applied TypeConverterAttribute. Esse atributo nomeará a classe que é o conversor de tipos de suporte para valores desse tipo, para fins de XAML e, potencialmente, outras finalidades.This attribute will name the class that is the supporting type converter for values of that type, for XAML purposes as well as potentially other purposes.

Conversores de tipo e extensões de marcaçãoType Converters and Markup Extensions

As extensões de marcação e os conversores de tipos exercem funções ortogonais em termos de comportamento do processador XAML e dos cenários aos quais são aplicados.Markup extensions and type converters fill orthogonal roles in terms of XAML processor behavior and the scenarios that they are applied to. Embora o contexto esteja disponível para usos de extensão de marcação, o comportamento de conversão de tipos de propriedades em que uma extensão de marcação fornece um valor geralmente não é verificado em implementações de extensão de marcação.Although context is available for markup extension usages, type conversion behavior of properties where a markup extension provides a value is generally is not checked in the markup extension implementations. Em outras palavras, mesmo se uma extensão de marcação retornar uma cadeia de caracteres de texto como saída do ProvideValue, o comportamento de conversão de tipo dessa cadeia de caracteres, conforme aplicado a uma propriedade específica ou a um tipo de valor da propriedade, não será chamado. Em geral, a finalidade de uma extensão de marcação é processar uma cadeia de caracteres e retornar um objeto sem nenhum conversor de tipo envolvido.In other words, even if a markup extension returns a text string as its ProvideValue output, type conversion behavior on that string as applied to a specific property or property value type is not invoked, Generally, the purpose of a markup extension is to process a string and return an object without any type converter involved.

Uma situação comum em que uma extensão de marcação é necessária, em vez de um conversor de tipos, é para fazer referência a um objeto que já existe.One common situation where a markup extension is necessary rather than a type converter is to make a reference to an object that already exists. Na melhor das hipóteses, um conversor de tipo sem monitoração de estado pode gerar somente uma nova instância, o que pode não ser desejável.At best, a stateless type converter could only generate a new instance, which might not be desirable. Para obter mais informações sobre extensões de marcação, consulte Extensões de marcação e XAML WPF.For more information on markup extensions, see Markup Extensions and WPF XAML.

Conversores de tipos nativosNative Type Converters

Na implementação do analisador XAML do WPF e do .NET Framework, alguns tipos têm manipulação de conversão de tipos nativos; porém, não são tipos que poderiam ser interpretados, convencionalmente, como primitivos.In the WPF and .NET Framework implementation of the XAML parser, there are certain types that have native type conversion handling, yet are not types that might conventionally be thought of as primitives. Um exemplo desse tipo é DateTime.An example of such a type is DateTime. O motivo disso se baseia em como a arquitetura de .NET Framework funciona: o tipo DateTime é definido em mscorlib, a biblioteca mais básica no .net.The reason for this is based on how the .NET Framework architecture works: the type DateTime is defined in mscorlib, the most basic library in .NET. DateTimeNão tem permissão para ser atribuído a um atributo proveniente de outro assembly que introduz uma dependência (TypeConverterAttribute é do sistema), de modo que o mecanismo de descoberta do conversor de tipos usual por atribuição não pode ter suporte.DateTime is not permitted to be attributed with an attribute that comes from another assembly that introduces a dependency (TypeConverterAttribute is from System) so the usual type converter discovery mechanism by attributing cannot be supported. Em vez disso, o analisador XAML tem uma lista de tipos que precisam de tal processamento nativo e os processa da mesma forma como os primitivos verdadeiros são processados.Instead, the XAML parser has a list of types that need such native processing and processes these similarly to how the true primitives are processed. (No caso DateTime disso, isso envolve uma chamada para Parse.)(In the case of DateTime this involves a call to Parse.)

Implementando um conversor de tiposImplementing a Type Converter

TypeConverterTypeConverter

No exemplo fornecido anteriormente, a classe PointConverter foi mencionada. PointIn the Point example given previously, the class PointConverter was mentioned. Para implementações do .NET de XAML, todos os conversores de tipo usados para fins XAML são classes que derivam da TypeConverterclasse base.For .NET implementations of XAML, all type converters that are used for XAML purposes are classes that derive from the base class TypeConverter. A TypeConverter classe existia em versões do .NET Framework que precedem a existência do XAML; um de seus usos originais era fornecer conversão de cadeia de caracteres para caixas de diálogo de propriedade em designers visuais.The TypeConverter class existed in versions of .NET Framework that precede the existence of XAML; one of its original usages was to provide string conversion for property dialogs in visual designers. Para o XAML, a função TypeConverter de é expandida para incluir a classe base para conversões de cadeia de caracteres e de cadeia de caracteres que habilitam a análise de um valor de atributo de cadeia de caracteres e, possivelmente, o processamento de um valor em tempo de execução de uma determinada propriedade de objeto de volta para uma cadeia de caracteres para serialização como um atributo.For XAML, the role of TypeConverter is expanded to include being the base class for to-string and from-string conversions that enable parsing a string attribute value, and possibly processing a run-time value of a particular object property back into a string for serialization as an attribute.

TypeConverterdefine quatro membros que são relevantes para converter para e de cadeias de caracteres para fins de processamento XAML:TypeConverter defines four members that are relevant for converting to and from strings for XAML processing purposes:

Desses, o método mais importante é ConvertFrom.Of these, the most important method is ConvertFrom. Esse método converte a cadeia de caracteres de entrada para o tipo de objeto necessário.This method converts the input string to the required object type. Estritamente falando, o ConvertFrom método poderia ser implementado para converter um intervalo muito maior de tipos no tipo de destino pretendido do conversor e, portanto, servir para fins que se estendam além do XAML, como suporte a conversões de tempo de execução, mas para fins de XAML é apenas o caminho do código que pode processar uma String entrada que importa.Strictly speaking, the ConvertFrom method could be implemented to convert a much wider range of types into the converter's intended destination type, and thus serve purposes that extend beyond XAML such as supporting run-time conversions, but for XAML purposes it is only the code path that can process a String input that matters.

O próximo método mais importante é ConvertTo.The next most important method is ConvertTo. Se um aplicativo for convertido em uma representação de marcação (por exemplo, se for salvo em XAML como um arquivo), ConvertTo será responsável por produzir uma representação de marcação.If an application is converted to a markup representation (for instance, if it is saved to XAML as a file), ConvertTo is responsible for producing a markup representation. Nesse caso, o caminho de código que importa para XAML é quando você passa um destinationType de String .In this case, the code path that matters for XAML is when you pass a destinationType of String .

CanConvertToe CanConvertFrom são métodos TypeConverter de suporte que são usados quando um serviço consulta os recursos da implementação.CanConvertTo and CanConvertFrom are support methods that are used when a service queries the capabilities of the TypeConverter implementation. 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.You must implement these methods to return true for type-specific cases that the equivalent conversion methods of your converter support. Para fins de XAML, isso geralmente significa String o tipo.For XAML purposes, this generally means the String type.

Informações de cultura e conversores de tipos para XAMLCulture Information and Type Converters for XAML

Cada TypeConverter implementação pode ter sua própria interpretação do que constitui uma cadeia de caracteres válida para uma conversão e também pode usar ou ignorar a descrição do tipo passada como parâmetros.Each TypeConverter implementation can have its own interpretation of what constitutes a valid string for a conversion, and can also use or ignore the type description passed as parameters. Há uma consideração importante em relação à cultura e à conversão de tipos XAML.There is an important consideration with regard to culture and XAML type conversion. O XAML dá suporte total ao uso de cadeias de caracteres localizáveis como valores de atributos.Using localizable strings as attribute values is entirely supported by XAML. Porém, não há suporte para o uso dessa cadeia de caracteres localizável como entrada do conversor de tipos com exigências específicas de cultura, porque os conversores de tipos para valores de atributos XAML envolvem um comportamento de análise de linguagem necessariamente fixo, usando a cultura do en-US.But using that localizable string as type converter input with specific culture requirements is not supported, because type converters for XAML attribute values involve a necessarily fixed-language parsing behavior, using en-US culture. Para obter mais informações sobre os motivos de design para essa restrição, você deve consultar a especificação da linguagem XAML ([MS-XAML]).For more information on the design reasons for this restriction, you should consult the XAML language specification ([MS-XAML]).

Como exemplo de casos em que a cultura pode ser um problema, algumas culturas usam vírgula como delimitador de ponto decimal para números.As an example where culture can be an issue, some cultures use a comma as their decimal point delimiter for numbers. Isso vai de encontro ao comportamento que muitos dos conversores de tipos XAML do WPF têm, que é usar uma vírgula como delimitador (com base em precedentes históricos, como a forma comum X,Y ou listas delimitadas por vírgulas).This will collide with the behavior that many of the WPF XAML type converters have, which is to use a comma as a delimiter (based on historical precedents such as the common X,Y form, or comma delimited lists). Nem mesmo a passagem de uma cultura no XAML ao redor (definindo Language ou xml:lang para a cultura do sl-SI, um exemplo de cultura que usa vírgula para decimal dessa maneira) resolve o problema.Even passing a culture in the surrounding XAML (setting Language or xml:lang to the sl-SI culture, an example of a culture that uses a comma for decimal in this way) does not solve the issue.

Implementando ConvertFromImplementing ConvertFrom

Para ser utilizável como uma TypeConverter implementação que dá suporte a XAML ConvertFrom , o método para esse conversor deve aceitar uma cadeia value de caracteres como o parâmetro.To be usable as a TypeConverter implementation that supports XAML, the ConvertFrom method for that converter must accept a string as the value parameter. Se a cadeia de caracteres estava em um formato válido e puder ser convertida pela TypeConverter implementação, o objeto retornado deverá dar suporte a uma conversão para o tipo esperado pela propriedade.If the string was in valid format, and can be converted by the TypeConverter implementation, then the returned object must support a cast to the type expected by the property. Caso contrário, ConvertFrom a implementação deve nullretornar.Otherwise, the ConvertFrom implementation must return null.

Cada TypeConverter implementação pode ter sua própria interpretação do 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 contextos de cultura passados como parâmetros.Each TypeConverter implementation can have its own interpretation of what constitutes a valid string for a conversion, and can also use or ignore the type description or culture contexts passed as parameters. No entanto, o processamento de XAML do WPF não pode passar valores para o contexto de descrição de tipo em todos os casos; tampouco consegue passar a cultura com base no xml:lang.However, the WPF XAML processing might not pass values to the type description context in all cases, and also might not pass culture based on xml:lang.

Observação

Não utilize os caracteres de chave, especialmente o {, como elemento possível do formato da cadeia de caracteres.Do not use the curly brace characters, particularly {, as a possible element of your string format. Esses caracteres são reservados como entrada e saída para uma sequência de extensão de marcação.These characters are reserved as the entry and exit for a markup extension sequence.

Implementando ConvertToImplementing ConvertTo

ConvertToé potencialmente usado para suporte de serialização.ConvertTo is potentially used for serialization support. O suporte ConvertTo de serialização para o tipo personalizado e seu conversor de tipo não é um requisito absoluto.Serialization support through ConvertTo for your custom type and its type converter is not an absolute requirement. No entanto, se você estiver implementando um controle ou usando a serialização do como parte dos recursos ou do design da sua classe, ConvertTodeverá implementar o.However, if you are implementing a control, or using serialization of as part of the features or design of your class, you should implement ConvertTo.

Para ser utilizável como uma TypeConverter implementação que dá suporte a XAML ConvertTo , o método para esse conversor deve aceitar uma instância do tipo (ou um valor) com suporte como value o parâmetro.To be usable as a TypeConverter implementation that supports XAML, the ConvertTo method for that converter must accept an instance of the type (or a value) being supported as the value parameter. Quando o destinationType parâmetro é o tipo String, o objeto retornado deve ser capaz de ser convertido como String.When the destinationType parameter is the type String, then the returned object must be able to be cast as String. A cadeia de caracteres retornada deve representar um valor serializado de value.The returned string must represent a serialized value of value. O ideal é que o formato de serialização escolhido seja capaz de gerar o mesmo valor se essa cadeia de caracteres fosse ConvertFrom passada para a implementação do mesmo conversor, sem perda significativa de informações.Ideally, the serialization format you choose should be capable of generating the same value if that string were passed to the ConvertFrom implementation of the same converter, without significant loss of information.

Se o valor não puder ser serializado ou o conversor não oferecer suporte à serialização, ConvertTo a implementação deverá nullretornar e poderá gerar uma exceção nesse caso.If the value cannot be serialized, or the converter does not support serialization, the ConvertTo implementation must return null, and is permitted to throw an exception in this case. Mas se você lançar exceções, deverá informar a incapacidade de usar essa conversão como parte da sua CanConvertTo implementação para que a melhor prática de verificar com CanConvertTo primeiro para evitar exceções seja suportada.But if you do throw exceptions, you should report the inability to use that conversion as part of your CanConvertTo implementation so that the best practice of checking with CanConvertTo first to avoid exceptions is supported.

Se destinationType o parâmetro não for do Stringtipo, você poderá escolher sua própria manipulação de conversor.If destinationType parameter is not of type String, you can choose your own converter handling. Normalmente, você reverteria para o tratamento de implementação base, que no ConvertTo basemost gera uma exceção específica.Typically, you would revert to base implementation handling, which in the basemost ConvertTo raises a specific exception.

Implementando CanConvertToImplementing CanConvertTo

Sua CanConvertTo implementação deve retornar true para destinationType o tipo Stringe, de outra forma, adiar para a implementação base.Your CanConvertTo implementation should return true for destinationType of type String, and otherwise defer to the base implementation.

Implementando CanConvertFromImplementing CanConvertFrom

Sua CanConvertFrom implementação deve retornar true para sourceType o tipo Stringe, de outra forma, adiar para a implementação base.Your CanConvertFrom implementation should return true for sourceType of type String, and otherwise defer to the base implementation.

Aplicando o TypeConverterAttributeApplying the TypeConverterAttribute

Para que o conversor de tipo personalizado seja usado como o conversor de tipo atuante para uma classe personalizada por um processador XAML, você deve aplicar TypeConverterAttribute o à sua definição de classe.In order for your custom type converter to be used as the acting type converter for a custom class by a XAML processor, you must apply the TypeConverterAttribute to your class definition. O ConverterTypeName que você especificar por meio do atributo deve ser o nome do tipo do conversor de tipo personalizado.The ConverterTypeName that you specify through the attribute must be the type name of your custom type converter. Com esse atributo aplicado, quando um processador XAML manipula valores em que o tipo de propriedade usa o tipo de classe personalizada, ele pode processar cadeias de caracteres de entrada e retornar as instâncias de objeto.With this attribute applied, when a XAML processor handles values where the property type uses your custom class type, it can input strings and return object instances.

Também é possível fornecer um conversor de tipos por propriedade.You can also provide a type converter on a per-property basis. Em vez de aplicar TypeConverterAttribute uma à definição de classe, aplique-a a uma definição de propriedade (a definição principal get , não as / set implementações dentro dela).Instead of applying a TypeConverterAttribute to the class definition, apply it to a property definition (the main definition, not the get/set implementations within it). O tipo da propriedade deve corresponder ao tipo que é processado pelo conversor de tipos personalizado.The type of the property must match the type that is processed by your custom type converter. Com esse atributo aplicado, quando um processador XAML manipula valores dessa propriedade, ele pode processar cadeias de caracteres de entrada e retornar instâncias de objeto.With this attribute applied, when a XAML processor handles values of that property, it can process input strings and return object instances. A técnica de conversor de tipo por propriedade é particularmente ú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 TypeConverterAttribute classe e não pode aplicar uma.The per-property type converter technique is particularly useful if you choose to use a property type from Microsoft .NET Framework or from some other library where you cannot control the class definition and cannot apply a TypeConverterAttribute there.

Consulte tambémSee also