Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Illustrated WPF phần 3 ppsx
Nội dung xem thử
Mô tả chi tiết
CHAPTER 4 ■ XAML
81
The Default Content Property
Many WPF visual elements display content to the user, such as the label on a button. I’ll describe content
in more detail in Chapter 6, but for our current discussion of XAML, you need to know the following:
• Every WPF class that can have content has a property that is specified as its default
content holder. I mentioned this a bit earlier when describing the content section
of the element syntax.
• This default content property is specified using the ContentPropertyAttribute
attribute in the class declaration. (This is a .NET attribute, not a XAML attribute.)
The declaration of the default content holder might not be on the class itself, however. You
might have to burrow down the inheritance tree a bit to find it.
For example, if you go to the documentation for the WPF Button class, you won’t find mention
of this attribute. But if you go down past the ButtonBase class to the ContentControl class and look at the
C# section, you’ll find the following declaration. The parameter of the attribute contains the string
"Content", which specifies that for all classes derived from this one, it is the Content property that is the
default content holder.
Attribute Content Property
↓ ↓
[ContentPropertyAttribute("Content")]
public class ContentControl : Control, IAddChild
{ ... ↑
Class Name
Different classes have different default content holder properties. For example, if you were to
drill down from the ListBox control to its base class ItemsControl, you’d find that the ContentProperty in
this case is the Items property.
For simple content, rather than placing content between the start tag and the end tag, you
could use attribute syntax. For example, the following markup shows four button instantiations that are
semantically equivalent. They all produce identical buttons.
The first button instantiation uses simple object element syntax, with the content between the
start and end tags. The second puts the content in the start tag by using attribute syntax. The third does
the same as the second but uses the empty element syntax for the start tag. The fourth is the same as the
third except that it includes the class name as part of the attribute name.
<StackPanel>
<Button>Click Me</Button> Object Element Syntax
<Button Content="Click Me"></Button> Attribute Syntax
<Button Content="Click Me"/> Attribute Syntax, Empty Element
<Button Button.Content="Click Me"/>
</StackPanel> ↑ Attribute Syntax, Empty Element, Qualified Name
CHAPTER 4 ■ XAML
82
Type Converters for Attributes
If you look at the attribute in the following line of markup, you might notice something puzzling. From
Chapter 3 you know that the Background property of a Button must be set with an object derived from the
Brush class, but the attribute sets it with the simple string "Blue". As a matter of fact, attribute syntax
requires that attributes be set with strings.
<Button Background="Blue"> ...
So, how can you assign a string to a property that requires some other type? The short answer is
that the XAML parser converts it for you. The parser uses the class and property name to check the type
of the property, and uses a TypeConverter for that type to convert the string to an object of the type
required by the property. Figure 4-9 illustrates the process.
Figure 4-9. The XAML parser converts the string value assigned to the attribute to the object type required
by the property.
CHAPTER 4 ■ XAML
83
Property Element Syntax
So far, you’ve seen classes as elements and properties as attributes. That’s a very clean classification, but
it’s not always possible to use something as simple as an attribute for a property. To address this, XAML
also provides another syntax for setting the values of more complex properties. This is called property
element syntax, and has the following characteristics:
• The property is listed, not as an attribute inside the start tag, but using element
syntax nested in the content part of the object element.
• The element name uses a two-part name in dot-syntax notation. The name
consists of the class name and the property name, separated by a period (dot), as
shown in the following syntax code:
Class Name Property Name
↓ ↓
<ElementTypeName.PropertyName>
Value
</ElementTypeName.PropertyName>
• The property element tag cannot contain any attributes.
• Notice that although it has the syntax of an element, it does not produce an object.
It sets a property on an object.
Figure 4-10 shows the use of both attribute syntax and property element syntax to set the
Background property of a Button object. Both forms produce the same object structure, as shown at the
bottom of the figure. Notice how much simpler and easier it is to read the attribute syntax version.
Figure 4-10. The Button object using either the attribute syntax or the property element syntax specifies
the same object structure.
CHAPTER 4 ■ XAML
84
Regular attribute syntax works well when a property value is simple and can be expressed by a
simple string⎯like the Background property of Button, as shown in the previous example. In that case,
the simple string on the right side of the assignment operator is much easier to read than the property
element syntax.
Some properties, however, are too complex to be set with a simple string. They might, for
example, contain multiple items or complex parts. The following markup shows an example of this. It
sets the Background of the Button, not to a simple brush but to a LinearGradientBrush. In this case,
specifying the LinearGradientBrush requires too much information to use a simple string, and therefore
requires the property element syntax. Other properties can be even more complex.
<Button>
<Button.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Red" Offset="0.0" />
<GradientStop Color="Blue" Offset="1.0" />
</LinearGradientBrush>
</Button.Background>
Click Me
</Button>
■ Note In general, you should use attribute syntax if possible, since it’s simpler and easier to understand. Use
property element syntax only for complex attributes that can’t be handled by attribute syntax.
Attached Property Syntax
Attached properties are a special type of property that is defined in one class but used in another. I’ll
explain attached properties in detail in Chapter 7. Here I just want to describe their syntax, since it looks
similar to property element syntax.
The following markup shows an example of using an attached property. If you look at the
Button declaration, you’ll see an attribute assignment to a property called Grid.Row. Notice that the class
name is Grid—not Button. That’s because the Row property is not declared in the Button class but in the
Grid class. This is an attached property.
<Button Grid.Row="2">Click</Button>
↑
Attached Property
You can distinguish an attached property from property element syntax by the fact that in an
attached property the class name is different from the class being instantiated, while in property
element syntax, the class name is the same as the object being instantiated.
CHAPTER 4 ■ XAML
85
Reviewing the XAML Syntax Forms
Although the XAML syntax forms are quite simple, they can sometimes be confusing when they’re first
encountered. Figure 4-11 summarizes the concepts.
Figure 4-11. A summary of the XAML syntax forms
Top-Level Elements
As mentioned earlier in the chapter, every XAML document must have a single, top-level element. Three
classes are used by WPF programs as top-level elements—Window, Application, and Page.
You’ve seen that Window and Application are used in Visual Studio’s WPF Application template
to build standard WPF applications. The Page class is used to build applications that use page-based
navigation, which I’ll cover in Chapter 14. XamlPad also uses the Page class.