hen Microsoft set about building the Windows Presentation Foundation, one core goal was to create an environment for applications capable of both two-dimensional and three-dimensional content simultaneously. Using a traditional approach, this would have led to an abstract Button class followed by Button2D and Button3D subclasses that would override the painting rules. Tearing a page from the CSS-based Internet, Microsoft also wanted the look and feel of all controls to be controllable via styles that, when updated, would in turn update the look and feel of every component of that type in the application.
Microsoft's solution is called "Lookless" controls. A Lookless control is a control that defines the behavior
of a control without regard to how it will look when rendered. For example, a button is a control that has a normal state, a mouseover state and a clicked state. The appearance of the button could be anythingfrom the familiar grey box to an obnoxiously spinning 3D flaming corporate logo circa web design 1997 style.
All WPF controls implement a default looktypically the same as the corresponding last generation Windows Forms control. In this article you'll see how to take that ugly grey button and transform it into a glass-effect pill button for a drug information application.
XAML styling for lookless controls owes a lot of its heritage to HTML and CSS, and you can apply styling in similar ways. For example, you can define the look for all buttons in an application, restrict it to all buttons on a specific screen, to a designated group of buttons, or to apply a special style for just one button. To do that, XAML allows you to define the look of your components at several levels. In terms of actual implementation, styles are applied to components and are then available to sub-components. Logically, they can be applied to an individual component, a page or window or in an external file that can be shared by multiple pages, windows, or applications.
Each option has its place: from one-offs, to page-specific items, to styles you want applied universally across your application. When more than one style could potentially apply to the same element, the XAML renderer applies styles in order of precedence: Inline --> Component --> External File. That's the same way CSS applies styles to elements. Generally, "closer" styles take precedence over styles defined further away from elements.
You can apply inline styles directly to an element simply by adding the style dependency property to it:
<Button Content="Button Label">
For small projects or when you're in the initial development phases, you will most likely define your styles in the <Window.Resources>
of the XAML file you're currently working on. You can access styles defined in the resources
section of a file throughout the file
To define your styles in a separate file, create a XAML file with a root element of <ResourceDictionary>
instead of <Window>
. You can then reference that external XAML file in your application's window using the code below:
<ResourceDictionary Source="Resources/Common.xaml" />
It's worth noting that if you use an external XAML file on the currently released version of WPF for Visual Studio 2005, any attempt to use the designer preview will error out complaining that, "Value 'Resources\Common.xaml' cannot be assigned to the property 'Source'."
even though the syntax is correct and will work if you run the application. Due to this bug, you should build your styles in the resources section of the page until you get them the way you want them, and only then move them to an external resource file.
You can apply styles to all components of a given type, and any component can reference a named style. The difference between the two is set in the style definition itself. If the style tag defines an x:Key
then that style will only be applied to components that specifically reference that style.
The example below shows the declaration of a named style referenced by a button. The style is defined in the Windows.Resources
section and the Button itself is somewhere in the main content area of the page:
|Figure 1. The PillButton: The figure shows several buttons using the PillButton style, complete with reflection.|
<Style x:Key="PillButton" TargetType="Button">
By not defining an x:Key
, your style will be applied to all components on the page that match the TargetType
attribute value. In the following example, all buttons on the page automatically get the style defined applied to them:
shows three buttons defined using this style in their default state.