Type Converter in WPF
I have gone through this article but still i am not very much clear about Type Converter and its usage.
http://msdn.microsoft.com/en-us/library/aa970913.aspx
Can anyone please explain in what it is and what ca开发者_Go百科n be done with it in WPF.
If you have a property that is not of type string
, but you need to set it from a XAML attribute, you need to convert the string
specified in XAML to the target property type. Hence, type converters.
For example - when you set a background property in XAML, you can write "Red", in code behind you cannnot just give the Background property the string "Red" because its type is Brush. WPF uses a type converter to convert from string to brush.
WPF 4.5 Unleashed has an extensive introduction to XAML declarative language. Some pages can be read on Google Books. I'm now refering to page 26.
If we want to specify the background color of a Button
object (actually Control.Background
), this is what we need to do as long as type converters are not explicitly added (by Microsoft) to the classes we use:
<Button>
<Button.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="255" R="255" G="255" B="255" />
</SolidColorBrush.Color>
</Button.Background>
</SolidColorBrush>
</Button>
In this declaration,
<Button.Background>
<SolidColorBrush>
means we create an instance of SolidColorBrush
and assign it to Button.Background
property, which type is Brush
, an abstract type.
Similarly,
<SolidColorBrush.Color>
<Color A="255" R="255" G="255" B="255" />
means we create an instance of Color
with corresponding properties, and assign it to SolidColorBrush.Color
which type is Color
.
A first simplification is possible by using a explicit converter able to understand that the string literal White
when provided as the content of a Color
XML element must be converted into a Color
instance obtained with Color.FromArgb(255, 255, 255, 255)
. This simplification now allow us to write:
<Button>
<Button.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
White
</SolidColorBrush.Color>
</Button.Background>
</SolidColorBrush>
</Button>
The possibility to use such converter has been explicitly added to the declaration of Color
structure by specifying a type converter attribute:
[TypeConverter(typeof(ColorConverter))]
public struct Color : IFormattable, IEquatable<Color>
The converter is ColorConverter.
Let's push that a step further, and add a type converter on Brush
, the type of Control.Background.
[TypeConverter(typeof(BrushConverter))]
public abstract class Brush : Animatable, IFormattable, DUCE.IResource
This converter will replace a valid string literal content with a SolidColorBrush
instance and now allows:
<Button>
<Button.Background>
White
</SolidColorBrush>
</Button>
This is the mechanism behind simplifications allowed by XAML when interpreting the XML content. A last simplification allowed by XAML: We can use the attribute syntax of XAML rather than the element syntax:
<Button Background="White" />
Wow! we started with 9 lines of code, and ended with only one!
A last word on how a XML element string literal content is interpreted (still from the same book):
XAML Processing Rules for Object Element Children
You’ve now seen the three types of children for object elements. To avoid ambiguity, any valid XAML parser or compiler follows these rules when encountering and interpreting child elements:
If the type implements IList, call IList.Add for each child.
Otherwise, if the type implements IDictionary, call IDictionary.Add for each child, using the x:Key attribute value for the key and the element for the value. (Although XAML2009 checks IDictionary before IList and supports other collection interfaces, as described earlier.)
Otherwise, if the parent supports a content property (indicated by System.Windows.Markup.ContentPropertyAttribute) and the type of the child is compatible with that property, treat the child as its value.
Otherwise, if the child is plain text and a type converter exists to transform the child into the parent type (and no properties are set on the parent element), treat the child as the input to the type converter and use the output as the parent object instance.
Otherwise, treat it as unknown content and potentially raise an error.
To answer your question about converter benefit in a different way: This benefit comes from rule 4 above.
精彩评论