Control WPF
Control WPF
Control WPF
Controls
Controls by Category
WPF Content Model
Control Library
Border
Animate a BorderThickness Value
BulletDecorator
Button
Create a Button That Has an Image
Calendar
Canvas
How-to Topics
Wrap a Border Around the Content of a Canvas
Get or Set Canvas Positioning Properties
Create and Use a Canvas
Use the Attached Properties of Canvas to Position Child Elements
Resize a Canvas by Using a Thumb
CheckBox
ComboBox
ContextMenu
ContextMenu Overview
DataGrid
Default Keyboard and Mouse Behavior in the DataGrid Control
How to: Add Row Details to a DataGrid Control
How to: Group, Sort, and Filter Data in the DataGrid Control
How to: Implement Validation with the DataGrid Control
Walkthrough: Display Data from a SQL Server Database in a DataGrid Control
Sizing Options in the DataGrid Control
DatePicker
DockPanel
How-to Topics
Get or Set a Dock Value
Create a DockPanel
Partition Space by Using the DockPanel Element
DocumentViewer
Expander
Expander Overview
How-to Topics
Create an Expander with a ScrollViewer
FlowDocumentPageViewer
FlowDocumentReader
FlowDocumentScrollViewer
Frame
Grid
How-to Topics
Build a Standard UI Dialog Box by Using Grid
Create a Complex Grid
Create a Grid Element
Create and Use a GridLengthConverter Object
Manipulate Columns and Rows by Using ColumnDefinitionsCollections and
RowDefinitionsCollections
Position the Child Elements of a Grid
Share Sizing Properties Between Grids
GridSplitter
How-to Topics
Resize Rows with a GridSplitter
Resize Columns with a GridSplitter
Make Sure That a GridSplitter Is Visible
GroupBox
Define a GroupBox Template
Image
How-to Topics
Use the Image Element
Convert an Image to Greyscale
Crop an Image
Rotate an Image
Label
Create a Control That Has an Access Key and Text Wrapping
ListBox
How-to Topics
Bind a ListBox to Data
Get a ListBoxItem
Improve the Scrolling Performance of a ListBox
ListView
Overviews
ListView Overview
GridView Overview
GridView Column Header Styles and Templates Overview
How-to Topics
Sort a GridView Column When a Header Is Clicked
Create a Custom View Mode for a ListView
Use Templates to Style a ListView That Uses GridView
Create a Style for a Dragged GridView Column Header
Display ListView Contents by Using a GridView
Use Triggers to Style Selected Items in a ListView
Create ListViewItems with a CheckBox
Display Data by Using GridViewRowPresenter
Group Items in a ListView That Implements a GridView
Style a Row in a ListView That Implements a GridView
Change the Horizontal Alignment of a Column in a ListView
Handle the MouseDoubleClick Event for Each Item in a ListView
Menu
Menu Overview
Panel
Panels Overview
How-to Topics
Create a Custom Panel Element
Override the Panel OnRender Method
Set the Height Properties of an Element
Set the Width Properties of an Element
PasswordBox
Popup
Popup Overview
Popup Placement Behavior
How-to Topics
Animate a Popup
Specify a Custom Popup Position
ProgressBar
PrintDialog
RadioButton
RepeatButton
RichTextBox
RichTextBox Overview
How-to Topics
Extract the Text Content from a RichTextBox
Change Selection in a RichTextBox Programmatically
Save, Load, and Print RichTextBox Content
Position a Custom Context Menu in a RichTextBox
ScrollBar
Customize the Thumb Size on a ScrollBar
ScrollViewer
ScrollViewer Overview
How-to Topics
Handle the ScrollChanged Event
Scroll Content by Using the IScrollInfo Interface
Use the Content-Scrolling Methods of ScrollViewer
Separator
Slider
Customize the Ticks on a Slider
StackPanel
How-to Topics
Choose Between StackPanel and DockPanel
Create a StackPanel
Horizontally or Vertically Align Content in a StackPanel
StatusBar
TabControl
TextBlock
TextBlock Overview
TextBox
TextBox Overview
How-to Topics
Create a Multiline TextBox Control
Detect When Text in a TextBox Has Changed
Enable Tab Characters in a TextBox Control
Get a Collection of Lines from a TextBox
Make a TextBox Control Read-Only
Position the Cursor at the Beginning or End of Text in a TextBox Control
Retrieve a Text Selection
Set Focus in a TextBox Control
Set the Text Content of a TextBox Control
Enable Spell Checking in a Text Editing Control
Use a Custom Context Menu with a TextBox
Use Spell Checking with a Context Menu
Add a Watermark to a TextBox
ToolBar
ToolBar Overview
Style Controls on a ToolBar
ToolTip
ToolTip Overview
How-to Topics
Position a ToolTip
Use the BetweenShowDelay Property
TreeView
TreeView Overview
How-to Topics
Create Simple or Complex TreeViews
Use SelectedValue, SelectedValuePath, and SelectedItem
Bind a TreeView to Data That Has an Indeterminable Depth
Improve the Performance of a TreeView
Find a TreeViewItem in a TreeView
WrapPanel
Viewbox
Apply Stretch Properties to the Contents of a Viewbox
Styles and Templates
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
How to: Find ControlTemplate-Generated Elements
Control Customization
Control Authoring Overview
Creating a Control That Has a Customizable Appearance
Guidelines for Designing Stylable Controls
Adorners
Adorners Overview
How-to Topics
Implement an Adorner
Bind an Adorner to an Element
Adorn the Children of a Panel
Remove an Adorner from an Element
Remove all Adorners from an Element
Control Styles and Templates
Button Styles and Templates
Calendar Styles and Templates
CheckBox Styles and Templates
ComboBox Styles and Templates
ContextMenu Styles and Templates
DataGrid Styles and Templates
DatePicker Styles and Templates
DocumentViewer Styles and Templates
Expander Styles and Templates
Frame Styles and Templates
GroupBox Styles and Templates
Label Styles and Templates
ListBox Styles and Templates
ListView Styles and Templates
Menu Styles and Templates
NavigationWindow Styles and Templates
PasswordBox Syles and Templates
ProgressBar Styles and Templates
RadioButton Styles and Templates
RepeatButton Syles and Templates
ScrollBar Styles and Templates
ScrollViewer Styles and Templates
Slider Styles and Templates
StatusBar Styles and Templates
TabControl Styles and Templates
TextBox Styles and Templates
Thumb Syles and Templates
ToggleButton Syles and Templates
ToolBar Styles and Templates
ToolTip Styles and Templates
TreeView Styles and Templates
Window Styles and Templates
UI Automation of a WPF Custom Control
Walkthroughs: Create a Custom Animated Button
Create a Button by Using Microsoft Expression Blend
Create a Button by Using XAML
Controls
5/4/2018 • 7 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) ships with many of the common UI components that are used in almost
every Windows application, such as Button, Label, TextBox, Menu, and ListBox. Historically, these objects have
been referred to as controls. While the WPF SDK continues to use the term "control" to loosely mean any class
that represents a visible object in an application, it is important to note that a class does not need to inherit from
the Control class to have a visible presence. Classes that inherit from the Control class contain a ControlTemplate,
which allows the consumer of a control to radically change the control's appearance without having to create a
new subclass. This topic discusses how controls (both those that do inherit from the Control class and those that
do not) are commonly used in WPF.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label>
Enter your first name:
</Label>
<TextBox Grid.Row="0" Grid.Column="1"
Name="firstName" Margin="0,5,10,5"/>
The following example creates the same application in code. For brevity, the creation of the Grid, grid1 , has been
excluded from the sample. grid1 has the same column and row definitions as shown in the preceding XAML
example.
Label firstNameLabel;
Label lastNameLabel;
TextBox firstName;
TextBox lastName;
Button submit;
Button clear;
void CreateControls()
{
firstNameLabel = new Label();
firstNameLabel.Content = "Enter your first name:";
grid1.Children.Add(firstNameLabel);
}
Private firstNameLabel As Label
Private lastNameLabel As Label
Private firstName As TextBox
Private lastName As TextBox
Private submit As Button
Private clear As Button
Sub CreateControls()
firstNameLabel = New Label()
firstNameLabel.Content = "Enter your first name:"
grid1.Children.Add(firstNameLabel)
</Button.Background>
View message
</Button>
submit.Background = buttonBrush;
submit.FontSize = 14;
submit.FontWeight = FontWeights.Bold;
submit.Background = buttonBrush
submit.FontSize = 14
submit.FontWeight = FontWeights.Bold
<Style TargetType="Button">
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="Green" Offset="0.0" />
<GradientStop Color="White" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
You can also apply a style to only certain controls of a specific type by assigning a key to the style and specifying
that key in the Style property of your control. For more information about styles, see Styling and Templating.
Creating a ControlTemplate
A Style allows you to set properties on multiple controls at a time, but sometimes you might want to customize
the appearance of a Control beyond what you can do by creating a Style. Classes that inherit from the Control
class have a ControlTemplate, which defines the structure and appearance of a Control. The Template property of a
Control is public, so you can give a Control a ControlTemplate that is different than its default. You can often
specify a new ControlTemplate for a Control instead of inheriting from a control to customize the appearance of a
Control.
Consider the very common control, Button. The primary behavior of a Button is to enable an application to take
some action when the user clicks it. By default, the Button in WPF appears as a raised rectangle. While developing
an application, you might want to take advantage of the behavior of a Button--that is, by handling the button's click
event--but you might change the button's appearance beyond what you can do by changing the button's
properties. In this case, you can create a new ControlTemplate.
The following example creates a ControlTemplate for a Button. The ControlTemplate creates a Button with
rounded corners and a gradient background. The ControlTemplate contains a Border whose Background is a
LinearGradientBrush with two GradientStop objects. The first GradientStop uses data binding to bind the Color
property of the GradientStop to the color of the button's background. When you set the Background property of
the Button, the color of that value will be used as the first GradientStop. For more information about data binding,
see Data Binding Overview. The example also creates a Trigger that changes the appearance of the Button when
IsPressed is true .
<!--Define a template that creates a gradient-colored button.-->
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="Border"
CornerRadius="20"
BorderThickness="1"
BorderBrush="Black">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="{Binding Background.Color,
RelativeSource={RelativeSource TemplatedParent}}"
Offset="0.0" />
<GradientStop Color="White" Offset="0.9" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<!--Change the appearance of
the button when the user clicks it.-->
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="{Binding Background.Color,
RelativeSource={RelativeSource TemplatedParent}}"
Offset="0.0" />
<GradientStop Color="DarkSlateGray" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
NOTE
The Background property of the Button must be set to a SolidColorBrush for the example to work properly.
Subscribing to Events
You can subscribe to a control's event by using either XAML or code, but you can only handle an event in code.
The following example shows how to subscribe to the Click event of a Button.
<Button Grid.Row="2" Grid.ColumnSpan="2" Name="submitName" Click="submit_Click"
Background="Green">View message</Button>
See Also
Styling and Templating
Controls by Category
Control Library
Data Templating Overview
Data Binding Overview
Input
Enable a Command
Walkthroughs: Create a Custom Animated Button
Control Customization
Controls by Category
5/4/2018 • 2 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) controls can be logically grouped into several categories. These
categories can be used to select the appropriate control for your scenario by helping you see which controls have
similar usage patterns or functionality.
Layout
Layout controls are used to manage the size, dimensions, position, and arrangement of child elements.
Border
BulletDecorator
Canvas
DockPanel
Expander
Grid
GridSplitter
GroupBox
Panel
ResizeGrip
Separator
ScrollBar
ScrollViewer
StackPanel
Thumb
Viewbox
VirtualizingStackPanel
Window
WrapPanel
Buttons
Buttons are one of the most basic user interface controls. Applications typically perform some task in the Click
event when a user clicks on them.
Button
RepeatButton
Data Display
Data display controls are used to show information from a data source.
DataGrid
ListView
TreeView
Menus
Menus are used to group related actions or to provide contextual assistance.
ContextMenu
Menu
ToolBar
Selection
Selection controls are used to enable a user to select one or more options.
CheckBox
ComboBox
ListBox
RadioButton
Slider
Navigation
Navigation controls enhance or extend the application navigation experience by creating targeting frames or
tabbed application appearance.
Frame
Hyperlink
Page
NavigationWindow
TabControl
Dialog Boxes
Dialog boxes provide targeted support for common user-interaction scenarios such as printing.
OpenFileDialog
PrintDialog
SaveFileDialog
User Information
User information controls provide contextual feedback or clarify an application's user interface. The user typically
cannot interact with these controls.
AccessText
Label
Popup
ProgressBar
StatusBar
TextBlock
ToolTip
Documents
WPF includes several specialized controls for viewing documents. These controls optimize the reading experience,
based on the targeted user scenario.
DocumentViewer
FlowDocumentPageViewer
FlowDocumentReader
FlowDocumentScrollViewer
StickyNoteControl
Input
Input controls enable the user to input text and other content.
TextBox
RichTextBox
PasswordBox
Media
WPF includes integrated support for hosting both audio and video content, as well as [codecs] for most popular
image formats.
Image
MediaElement
SoundPlayerAction
Digital Ink
Digital ink controls provide integrated support for Tablet PC features, such as ink viewing and ink input.
InkCanvas
InkPresenter
See Also
Control Library
WPF Content Model
5/4/2018 • 4 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) is a presentation platform that provides many controls and control-like
types whose primary purpose is to display different types of content. To determine which control to use or which
control to derive from, you should understand the kinds of objects a particular control can best display.
This topic summarizes the content model for WPF control and control-like types. The content model describes
what content can be used in a control. This topic also lists the content properties for each content model. A content
property is a property that is used to store the content of the object.
Controls that inherit from these classes can contain the same type of content and treat the content in the same
way. The following illustration shows one control from each content model that contains an image and some text.
The FlowDocument implements the IDocumentPaginatorSource interface; therefore, all three classes can take a
FlowDocument as content.
See Also
Advanced
Control Library
8/31/2018 • 2 minutes to read • Edit Online
The Windows Presentation Foundation (WPF ) control library contains information on the controls provided by
Windows Presentation Foundation (WPF ), listed alphabetically.
In This Section
Border
BulletDecorator
Button
Calendar
Canvas
CheckBox
ComboBox
ContextMenu
DataGrid
DatePicker
DockPanel
DocumentViewer
Expander
FlowDocumentPageViewer
FlowDocumentReader
FlowDocumentScrollViewer
Frame
Grid
GridSplitter
GroupBox
Image
Label
ListBox
ListView
Menu
Panel
PasswordBox
Popup
ProgressBar
PrintDialog
RadioButton
RepeatButton
Ribbon (WPF )
RichTextBox
ScrollBar
ScrollViewer
Separator
Slider
StackPanel
StatusBar
TabControl
TextBlock
TextBox
ToolBar
ToolTip
TreeView
WrapPanel
Viewbox
Reference
System.Windows.Controls
System.Windows.Controls.Primitives
Related Sections
Control Customization
Controls by Category
WPF Content Model
Border
5/4/2018 • 2 minutes to read • Edit Online
The following sample demonstrates how to dynamically change properties of the Border element.
In This Section
Animate a BorderThickness Value
Reference
Decorator
Border
Related Sections
Panels Overview
Alignment, Margins, and Padding Overview
How to: Animate a BorderThickness Value
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to animate changes to the thickness of a border by using the ThicknessAnimation class.
Example
The following example animates the thickness of a border by using ThicknessAnimation. The example uses the
BorderThickness property of Border.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Media;
namespace SDKSamples
{
public class ThicknessAnimationExample : Page
{
public ThicknessAnimationExample()
{
Content = myStackPanel;
}
}
}
Imports Microsoft.VisualBasic
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Shapes
Imports System.Windows.Media.Animation
Imports System.Windows.Media
Namespace SDKSamples
Public Class ThicknessAnimationExample
Inherits Page
Public Sub New()
Content = myStackPanel
End Sub
End Class
End Namespace
For the complete sample, see Animation Example Gallery.
See Also
ThicknessAnimation
BorderThickness
Border
Animation Overview
Animation and Timing
How -to Topics
Animate the Thickness of a Border by Using Key Frames
BulletDecorator
5/4/2018 • 2 minutes to read • Edit Online
BulletDecorator has two content properties: Bullet and Child. The Bullet property defines the UIElement to use as a
bullet. The Child property defines a UIElement that visually aligns with the bullet.
The following illustration shows examples of controls that use a BulletDecorator.
Reference
BulletDecorator
Button
5/4/2018 • 2 minutes to read • Edit Online
A Button control reacts to user input from a mouse, keyboard, stylus, or other input device and raises a Click event.
A Button is a basic user interface (UI) component that can contain simple content, such as text, and can also contain
complex content, such as images and Panel controls.
In This Section
Create a Button That Has an Image
Reference
Button
ButtonBase
RadioButton
RepeatButton
How to: Create a Button That Has an Image
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example creates two Button controls. One Button contains text and the other contains an image. The
image is in a folder called data, which is a subfolder of the example’s project folder. When a user clicks the Button
that has the image, the background and the text of the other Button change.
This example creates Button controls by using markup but uses code to write the Click event handlers.
See Also
Controls
Control Library
Calendar
5/4/2018 • 2 minutes to read • Edit Online
Calendar controls
The following table provides information about tasks that are typically associated with the Calendar.
TASK IMPLEMENTATION
Have the Calendar display a month, an entire year, or a Set the DisplayMode property to Month, Year, or Decade.
decade.
Specify whether the user can select a date, a range of dates, or Use the SelectionMode.
multiple ranges of dates.
Specify the range of dates that the Calendar displays. Use the DisplayDateStart and DisplayDateEnd properties.
Specify whether the current date is highlighted. Use the IsTodayHighlighted property. By default,
IsTodayHighlighted is true .
Change the size of the Calendar. Use a Viewbox or set the LayoutTransform property to a
ScaleTransform. Note that if you set the Width and Height
properties of a Calendar, the actual calendar does not change
its size.
The Calendar control provides basic navigation using either the mouse or keyboard. The following table
summarizes keyboard navigation.
See Also
Controls
Styling and Templating
Canvas
5/4/2018 • 2 minutes to read • Edit Online
In This Section
How -to Topics
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
Canvas How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the Canvas element to absolutely position child elements.
In This Section
Wrap a Border Around the Content of a Canvas
Get or Set Canvas Positioning Properties
Create and Use a Canvas
Use the Attached Properties of Canvas to Position Child Elements
Resize a Canvas by Using a Thumb
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
How to: Wrap a Border Around the Content of a
Canvas
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example shows how to display Hello World! inside a Canvas element. The Canvas element is
wrapped by a Border element so that a border outlines the element.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Border
BorderThickness="2"
BorderBrush="Black"
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="100"
Height="100">
<Canvas>
<TextBlock Canvas.Top="10" Canvas.Left="20">Hello World!</TextBlock>
</Canvas>
</Border>
</Page>
See Also
Canvas
Border
Panels Overview
How to: Get or Set Canvas Positioning Properties
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the positioning methods of the Canvas element to position child content. This
example uses content in a ListBoxItem to represent positioning values and converts the values into instances of
Double, which is a required argument for positioning. The values are then converted back into strings and
displayed as text in a TextBlock element by using the GetLeft method.
Example
The following example creates a ListBox element that has eleven selectable ListBoxItem elements. The
SelectionChanged event triggers the ChangeLeft custom method, which the subsequent code block defines.
Each ListBoxItem represents a Double value, which is one of the arguments that the SetLeft method of Canvas
accepts. In order to use a ListBoxItem to represent an instance of Double, you must first convert the ListBoxItem to
the correct data type.
When a user changes the ListBox selection, it invokes the ChangeLeft custom method. This method passes the
ListBoxItem to a LengthConverter object, which converts the Content of a ListBoxItem to an instance of Double
(notice that this value has already been converted to a String by using the ToString method). This value is then
passed back to the SetLeft and GetLeft methods of Canvas in order to change the position of the text1 object.
See Also
Canvas
ListBoxItem
LengthConverter
Panels Overview
How to: Create and Use a Canvas
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example explicitly positions two TextBlock elements by using the SetTop and SetLeft methods of
Canvas. The example also assigns a Background color of LightSteelBlue to the Canvas.
NOTE
When you use Extensible Application Markup Language (XAML) to position TextBlock elements, use the Top and Left
properties.
// Add a second text element to show how absolute positioning works in a Canvas
TextBlock txt2 = new TextBlock();
txt2.FontSize = 22;
txt2.Text = "Isn't absolute positioning handy?";
Canvas.SetTop(txt2, 200);
Canvas.SetLeft(txt2, 75);
myCanvas.Children.Add(txt2);
mainWindow.Content = myCanvas;
mainWindow.Title = "Canvas Sample";
mainWindow.Show();
}
}
WindowTitle = "Canvas Sample"
'Create a Canvas as the root Panel
Dim myCanvas As New Canvas()
myCanvas.Background = Brushes.LightSteelBlue
'Add a second text element to show how absolute positioning works in a Canvas
Dim txt2 As New TextBlock
txt2.FontSize = 22
txt2.Text = "Isn't absolute positioning handy?"
Canvas.SetLeft(txt2, 75)
Canvas.SetTop(txt2, 200)
myCanvas.Children.Add(txt2)
Me.Content = myCanvas
See Also
Canvas
TextBlock
SetTop
SetLeft
Top
Left
Panels Overview
How -to Topics
How to: Use the Attached Properties of Canvas to
Position Child Elements
9/8/2018 • 2 minutes to read • Edit Online
This example shows how to use the attached properties of Canvas to position child elements.
Example
The following example adds four Button elements as child elements of a parent Canvas. Each element is
represented by a Bottom, Left, Right, and Top. Each Button is positioned relative to the parent Canvas and
according to its assigned property value.
// Create the application's main window
mainWindow = gcnew System::Windows::Window();
mainWindow->Title = "Canvas Attached Properties Sample";
// Add a Border
Border^ myBorder = gcnew Border();
myBorder->HorizontalAlignment = HorizontalAlignment::Left;
myBorder->VerticalAlignment = VerticalAlignment::Top;
myBorder->BorderBrush = Brushes::Black;
myBorder->BorderThickness = System::Windows::Thickness(2);
// Add a Border
Border myBorder = new Border();
myBorder.HorizontalAlignment = HorizontalAlignment.Left;
myBorder.VerticalAlignment = VerticalAlignment.Top;
myBorder.BorderBrush = Brushes.Black;
myBorder.BorderThickness = new Thickness(2);
See Also
Canvas
Bottom
Left
Right
Top
Button
Panels Overview
How -to Topics
Attached Properties Overview
How to: Resize a Canvas by Using a Thumb
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to use a Thumb control to resize a Canvas control.
Example
The Thumb control provides drag functionality that can be used to move or resize controls by monitoring the
DragStarted, DragDelta and DragCompleted events of the Thumb.
The user begins a drag operation by pressing the left mouse button when the mouse pointer is paused on the
Thumb control. The drag operation continues as long as the left mouse button remains pressed. During the drag
operation, the DragDelta can occur more than once. Each time it occurs, the DragDeltaEventArgs class provides
the change in position that corresponds to the change in mouse position. When the user releases the left mouse
button, the drag operation is finished. The drag operation only provides new coordinates; it does not automatically
reposition the Thumb.
The following example shows a Thumb control that is the child element of a Canvas control. The event handler for
its DragDelta event provides the logic to move the Thumb and resize the Canvas. The event handlers for the
DragStarted and DragCompleted event change the color of the Thumb during a drag operation. The following
example defines the Thumb.
The following example shows the DragDelta event handler that moves the Thumb and resizes the Canvas in
response to a mouse movement.
See Also
Thumb
DragStarted
DragDelta
DragCompleted
CheckBox
5/4/2018 • 2 minutes to read • Edit Online
You can use a CheckBox in the user interface (UI) of your application to represent options that a user can select or
clear. You can use a single check box or you can group two or more check boxes.
The following graphic shows the different states of a CheckBox.
Reference
CheckBox
RadioButton
ButtonBase
RepeatButton
Related Sections
ComboBox
8/31/2018 • 2 minutes to read • Edit Online
The ComboBox control presents users with a list of options. The list is shown and hidden as the control expands
and collapses. In its default state, the list is collapsed, displaying only one choice. The user clicks a button to see the
complete list of options.
The following illustration shows a ComboBox in different states.
In This Section
How to: Get a ComboBoxItem
Reference
ComboBox
ContextMenu
5/4/2018 • 2 minutes to read • Edit Online
The ContextMenu allows a control to display a Menu that is specific to the context of the control. Typically, the
ContextMenu is exposed in the user interface (UI) through the right mouse button or through the keyboard’s
menu button.
The following figure illustrates a ContextMenu in two different states: the default state and the open state. In the
default state, the control is collapsed. When the right mouse button is pressed over the parent of the menu, the
control expands and displays the menu items.
In This Section
ContextMenu Overview
Reference
ContextMenu
Related Sections
ContextMenu Overview
8/31/2018 • 2 minutes to read • Edit Online
The ContextMenu class represents the element that exposes functionality by using a context-specific Menu.
Typically, a user exposes the ContextMenu in the user interface (UI) by right-clicking the mouse button. This topic
introduces the ContextMenu element and provides examples of how to use it in Extensible Application Markup
Language (XAML ) and code.
ContextMenu Control
A ContextMenu is attached to a specific control. The ContextMenu element enables you to present users with a list
of items that specify commands or options that are associated with a particular control, for example, a Button.
Users right-click the control to make the menu appear. Typically, clicking a MenuItem opens a submenu or causes
an application to carry out a command.
Creating ContextMenus
The following examples show how to create a ContextMenu with submenus. The ContextMenu controls are
attached to button controls.
btn.Background = Brushes.Red
btn.Height = 30
btn.Content = "Created with Visual Basic."
btn.ContextMenu = (contextmenu)
cv2.Children.Add(btn)
The following example uses the Trigger element to change the appearance of a Menu in response to events that
are raised on the ContextMenu. When a user moves the mouse over the menu, the appearance of the
ContextMenu items changes.
See Also
ContextMenu
Style
Menu
MenuItem
ContextMenu
ContextMenu Styles and Templates
WPF Controls Gallery Sample
DataGrid
5/4/2018 • 2 minutes to read • Edit Online
The DataGrid control enables you to display and edit data from many different sources, such as from a SQL
database, LINQ query, or any other bindable data source. For more information, see Binding Sources Overview.
Columns can display text, controls, such as a ComboBox, or any other WPF content, such as images, buttons, or
any content contained in a template. You can use a DataGridTemplateColumn to display data defined in a template.
The following table lists the column types that are provided by default.
DataGridTextColumn String
DataGridCheckBoxColumn Boolean
DataGridComboBoxColumn Enum
DataGridHyperlinkColumn Uri
DataGrid can be customized in appearance, such as cell font, color, and size. DataGrid supports all styling and
templating functionality of other WPF controls. DataGrid also includes default and customizable behaviors for
editing, sorting, and validation.
The following table lists some of the common tasks for DataGrid and how to accomplish them. By viewing the
related API, you can find more information and sample code.
SCENARIO APPROACH
Alternating background colors Set the AlternationIndex property to 2 or more, and then
assign a Brush to the RowBackground and
AlternatingRowBackground properties.
Define cell and row selection behavior Set the SelectionMode and SelectionUnit properties.
Customize the visual appearance of headers, cells, and rows Apply a new Style to the ColumnHeaderStyle,
RowHeaderStyle, CellStyle, or RowStyle properties.
Set sizing options Set the Height, MaxHeight, MinHeight, Width, MaxWidth, or
MinWidth properties. For more information, see Sizing
Options in the DataGrid Control.
Access selected items Check the SelectedCells property to get the selected cells and
the SelectedItems property to get the selected rows. For more
information, see SelectedCells.
Use XML data as the data source Bind the ItemsSource on the DataGrid to the XPath query
that represents the collection of items. Create each column in
the DataGrid. Bind each column by setting the XPath on the
binding to the query that gets the property on the item
source. For an example, see DataGridTextColumn.
Related Topics
TITLE DESCRIPTION
Walkthrough: Display Data from a SQL Server Database in a Describes how to set up a new WPF project, add an Entity
DataGrid Control Framework Element, set the source, and display the data in a
DataGrid.
How to: Add Row Details to a DataGrid Control Describes how to create row details for a DataGrid.
How to: Implement Validation with the DataGrid Control Describes how to validate values in DataGrid cells and rows,
and display validation feedback.
Default Keyboard and Mouse Behavior in the DataGrid Describes how to interact with the DataGrid control by using
Control the keyboard and mouse.
How to: Group, Sort, and Filter Data in the DataGrid Control Describes how to view data in a DataGrid in different ways by
grouping, sorting, and filtering the data.
Sizing Options in the DataGrid Control Describes how to control absolute and automatic sizing in the
DataGrid.
See Also
DataGrid
Styling and Templating
Data Binding Overview
Data Templating Overview
Controls
WPF Content Model
Default Keyboard and Mouse Behavior in the
DataGrid Control
5/4/2018 • 6 minutes to read • Edit Online
This topic describes how users can interact with the DataGrid control by using the keyboard and mouse.
Typical interactions with the DataGrid include navigation, selection, and editing. Selection behavior is affected by
the SelectionMode and SelectionUnit properties. The default values that cause the behavior described in this topic
are DataGridSelectionMode.Extended and DataGridSelectionUnit.FullRow. Changing these values might cause
behavior that is different from that described. When a cell is in edit mode, the editing control might override the
standard keyboard behavior of the DataGrid.
DOWN ARROW Moves the focus to the cell directly below the current cell. If
the focus is in the last row, pressing the DOWN ARROW does
nothing.
UP ARROW Moves the focus to the cell directly above the current cell. If
the focus is in the first row, pressing the UP ARROW does
nothing.
LEFT ARROW Moves the focus to the previous cell in the row. If the focus is
in the first cell in the row, pressing the LEFT ARROW does
nothing.
RIGHT ARROW Moves the focus to the next cell in the row. If the focus is in
the last cell in the row, pressing the RIGHT ARROW does
nothing.
HOME Moves the focus to the first cell in the current row.
END Moves the focus to the last cell in the current row.
PAGE DOWN If rows are not grouped, scrolls the control downward by the
number of rows that are fully displayed. Moves the focus to
the last fully displayed row without changing columns.
If rows are grouped, moves the focus to the last row in the
DataGrid without changing columns.
PAGE UP If rows are not grouped, scrolls the control upward by the
number of rows that are fully displayed. Moves focus to the
first displayed row without changing columns.
If rows are grouped, moves the focus to the first row in the
DataGrid without changing columns.
KEY OR KEY COMBINATION DESCRIPTION
TAB Moves the focus to the next cell in the current row. If the
focus is in the last cell of the row, moves the focus to the first
cell in the next row. If the focus is in the last cell in the control,
moves the focus to the next control in the tab order of the
parent container.
SHIFT+TAB Moves the focus to the previous cell in the current row. If the
focus is already in the first cell of the row, moves the focus to
the last cell in the previous row. If the focus is in the first cell in
the control, moves the focus to the previous control in the tab
order of the parent container.
CTRL+DOWN ARROW Moves the focus to the last cell in the current column.
CTRL+UP ARROW Moves the focus to the first cell in the current column.
CTRL+RIGHT ARROW Moves the focus to the last cell in the current row.
CTRL+LEFT ARROW Moves the focus to the first cell in the current row.
ENTER Commits any changes to the current cell and row and moves
the focus to the cell directly below the current cell. If the focus
is in the last row, commits any changes without moving the
focus.
ESC If the control is in edit mode, cancels the edit and reverts any
changes that were made in the control. If the underlying data
source implements IEditableObject, pressing ESC a second
time cancels edit mode for the entire row.
BACKSPACE Deletes the character before the cursor when editing a cell.
DELETE Deletes the character after the cursor when editing a cell.
KEY OR KEY COMBINATION DESCRIPTION
CTRL+ENTER Commits any changes to the current cell without moving the
focus.
Selection Keys
If the SelectionMode property is set to Extended, the navigation behavior does not change, but navigating with the
keyboard while pressing SHIFT (including CTRL+SHIFT) will modify a multi-row selection. Before navigation
starts, the control marks the current row as an anchor row. When you navigate while pressing SHIFT, the selection
includes all rows between the anchor row and the current row.
The following selection keys modify multi-row selection.
SHIFT+DOWN ARROW
SHIFT+UP ARROW
SHIFT+PAGE DOWN
SHIFT+PAGE UP
CTRL+SHIFT+DOWN ARROW
CTRL+SHIFT+UP ARROW
CTRL+SHIFT+HOME
CTRL+SHIFT+END
Click an unselected row Makes the clicked row the current row, and the clicked cell the
current cell.
Click the current cell Puts the current cell into edit mode.
Click the Select All button at the top left corner of the If SelectionMode is set to Extended, selects all rows in the
DataGrid DataGrid.
Mouse Selection
If the SelectionMode property is set to Extended, clicking a row while pressing CTRL or SHIFT will modify a multi-
row selection.
When you click a row while pressing CTRL, the row will change its selection state while all other rows retain their
current selection state. Do this to select non-adjacent rows.
When you click a row while pressing SHIFT, the selection includes all rows between the current row and an anchor
row located at the position of the current row prior to the click. Subsequent clicks while pressing SHIFT change the
current row, but not the anchor row. Do this to select a range of adjacent rows.
CTRL+SHIFT can be combined to select non-adjacent ranges of adjacent rows. To do this, select the first range by
using SHIFT+click as described earlier. After the first range of rows is selected, use CTRL+click to select the first
row in the next range, and then click the last row in the next range while pressing CTRL+SHIFT.
See Also
DataGrid
SelectionMode
How to: Add Row Details to a DataGrid Control
5/4/2018 • 3 minutes to read • Edit Online
When using the DataGrid control, you can customize the data presentation by adding a row details section. Adding
a row details section enables you to group some data in a template that is optionally visible or collapsed. For
example, you can add row details to a DataGrid that presents only a summary of the data for each row in the
DataGrid, but presents more data fields when the user selects a row. You define the template for the row details
section in the RowDetailsTemplate property. The following illustration shows an example of a row details section.
You define the row details template as either inline XAML or as a resource. Both approaches are shown in the
following procedures. A data template that is added as a resource can be used throughout the project without re-
creating the template. A data template that is added as inline XAML is only accessible from the control where it is
defined.
To display row details by using inline XAML
1. Create a DataGrid that displays data from a data source.
2. In the DataGrid element, add a RowDetailsTemplate element.
3. Create a DataTemplate that defines the appearance of the row details section.
The following XAML shows the DataGrid and how to define the RowDetailsTemplate inline. The DataGrid
displays three values in each row and three more values when the row is selected.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<Grid>
<DataGrid Name="dataGrid1" IsReadOnly="True" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Company Name" Binding="{Binding CompanyName}">
</DataGridTextColumn>
<DataGridTextColumn Header="Contact First Name" Binding="{Binding FirstName}">
</DataGridTextColumn>
<DataGridTextColumn Header="Contact Last Name" Binding="{Binding LastName}">
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Email: " VerticalAlignment="Center" />
<TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding
EmailAddress}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Phone: " VerticalAlignment="Center" />
<TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding
Phone}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Sales Person: "
VerticalAlignment="Center" />
<TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding
SalesPerson}" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
The following code shows the query that is used to select the data that is displayed in the DataGrid. In this
example, the query selects data from an entity that contains customer information.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
AdventureWorksLT2008Entities advenWorksEntities = new AdventureWorksLT2008Entities();
var query =
from customer in customers
orderby customer.CompanyName
select new
{
customer.LastName,
customer.FirstName,
customer.CompanyName,
customer.Title,
customer.EmailAddress,
customer.Phone,
customer.SalesPerson
};
dataGrid1.ItemsSource = query.ToList();
}
dataGrid1.ItemsSource = query.ToList()
End Sub
4. On the DataTemplate, set the x:Key Directive to a value that uniquely identifies the data template.
5. In the DataGrid element, set the RowDetailsTemplate property to the resource defined in the previous steps.
Assign the resource as a static resource.
The following XAML shows the RowDetailsTemplate property set to the resource from the previous
example.
It is often useful to view data in a DataGrid in different ways by grouping, sorting, and filtering the data. To group,
sort, and filter the data in a DataGrid, you bind it to a CollectionView that supports these functions. You can then
work with the data in the CollectionView without affecting the underlying source data. The changes in the
collection view are reflected in the DataGrid user interface (UI).
The CollectionView class provides grouping and sorting functionality for a data source that implements the
IEnumerable interface. The CollectionViewSource class enables you to set the properties of a CollectionView from
XAML.
In this example, a collection of Task objects is bound to a CollectionViewSource. The CollectionViewSource is
used as the ItemsSource for the DataGrid. Grouping, sorting, and filtering are performed on the
CollectionViewSource and are displayed in the DataGrid UI.
NOTE
The objects in the collection must implement the INotifyPropertyChanged changed interface and the IEditableObject
interface in order for the DataGrid to respond correctly to property changes and edits. For more information, see
Implement Property Change Notification.
2. In XAML, create an instance of the collection class and set the x:Key Directive.
3. In XAML, create an instance of the CollectionViewSource class, set the x:Key Directive, and set the instance
of your collection class as the Source.
<Window.Resources>
<local:Tasks x:Key="tasks" />
<CollectionViewSource x:Key="cvsTasks" Source="{StaticResource tasks}"
Filter="CollectionViewSource_Filter">
</CollectionViewSource>
</Window.Resources>
4. Create an instance of the DataGrid class, and set the ItemsSource property to the CollectionViewSource.
<DataGrid x:Name="dataGrid1"
ItemsSource="{Binding Source={StaticResource cvsTasks}}"
CanUserAddRows="False">
5. To access the CollectionViewSource from your code, use the GetDefaultView method to get a reference to
the CollectionViewSource.
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ProjectName"/>
<PropertyGroupDescription PropertyName="Complete"/>
</CollectionViewSource.GroupDescriptions>
When items are grouped in the DataGrid, you can define a GroupStyle that specifies the appearance of each group.
You apply the GroupStyle by adding it to the GroupStyle collection of the DataGrid. If you have multiple levels of
grouping, you can apply different styles to each group level. Styles are applied in the order in which they are
defined. For example, if you define two styles, the first will be applied to top level row groups. The second style will
be applied to all row groups at the second level and lower. The DataContext of the GroupStyle is the
CollectionViewGroup that the group represents.
To change the appearance of row group headers
1. Create a GroupStyle that defines the appearance of the row group.
2. Put the GroupStyle inside the <DataGrid.GroupStyle> tags.
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="#FF112255" BorderBrush="#FF002255"
Foreground="#FFEEEEEE" BorderThickness="1,1,1,5">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}"
Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups under the top level. -->
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="LightBlue">
<TextBlock Text="{Binding Path=Name, Converter={StaticResource completeConverter}}"
Foreground="Blue" Margin="30,0,0,0" Width="100"/>
<TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
Alternatively, you can filter items in a DataGrid by creating a method that provides the filtering logic and setting
the CollectionView.Filter property to apply the filter. To see an example of this method, see Filter Data in a View.
Example
The following example demonstrates grouping, sorting, and filtering Task data in a CollectionViewSource and
displaying the grouped, sorted, and filtered Task data in a DataGrid. The CollectionViewSource is used as the
ItemsSource for the DataGrid. Grouping, sorting, and filtering are performed on the CollectionViewSource and are
displayed in the DataGrid UI.
To test this example, you will need to adjust the DGGroupSortFilterExample name to match your project name. If
you are using Visual Basic, you will need to change the class name for Window to the following.
<Window x:Class="MainWindow"
<Window x:Class="DGGroupSortFilterExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DGGroupSortFilterExample"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="Group, Sort, and Filter Example" Height="575" Width="525">
<Window.Resources>
<local:CompleteConverter x:Key="completeConverter" />
<local:Tasks x:Key="tasks" />
<CollectionViewSource x:Key="cvsTasks" Source="{StaticResource tasks}"
Filter="CollectionViewSource_Filter">
<CollectionViewSource.SortDescriptions>
<!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"'
declaration. -->
<scm:SortDescription PropertyName="ProjectName"/>
<scm:SortDescription PropertyName="Complete" />
<scm:SortDescription PropertyName="DueDate" />
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ProjectName"/>
<PropertyGroupDescription PropertyName="Complete"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<DataGrid x:Name="dataGrid1"
ItemsSource="{Binding Source={StaticResource cvsTasks}}"
CanUserAddRows="False">
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="#FF112255"
BorderBrush="#FF002255" Foreground="#FFEEEEEE" BorderThickness="1,1,1,5">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}"
Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding
Path=ItemCount}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups under the top level. -->
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="LightBlue">
<TextBlock Text="{Binding Path=Name, Converter={StaticResource
completeConverter}}" Foreground="Blue" Margin="30,0,0,0" Width="100"/>
<TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBlock Text=" Filter completed items " VerticalAlignment="Center" />
<CheckBox x:Name="cbCompleteFilter" VerticalAlignment="Center"
Checked="CompleteFilter_Changed" Unchecked="CompleteFilter_Changed" />
<Button Content="Remove Groups" Margin="10,2,2,2" Click="UngroupButton_Click" />
<Button Content="Group by Project/Status" Margin="2" Click="GroupButton_Click" />
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace DGGroupSortFilterExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
[ValueConversion(typeof(Boolean), typeof(String))]
public class CompleteConverter : IValueConverter
{
// This converter changes the value of a Tasks Complete status from true/false to a string value of
// "Complete"/"Active" for use in the row group header.
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
bool complete = (bool)value;
if (complete)
return "Complete";
else
return "Active";
}
// Task Class
// Requires using System.ComponentModel;
public class Task : INotifyPropertyChanged, IEditableObject
{
// The Task class implements INotifyPropertyChanged and IEditableObject
// so that the datagrid can properly respond to changes to the
// data collection and edits made in the DataGrid.
// Public properties.
public string ProjectName
{
get { return this.m_ProjectName; }
set
{
if (value != this.m_ProjectName)
{
this.m_ProjectName = value;
NotifyPropertyChanged("ProjectName");
}
}
}
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Class MainWindow
Public Sub New()
InitializeComponent()
' Generate some task data and add it to the task list.
For index = 1 To 14
_tasks.Add(New Task() With _
{.ProjectName = "Project " & ((index Mod 3) + 1).ToString(), _
.TaskName = "Task " & index.ToString(), _
.DueDate = Date.Now.AddDays(index), _
.Complete = (index Mod 2 = 0) _
})
Next
End Sub
Public Function ConvertBack1(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As
Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements
System.Windows.Data.IValueConverter.ConvertBack
Dim strComplete As String = value
If strComplete = "Complete" Then
Return True
Else
Return False
End If
End Function
End Class
See also
Data Binding Overview
Create and Bind to an ObservableCollection
Filter Data in a View
Sort Data in a View
Sort and Group Data Using a View in XAML
How to: Implement Validation with the DataGrid
Control
5/4/2018 • 9 minutes to read • Edit Online
The DataGrid control enables you to perform validation at both the cell and row level. With cell-level validation,
you validate individual properties of a bound data object when a user updates a value. With row -level validation,
you validate entire data objects when a user commits changes to a row. You can also provide customized visual
feedback for validation errors, or use the default visual feedback that the DataGrid control provides.
The following procedures describe how to apply validation rules to DataGrid bindings and customize the visual
feedback.
To validate individual cell values
Specify one or more validation rules on the binding used with a column. This is similar to validating data in
simple controls, as described in Data Binding Overview.
The following example shows a DataGrid control with four columns bound to different properties of a
business object. Three of the columns specify the ExceptionValidationRule by setting the
ValidatesOnExceptions property to true .
<Grid>
<Grid.Resources>
<local:Courses x:Key="courses"/>
</Grid.Resources>
</Grid>
When a user enters an invalid value (such as a non-integer in the Course ID column), a red border appears
around the cell. You can change this default validation feedback as described in the following procedure.
To customize cell validation feedback
Set the column's EditingElementStyle property to a style appropriate for the column's editing control.
Because the editing controls are created at run time, you cannot use the Validation.ErrorTemplate attached
property like you would with simple controls.
The following example updates the previous example by adding an error style shared by the three columns
with validation rules. When a user enters an invalid value, the style changes the cell background color and
adds a ToolTip. Note the use of a trigger to determine whether there is a validation error. This is required
because there is currently no dedicated error template for cells.
<DataGrid.Resources>
<Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="-2"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Course Name"
Binding="{Binding Name, TargetNullValue=(enter a course name)}"/>
<DataGridTextColumn Header="Course ID"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id, ValidatesOnExceptions=True}"/>
<DataGridTextColumn Header="Start Date"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding StartDate, ValidatesOnExceptions=True,
StringFormat=d}"/>
<DataGridTextColumn Header="End Date"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding EndDate, ValidatesOnExceptions=True,
StringFormat=d}"/>
</DataGrid.Columns>
You can implement more extensive customization by replacing the CellStyle used by the column.
To validate multiple values in a single row
1. Implement a ValidationRule subclass that checks multiple properties of the bound data object. In your
Validate method implementation, cast the value parameter value to a BindingGroup instance. You can then
access the data object through the Items property.
The following example demonstrates this process to validate whether the StartDate property value for a
Course object is earlier than its EndDate property value.
End Function
End Class
2. Add the validation rule to the DataGrid.RowValidationRules collection. The RowValidationRules property
provides direct access to the ValidationRules property of a BindingGroup instance that groups all the
bindings used by the control.
The following example sets the RowValidationRules property in XAML. The ValidationStep property is set to
UpdatedValue so that the validation occurs only after the bound data object is updated.
<DataGrid.RowValidationRules>
<local:CourseValidationRule ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
When a user specifies an end date that is earlier than the start date, a red exclamation mark (!) appears in
the row header. You can change this default validation feedback as described in the following procedure.
To customize row validation feedback
Set the DataGrid.RowValidationErrorTemplate property. This property enables you to customize row
validation feedback for individual DataGrid controls. You can also affect multiple controls by using an
implicit row style to set the DataGridRow.ValidationErrorTemplate property.
The following example replaces the default row validation feedback with a more visible indicator. When a
user enters an invalid value, a red circle with a white exclamation mark appears in the row header. This
occurs for both row and cell validation errors. The associated error message is displayed in a ToolTip.
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
<Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
<Ellipse StrokeThickness="0" Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
<TextBlock Text="!" FontSize="{TemplateBinding FontSize}"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>
Example
The following example provides a complete demonstration for cell and row validation. The Course class provides a
sample data object that implements IEditableObject to support transactions. The DataGrid control interacts with
IEditableObject to enable users to revert changes by pressing ESC.
NOTE
If you are using Visual Basic, in the first line of MainWindow.xaml, replace x:Class="DataGridValidation.MainWindow" with
x:Class="MainWindow" .
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DataGridValidation
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
dataGrid1.InitializingNewItem += (sender, e) =>
{
Course newCourse = e.NewItem as Course;
newCourse.StartDate = newCourse.EndDate = DateTime.Today;
};
}
}
#region IEditableObject
#endregion
#region INotifyPropertyChanged
#endregion
Imports System.Collections.ObjectModel
Imports System.ComponentModel
End Sub
End Class
Sub New()
Me.Add(New Course With { _
.Name = "Learning WPF", _
.Id = 1001, _
.StartDate = New DateTime(2010, 1, 11), _
.EndDate = New DateTime(2010, 1, 22) _
})
Me.Add(New Course With { _
.Name = "Learning Silverlight", _
.Id = 1002, _
.StartDate = New DateTime(2010, 1, 25), _
.EndDate = New DateTime(2010, 2, 5) _
})
Me.Add(New Course With { _
.Name = "Learning Expression Blend", _
.Id = 1003, _
.StartDate = New DateTime(2010, 2, 8), _
.EndDate = New DateTime(2010, 2, 19) _
})
Me.Add(New Course With { _
.Name = "Learning LINQ", _
.Id = 1004, _
.StartDate = New DateTime(2010, 2, 22), _
.EndDate = New DateTime(2010, 3, 5) _
})
End Sub
End Class
#Region "IEditableObject"
#End Region
#Region "INotifyPropertyChanged"
#End Region
End Class
End Function
End Class
<Window x:Class="DataGridValidation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataGridValidation"
Title="DataGrid Validation Example" Height="240" Width="600">
<Grid>
<Grid.Resources>
<local:Courses x:Key="courses"/>
</Grid.Resources>
<DataGrid.Resources>
<Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="-2"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Course Name"
Binding="{Binding Name, TargetNullValue=(enter a course name)}"/>
<DataGridTextColumn Header="Course ID"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id, ValidatesOnExceptions=True}"/>
<DataGridTextColumn Header="Start Date"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding StartDate, ValidatesOnExceptions=True,
StringFormat=d}"/>
<DataGridTextColumn Header="End Date"
EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding EndDate, ValidatesOnExceptions=True,
StringFormat=d}"/>
</DataGrid.Columns>
<DataGrid.RowValidationRules>
<local:CourseValidationRule ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
<Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
<Ellipse StrokeThickness="0" Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
<TextBlock Text="!" FontSize="{TemplateBinding FontSize}"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>
</DataGrid>
</Grid>
</Window>
See Also
DataGrid
DataGrid
Data Binding
Implement Binding Validation
Implement Validation Logic on Custom Objects
Walkthrough: Display data from a SQL Server
database in a DataGrid control
9/18/2018 • 2 minutes to read • Edit Online
In this walkthrough, you retrieve data from a SQL Server database and display that data in a DataGrid control. You
use the ADO.NET Entity Framework to create the entity classes that represent the data, and use LINQ to write a
query that retrieves the specified data from an entity class.
Prerequisites
You need the following components to complete this walkthrough:
Visual Studio.
Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorks sample
database attached to it. You can download the AdventureWorks database from the GitHub.
8. Click Finish.
The Product and ProductCategory entities are displayed in the Entity Designer.
Retrieve and present the data
1. Open the MainWindow.xaml file.
2. Set the Width property on the Window to 450.
3. In the XAML editor, add the following DataGrid tag between the <Grid> and </Grid> tags to add a
DataGrid named dataGrid1 .
NOTE
If you are using Visual Basic, in the first line of MainWindow.xaml, replace
x:Class="DataGridSQLExample.MainWindow" with x:Class="MainWindow" .
<Window x:Class="DataGridSQLExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="450"
Loaded="Window_Loaded">
<Grid>
<DataGrid Name="dataGrid1" />
</Grid>
</Window>
namespace DataGridSQLExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
AdventureWorksLT2008Entities dataEntities = new AdventureWorksLT2008Entities();
public MainWindow()
{
InitializeComponent();
}
var query =
from product in products
where product.Color == "Red"
orderby product.ListPrice
select new { product.Name, product.Color, CategoryName = product.ProductCategory.Name,
product.ListPrice };
dataGrid1.ItemsSource = query.ToList();
}
}
}
Imports System.Data.Objects
Class MainWindow
Dim dataEntities As AdventureWorksLT2008Entities = New AdventureWorksLT2008Entities
Dim query = _
From product In products _
Where product.Color = "Red" _
Order By product.ListPrice _
Select product.Name, product.Color, CategoryName = product.ProductCategory.Name,
product.ListPrice
dataGrid1.ItemsSource = query.ToList()
End Sub
End Class
Various options are available to control how the DataGrid sizes itself. The DataGrid, and individual rows and
columns in the DataGrid, can be set to size automatically to their contents or can be set to specific values. By
default, the DataGrid will grow and shrink to fit the size of its contents.
PROPERTY DESCRIPTION
MaxHeight Sets the upper bound for the height of the DataGrid. The
DataGrid will grow vertically until it reaches this height.
MinHeight Sets the lower bound for the height of the DataGrid. The
DataGrid will shrink vertically until it reaches this height.
MaxWidth Sets the upper bound for the width of the DataGrid. The
DataGrid will grow horizontally until it reaches this width.
PROPERTY DESCRIPTION
MinWidth Sets the lower bound for the width of the DataGrid. The
DataGrid will shrink horizontally until it reaches this width.
NAME DESCRIPTION
The DataGridLengthConverter class can be used to convert data between numeric or string values and
DataGridLength values.
By default, the DataGrid.ColumnWidth property is set to SizeToHeader, and the DataGridColumn.Width property
is set to Auto. When the sizing mode is set to Auto or SizeToCells, columns will grow to the width of their widest
visible content. When scrolling, these sizing modes will cause columns to expand if content that is larger than the
current column size is scrolled into view. The column will not shrink after the content is scrolled out of view.
Columns in the DataGrid can also be set to automatically size only within specified boundaries, or columns can be
set to a specific size. The following table shows the properties that can be set to control column sizes.
PROPERTY DESCRIPTION
DataGrid.MaxColumnWidth Sets the upper bound for all columns in the DataGrid.
DataGrid.MinColumnWidth Sets the lower bound for all columns in the DataGrid.
See Also
DataGrid
DataGridColumn
DataGridLength
DataGridLengthConverter
DatePicker
5/4/2018 • 2 minutes to read • Edit Online
The DatePicker control allows the user to select a date by either typing it into a text field or by using a drop-down
Calendar control.
The following illustration shows a DatePicker.
DatePicker Control
Many of a DatePicker control's properties are for managing its built-in Calendar, and function identically to the
equivalent property in Calendar. In particular, the DatePicker.IsTodayHighlighted, DatePicker.FirstDayOfWeek,
DatePicker.BlackoutDates, DatePicker.DisplayDateStart, DatePicker.DisplayDateEnd, DatePicker.DisplayDate, and
DatePicker.SelectedDate properties function identically to their Calendar counterparts. For more information, see
Calendar.
Users can type a date directly into a text field, which sets the Text property. If the DatePicker cannot convert the
entered string to a valid date, the DateValidationError event will be raised. By default, this causes an exception, but
an event handler for DateValidationError can set the ThrowException property to false and prevent an exception
from being raised.
See Also
Controls
Styling and Templating
DockPanel
5/4/2018 • 2 minutes to read • Edit Online
The DockPanel element is used to position child content along the edge of a layout container.
In This Section
How -to Topics
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
DockPanel How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the DockPanel element to position child elements along the edge of a
layout container.
In This Section
Get or Set a Dock Value
Create a DockPanel
Partition Space by Using the DockPanel Element
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
How to: Get or Set a Dock Value
5/4/2018 • 2 minutes to read • Edit Online
The following example shows how to assign a Dock value for an object. The example uses the GetDock and
SetDock methods of DockPanel.
Example
The example creates an instance of the TextBlock element, txt1 , and assigns a Dock value of Top by using the
SetDock method of DockPanel. It then appends the value of the Dock property to the Text of the TextBlock element
by using the GetDock method. Finally, the example adds the TextBlock element to the parent DockPanel, dp1 .
' Create a Text Control and then set its Dock property
txt1 = New TextBlock()
DockPanel.SetDock(txt1, Dock.Top)
txt1.Text = "The Dock Property is set to " & DockPanel.GetDock(txt1).ToString()
dp1.Children.Add(txt1)
_mainWindow.Content = dp1
_mainWindow.Show()
See Also
DockPanel
GetDock
SetDock
Panels Overview
How to: Create a DockPanel
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example creates and uses an instance of DockPanel by using code. The example shows you how to
partition space by creating five Rectangle elements and positioning (docking) them inside a parent DockPanel. If
you retain the default setting, the final rectangle fills all the remaining unallocated space.
private void CreateAndShowMainWindow()
{
// Create the application's main window
mainWindow = new Window ();
// Create a DockPanel
DockPanel myDockPanel = new DockPanel();
// Add the DockPanel to the Window as Content and show the Window
mainWindow.Content = myDockPanel;
mainWindow.Title = "DockPanel Sample";
mainWindow.Show();
}
}
WindowTitle = "DockPanel Sample"
'Create a DockPanel as the root Panel
Dim myDP As New DockPanel()
' Add the first Rectangle to the DockPanel
Dim rect1 As New Rectangle
rect1.Stroke = Brushes.Black
rect1.Fill = Brushes.SkyBlue
rect1.Height = 25
DockPanel.SetDock(rect1, Dock.Top)
myDP.Children.Add(rect1)
See Also
DockPanel
Dock
Panels Overview
How to: Partition Space by Using the DockPanel
Element
5/4/2018 • 4 minutes to read • Edit Online
The following example creates a simple user interface (UI) framework using a DockPanel element. The DockPanel
partitions available space to its child elements.
Example
This example uses the Dock property, which is an attached property, to dock two identical Border elements at the
Top of the partitioned space. A third Border element is docked to the Left, with its width set to 200 pixels. A fourth
Border is docked to the Bottom of the screen. The last Border element automatically fills the remaining space.
NOTE
By default, the last child of a DockPanel element fills the remaining unallocated space. If you do not want this behavior, set
LastChildFill="False" .
See Also
DockPanel
Panels Overview
DocumentViewer
5/4/2018 • 2 minutes to read • Edit Online
The DocumentViewer control is used to view FixedDocument content (such as XML Paper Specification (XPS )
documents) in a paginated format.
Reference
DocumentViewer
FixedDocument
See Also
Documents
Document Serialization and Storage
Printing Overview
Expander
5/4/2018 • 2 minutes to read • Edit Online
An Expander allows a user to view a header and expand that header to see further details, or to collapse a section
up to a header.
The following illustration provides an example of this control in its expanded position.
Expander control
In This Section
Expander Overview
How -to Topics
Reference
Expander
Related Sections
Expander Overview
5/4/2018 • 5 minutes to read • Edit Online
An Expander control provides a way to provide content in an expandable area that resembles a window and
includes a header.
The Content and Header of an Expander can also contain complex content, such as RadioButton and Image
objects.
When you place an Expander control in a ScrollViewer, set the ScrollViewer dimension property that corresponds
to the direction in which the Expander content opens to the size of the Expander content area. For example, if you
set the ExpandDirection property on the Expander to Down (the content area opens down), set the Height
property on the ScrollViewer control to the required height for the content area. If you instead set the height
dimension on the content itself, ScrollViewer does not recognize this setting and therefore, does not provide
scrollable content.
The following example shows how to create an Expander control that has complex content and that contains a
ScrollViewer control. This example creates an Expander that is like the illustration at the beginning of this section.
void MakeExpander()
{
//Create containing stack panel and assign to Grid row/col
StackPanel sp = new StackPanel();
Grid.SetRow(sp, 0);
Grid.SetColumn(sp, 1);
sp.Background = Brushes.LightSalmon;
spScroll.Children.Add(tbc);
ScrollViewer scr = new ScrollViewer();
scr.Content = spScroll;
scr.Height = 50;
exp.Content = scr;
exp.Width=200;
exp.HorizontalContentAlignment= HorizontalAlignment.Stretch;
//Insert Expander into the StackPanel and add it to the
//Grid
sp.Children.Add(exp);
myGrid.Children.Add(sp);
}
Sub MakeExpander()
spScroll.Children.Add(tbc)
Dim scr As ScrollViewer = New ScrollViewer()
scr.Content = spScroll
scr.Height = 50
exp.Content = scr
See Also
Expander
ExpandDirection
How -to Topics
Expander How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the Expander control.
In This Section
Create an Expander with a ScrollViewer
Reference
Expander
Related Sections
Expander Overview
How to: Create an Expander with a ScrollViewer
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to create an Expander control that contains complex content, such as an image and text.
The example also encloses the content of the Expander in a ScrollViewer control.
Example
The following example shows how to create an Expander. The example uses a BulletDecorator control, which
contains an image and text, in order to define the Header. A ScrollViewer control provides a method for scrolling
the expanded content.
Note that the example sets the Height property on the ScrollViewer instead of on the content. If the Height is set
on the content, the ScrollViewer does not allow the user to scroll the content. The Width property is set on the
Expander control and this setting applies to the Header and the expanded content.
spScroll.Children.Add(tbc);
ScrollViewer scr = new ScrollViewer();
scr.Content = spScroll;
scr.Height = 50;
exp.Content = scr;
exp.Width=200;
exp.HorizontalContentAlignment= HorizontalAlignment.Stretch;
See Also
Expander
Expander Overview
How -to Topics
FlowDocumentPageViewer
5/4/2018 • 2 minutes to read • Edit Online
The FlowDocumentPageViewer control is used to view FlowDocument content on a per page basis. Contrast with
the FlowDocumentScrollViewer, which presents FlowDocument content in a scrolling viewer.
See Also
FlowDocument
Flow Document Overview
How -to Topics
Documents in WPF
FlowDocumentReader
5/4/2018 • 2 minutes to read • Edit Online
The FlowDocumentReader control is used to view FlowDocument content. It supports multiple viewing modes.
See Also
FlowDocumentReader
FlowDocumentPageViewer
FlowDocumentScrollViewer
Documents in WPF
Flow Document Overview
FlowDocumentScrollViewer
5/4/2018 • 2 minutes to read • Edit Online
The FlowDocumentScrollViewer control is used to view FlowDocument content in a scrolling container. Contrast
with FlowDocumentPageViewer, which views content on a per page basis.
See Also
FlowDocumentReader
FlowDocumentPageViewer
FlowDocumentScrollViewer
FlowDocument
Documents in WPF
Flow Document Overview
Frame
5/4/2018 • 2 minutes to read • Edit Online
The Frame control supports content navigation within content. Frame can be hosted by a root element like
Window, NavigationWindow, Page, UserControl, FlowDocument, or as an island within a content tree that belongs
to a root element.
Reference
Frame
Related Sections
Navigation Overview
Grid
5/4/2018 • 2 minutes to read • Edit Online
The Grid element is used to precisely position content in rows and columns.
In This Section
How -to Topics
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
Grid How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to position elements using the Grid element.
In This Section
Build a Standard UI Dialog Box by Using Grid
Create a Complex Grid
Create a Grid Element
Create and Use a GridLengthConverter Object
Manipulate Columns and Rows by Using ColumnDefinitionsCollections and RowDefinitionsCollections
Position the Child Elements of a Grid
Share Sizing Properties Between Grids
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
How to: Build a Standard UI Dialog Box by Using
Grid
5/4/2018 • 3 minutes to read • Edit Online
This example shows how to create a standard user interface (UI) dialog box by using the Grid element.
Example
The following example creates a dialog box like the Run dialog box in the Windows operating system.
The example creates a Grid and uses the ColumnDefinition and RowDefinition classes to define five columns and
four rows.
The example then adds and positions an Image, RunIcon.png , to represent the image that is found in the dialog
box. The image is placed in the first column and row of the Grid (the upper-left corner).
Next, the example adds a TextBlock element to the first column, which spans the remaining columns of the first
row. It adds another TextBlock element to the second row in the first column, to represent the Open text box. A
TextBlock follows, which represents the data entry area.
Finally, the example adds three Button elements to the final row, which represent the OK, Cancel, and Browse
events.
grid1.Children.Add(img1);
grid1.Children.Add(txt1);
grid1.Children.Add(txt2);
grid1.Children.Add(tb1);
grid1.Children.Add(button1);
grid1.Children.Add(button2);
grid1.Children.Add(button3);
mainWindow.Content = grid1;
Grid.SetRow(button1, 3)
Grid.SetColumn(button1, 2)
Grid.SetRow(button2, 3)
Grid.SetColumn(button2, 3)
Grid.SetRow(button3, 3)
Grid.SetColumn(button3, 4)
myGrid.Children.Add(button1)
myGrid.Children.Add(button2)
myGrid.Children.Add(button3)
Me.Content = myGrid
See Also
Grid
GridUnitType
Panels Overview
How -to Topics
How to: Create a Complex Grid
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use a Grid to create layout that looks like a monthly calendar.
Example
The following example defines eight rows and eight columns by using the RowDefinition and ColumnDefinition
classes. It uses the Grid.ColumnSpan and Grid.RowSpan attached properties, together with Rectangle elements,
which fill the backgrounds of various columns and rows. This design is possible because more than one element
can exist in each cell in a Grid, a principle difference between Grid and Table.
The example uses vertical gradients to Fill the columns and rows in order to improve the visual presentation and
readability of the calendar. Styled TextBlock elements represent the dates and days of the week. TextBlock elements
are absolutely positioned within their cells by using the Margin property and alignment properties that are defined
within the style for the application.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="Complex Grid Example">
<Border BorderBrush="Black">
<!-- These Rectangles constitute the backgrounds of the various Rows and Columns -->
Example
The following example shows how to create and use an instance of Grid by using either Extensible Application
Markup Language (XAML ) or code. This example uses three ColumnDefinition objects and three RowDefinition
objects to create a grid that has nine cells, such as in a worksheet. Each cell contains a TextBlock element that
represents data, and the top row contains a TextBlock with the ColumnSpan property applied. To show the
boundaries of each cell, the ShowGridLines property is enabled.
Me.Content = myGrid
End Sub
See Also
Grid
Panels Overview
How to: Create and Use a GridLengthConverter
Object
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example shows how to create and use an instance of GridLengthConverter. The example defines a
custom method called changeCol , which passes the ListBoxItem to a GridLengthConverter that converts the
Content of a ListBoxItem to an instance of GridLength. The converted value is then passed back as the value of the
Width property of the ColumnDefinition element.
The example also defines a second custom method, called changeColVal . This custom method converts the Value
of a Slider to a String and then passes that value back to the ColumnDefinition as the Width of the element.
Note that a separate Extensible Application Markup Language (XAML ) file defines the contents of a ListBoxItem.
See Also
GridLengthConverter
GridLength
How to: Manipulate Columns and Rows by Using
ColumnDefinitionsCollections and
RowDefinitionsCollections
5/4/2018 • 4 minutes to read • Edit Online
This example shows how to use the methods in the ColumnDefinitionCollection and RowDefinitionCollection
classes to perform actions like adding, clearing, or counting the contents of rows or columns. For example, you can
Add, Clear, or Count the items that are included in a ColumnDefinition or RowDefinition.
Example
The following example creates a Grid element with a Name of grid1 . The Grid contains a StackPanel that holds
Button elements, each controlled by a different collection method. When you click a Button, it activates a method
call in the code-behind file.
This example defines a series of custom methods, each corresponding to a Click event in the Extensible Application
Markup Language (XAML ) file. You can change the number of columns and rows in the Grid in several ways,
which includes adding or removing rows and columns; and counting the total number of rows and columns. To
prevent ArgumentOutOfRangeException and ArgumentException exceptions, you can use the error-checking
functionality that the RemoveRange method provides.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace columndefinitions_grid
{
public partial class Window1 : Window
{
RowDefinition rowDef1;
ColumnDefinition colDef1;
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
'@ <summary>
'@ Interaction logic for Window1.xaml
'@ </summary>
End Class
End Namespace
See Also
Grid
ColumnDefinitionCollection
RowDefinitionCollection
How to: Position the Child Elements of a Grid
5/4/2018 • 3 minutes to read • Edit Online
This example shows how to use the get and set methods that are defined on Grid to position child elements.
Example
The following example defines a parent Grid element ( grid1 ) that has three columns and three rows. A child
Rectangle element ( rect1 ) is added to the Grid in column position zero, row position zero. Button elements
represent methods that can be called to reposition the Rectangle element within the Grid. When a user clicks a
button, the related method is activated.
The following code-behind example handles the methods that the button Click events raise. The example writes
these method calls to TextBlock elements that use related get methods to output the new property values as
strings.
}
private void setCol1(object sender, RoutedEventArgs e)
{
Grid.SetColumn(rect1, 1);
txt1.Text = "Rectangle is in Column " + Grid.GetColumn(rect1).ToString();
}
private void setCol2(object sender, RoutedEventArgs e)
{
Grid.SetColumn(rect1, 2);
txt1.Text = "Rectangle is in Column " + Grid.GetColumn(rect1).ToString();
}
private void setRow0(object sender, RoutedEventArgs e)
{
Grid.SetRow(rect1, 0);
txt2.Text = "Rectangle is in Row " + Grid.GetRow(rect1).ToString();
}
private void setRow1(object sender, RoutedEventArgs e)
{
Grid.SetRow(rect1, 1);
txt2.Text = "Rectangle is in Row " + Grid.GetRow(rect1).ToString();
}
private void setRow2(object sender, RoutedEventArgs e)
{
Grid.SetRow(rect1, 2);
txt2.Text = "Rectangle is in Row " + Grid.GetRow(rect1).ToString();
}
private void setColspan(object sender, RoutedEventArgs e)
{
Grid.SetColumnSpan(rect1, 3);
txt3.Text = "ColumnSpan is set to " + Grid.GetColumnSpan(rect1).ToString();
}
private void setRowspan(object sender, RoutedEventArgs e)
{
Grid.SetRowSpan(rect1, 3);
txt4.Text = "RowSpan is set to " + Grid.GetRowSpan(rect1).ToString();
}
Private Sub setCol0(ByVal sender As Object, ByVal e As RoutedEventArgs)
Grid.SetColumn(rect1, 0)
txt1.Text = "Rectangle is in Column " + Grid.GetColumn(rect1).ToString()
End Sub
See Also
Grid
Panels Overview
How to: Share Sizing Properties Between Grids
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to share the sizing data of columns and rows between Grid elements in order to keep
sizing consistent.
Example
The following example introduces two Grid elements as child elements of a parent DockPanel. The
IsSharedSizeScope attached property of Grid is defined on the parent DockPanel.
The example manipulates the property value by using two Button elements; each element represents one of the
Boolean property values. When the IsSharedSizeScope property value is set to true , each column or row
member of a SharedSizeGroup shares sizing information, regardless of the content of a row or column.
...
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
<Button Click="setTrue" Margin="0,0,10,10">Set IsSharedSizeScope="True"</Button>
<Button Click="setFalse" Margin="0,0,10,10">Set IsSharedSizeScope="False"</Button>
</StackPanel>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="FirstColumn"/>
<ColumnDefinition SharedSizeGroup="SecondColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" SharedSizeGroup="FirstRow"/>
</Grid.RowDefinitions>
</StackPanel>
The following code-behind example handles the methods that the button Click event raises. The example writes the
results of these method calls to TextBlock elements that use related get methods to output the new property values
as strings.
Grid.SetIsSharedSizeScope(dp1, True)
txt1.Text = "IsSharedSizeScope Property is set to " + Grid.GetIsSharedSizeScope(dp1).ToString()
End Sub
Grid.SetIsSharedSizeScope(dp1, False)
txt1.Text = "IsSharedSizeScope Property is set to " + Grid.GetIsSharedSizeScope(dp1).ToString()
End Sub
See Also
Grid
IsSharedSizeScope
Panels Overview
GridSplitter
5/4/2018 • 2 minutes to read • Edit Online
In This Section
How -to Topics
Reference
GridSplitter
Related Sections
GridSplitter How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the GridSplitter control.
In This Section
Resize Rows with a GridSplitter
Resize Columns with a GridSplitter
Make Sure That a GridSplitter Is Visible
Reference
GridSplitter
Grid
Related Sections
How to: Resize Rows with a GridSplitter
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use a horizontal GridSplitter to redistribute the space between two rows in a Grid
without changing the dimensions of the Grid.
Example
How to create a GridSplitter that overlays the edge of a row
To specify a GridSplitter that resizes adjacent rows in a Grid, set the Row attached property to one of the rows that
you want to resize. If your Grid has more than one column, set the ColumnSpan attached property to specify the
number of columns. Then set the VerticalAlignment to Top or Bottom (which alignment you set depends on which
two rows you want to resize). Finally, set the HorizontalAlignment property to Stretch.
The following example shows how to define a horizontal GridSplitter that resizes adjacent rows.
<GridSplitter Grid.Row="1"
Grid.ColumnSpan="3"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="Black"
ShowsPreview="true"
ResizeDirection="Rows"
Height="5"/>
A GridSplitter that does not occupy its own row may be obscured by other controls in the Grid. For more
information about how to prevent this issue, see Make Sure That a GridSplitter Is Visible.
How to create a GridSplitter that occupies a row
To specify a GridSplitter that occupies a row in a Grid, set the Row attached property to one of the rows that you
want to resize. If your Grid has more than one column, set the ColumnSpan attached property to the number of
columns. Then set the VerticalAlignment to Center, set the HorizontalAlignment property to Stretch, and set the
Height of the row that contains the GridSplitter to Auto.
The following example shows how to define a horizontal GridSplitter that occupies a row and resizes the rows on
either side of it.
<Grid.RowDefinitions>
<RowDefinition Height="50*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="50*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="1" Background="Tan"/>
<GridSplitter Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Background="Black"
ShowsPreview="True"
Height="5"
/>
<StackPanel Grid.Row="2" Grid.Column="0" Background="Brown"/>
See Also
GridSplitter
How -to Topics
How to: Resize Columns with a GridSplitter
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to create a vertical GridSplitter in order to redistribute the space between two columns in
a Grid without changing the dimensions of the Grid.
Example
How to create a GridSplitter that overlays the edge of a column
To specify a GridSplitter that resizes adjacent columns in a Grid, set the Column attached property to one of the
columns that you want to resize. If your Grid has more than one row, set the RowSpan attached property to the
number of rows. Then set the HorizontalAlignment property to Left or Right (which alignment you set depends on
which two columns you want to resize). Finally, set the VerticalAlignment property to Stretch.
<GridSplitter Grid.Column="1"
Grid.RowSpan="3"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="true"
Width="5"/>
A GridSplitter that does not have its own column may be obscured by other controls in the Grid. For more
information about how to prevent this issue, see Make Sure That a GridSplitter Is Visible.
How to create a GridSplitter that occupies a column
To specify a GridSplitter that occupies a column in a Grid, set the Column attached property to one of the columns
that you want to resize. If your Grid has more than one row, set the RowSpan attached property to the number of
rows. Then set the HorizontalAlignment to Center, set the VerticalAlignment property to Stretch, and set the Width
of the column that contains the GridSplitter to Auto.
The following example shows how to define a vertical GridSplitter that occupies a column and resizes the columns
on either side of it.
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="True"
Width="5"
/>
See Also
GridSplitter
How -to Topics
How to: Make Sure That a GridSplitter Is Visible
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to make sure a GridSplitter control is not hidden by the other controls in a Grid.
Example
The Children of a Grid control are rendered in the order that they are defined in markup or code. GridSplitter
controls can be hidden by other controls if you do not define them as the last elements in the Children collection
or if you give other controls a higher ZIndexProperty.
To prevent hidden GridSplitter controls, do one of the following.
Make sure that GridSplitter controls are the last Children added to the Grid. The following example shows the
GridSplitter as the last element in the Children collection of the Grid.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0"/>
<GridSplitter Grid.Column ="0" Background="Blue"/>
</Grid>
Set the ZIndexProperty on the GridSplitter to be higher than a control that would otherwise hide it. The
following example gives the GridSplitter control a higher ZIndexProperty than the Button control.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="0" Background="Blue"
Panel.ZIndex="1"/>
<Button Grid.Column="0"/>
</Grid>
Set margins on the control that would otherwise hide the GridSplitter so that the GridSplitter is exposed. The
following example sets margins on a control that would otherwise overlay and hide the GridSplitter.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column ="0" Background="Blue"/>
<Button Grid.Column="0" Margin="0,0,5,0"/>
</Grid>
See Also
GridSplitter
How -to Topics
GroupBox
5/4/2018 • 2 minutes to read • Edit Online
The GroupBox control is a HeaderedContentControl that provides a titled container for graphical user interface
(GUI) content.
The following illustration shows a GroupBox that contains a TabControl and a Button that are enclosed in a
StackPanel.
In This Section
Define a GroupBox Template
Reference
GroupBox
Related Sections
How to: Define a GroupBox Template
8/31/2018 • 2 minutes to read • Edit Online
Example
The following example defines a GroupBox control template by using a Grid control for layout. The template uses a
BorderGapMaskConverter to define the border of the GroupBox so that the border does not obscure the Header
content.
<!--=================================================================
GroupBox Template Example
==================================================================-->
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="{x:Type GroupBox}"
TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush"
Value="Gray"/>
<Setter Property="Foreground"
Value="White"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="4"/>
</Grid.RowDefinitions>
<Border CornerRadius="4"
Grid.Row="1"
Grid.RowSpan="3"
Grid.Column="0"
Grid.ColumnSpan="4"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Transparent"
Background="{TemplateBinding Background}"/>
<!-- ContentPresenter for the header -->
<Border x:Name="Header"
Padding="6,0,6,0"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1">
<ContentPresenter ContentSource="Header"
RecognizesAccessKey="True" />
</Border>
<!-- Primary content for GroupBox -->
<ContentPresenter Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="{TemplateBinding Padding}"/>
Margin="{TemplateBinding Padding}"/>
<Border CornerRadius="0"
Grid.Row="1"
Grid.RowSpan="3"
Grid.ColumnSpan="4"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Border.OpacityMask>
<MultiBinding Converter=
"{StaticResource BorderGapMaskConverter}"
ConverterParameter="6">
<Binding ElementName="Header"
Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="ActualHeight"/>
</MultiBinding>
</Border.OpacityMask>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
See Also
GroupBox
GroupBox How -to Topics
Image
5/4/2018 • 2 minutes to read • Edit Online
The Image element is used to display bitmap images in Windows Presentation Foundation (WPF ) applications.
In This Section
How -to Topics
Reference
Image
BitmapImage
BitmapSource
See Also
Imaging Overview
How -to Topics
Image How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the Image element.
In This Section
Use the Image Element
Convert an Image to Greyscale
Crop an Image
Rotate an Image
Reference
Image
BitmapImage
BitmapSource
See Also
Imaging Overview
How -to Topics
How to: Use the Image Element
5/4/2018 • 3 minutes to read • Edit Online
This example shows how to include images in an application by using the Image element.
Example
The following example shows how to render an image 200 pixels wide. In this Extensible Application Markup
Language (XAML ) example, both attribute syntax and property tag syntax are used to define the image. For more
information on attribute syntax and property syntax, see Dependency Properties Overview. A BitmapImage is used
to define the image's source data and is explicitly defined for the property tag syntax example. In addition, the
DecodePixelWidth of the BitmapImage is set to the same width as the Width of the Image. This is done to ensure
that the minimum amount of memory is used rendering the image.
NOTE
In general, if you want to specify the size of a rendered image, specify only the Width or the Height but not both. If you only
specify one, the image's aspect ratio is preserved. Otherwise, the image may unexpectedly appear stretched or warped. To
control the image's stretching behavior, use the Stretch and StretchDirection properties.
NOTE
When you specify the size of an image with either Width or Height, you should also set either DecodePixelWidth or
DecodePixelHeight to the same respective size.
The Stretch property determines how the image source is stretched to fill the image element. For more
information, see the Stretch enumeration.
<!-- Simple image rendering. However, rendering an image this way may not
result in the best use of application memory. See markup below which
creates the same end result but using less memory. -->
<Image Width="200"
Source="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg"/>
<Image Width="200">
<Image.Source>
<!-- To save significant application memory, set the DecodePixelWidth or
DecodePixelHeight of the BitmapImage value of the image source to the desired
height and width of the rendered image. If you don't do this, the application will
cache the image as though it were rendered as its normal size rather then just
the size that is displayed. -->
<!-- Note: In order to preserve aspect ratio, only set either DecodePixelWidth
or DecodePixelHeight but not both. -->
<BitmapImage DecodePixelWidth="200"
UriSource="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg" />
</Image.Source>
</Image>
Example
The following example shows how to render an image 200 pixels wide using code.
NOTE
Setting BitmapImage properties must be done within a BeginInit and EndInit block.
// Create source
BitmapImage myBitmapImage = new BitmapImage();
See Also
Imaging Overview
How to: Convert an Image to Greyscale
5/4/2018 • 3 minutes to read • Edit Online
Example
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
</Page.Resources>
<StackPanel>
<!-- Apply the "convertFormatImage" resource defined above to this image. -->
<Image Width="200" Source="{StaticResource convertFormatImage}" />
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace SDKSample
{
public partial class FormatConvertedBitmapExample : Page
{
public FormatConvertedBitmapExample()
{
///// Create a BitmapImage and set it's DecodePixelWidth to 200. Use /////
///// this BitmapImage as a source for other BitmapSource objects. /////
// Use the BitmapSource object defined above as the source for this new
// BitmapSource (chain the BitmapSource objects together).
newFormatedBitmapSource.Source = myBitmapImage;
Namespace SDKSample
Class FormatConvertedBitmapExample
Inherits Page
'/// Create a BitmapImage and set it's DecodePixelWidth to 200. Use /////
'/// this BitmapImage as a source for other BitmapSource objects. /////
Dim myBitmapImage As New BitmapImage()
' BitmapSource objects like BitmapImage can only have their properties
' changed within a BeginInit/EndInit block.
myBitmapImage.BeginInit()
myBitmapImage.UriSource = New Uri("sampleImages/WaterLilies.jpg", UriKind.Relative)
' BitmapSource objects like FormatConvertedBitmap can only have their properties
' changed within a BeginInit/EndInit block.
newFormatedBitmapSource.BeginInit()
' Use the BitmapSource object defined above as the source for this new
' BitmapSource (chain the BitmapSource objects together).
newFormatedBitmapSource.Source = myBitmapImage
Example
The following Extensible Application Markup Language (XAML ) defines resources used within the samples below.
<Page.Resources>
<!-- Define some image resources, for use as the image element source. -->
<BitmapImage x:Key="masterImage" UriSource="/sampleImages/gecko.jpg" />
<CroppedBitmap x:Key="croppedImage"
Source="{StaticResource masterImage}" SourceRect="30 20 105 50"/>
</Page.Resources>
<!-- Use the cropped image resource as the images source -->
<Image Width="200" Source="{StaticResource croppedImage}"
Margin="5" Grid.Column="0" Grid.Row="1" />
The CroppedBitmap can also be used as the source of another CroppedBitmap, chaining the cropping. Note that
the SourceRect uses values that are relative to the source cropped bitmap and not the initial image.
<!-- Chain a cropped bitmap off a previosly defined cropped image -->
<Image Width="200" Grid.Column="0" Grid.Row="3" Margin="5">
<Image.Source>
<CroppedBitmap Source="{StaticResource croppedImage}"
SourceRect="30 0 75 50"/>
</Image.Source>
</Image>
See Also
Create a Clip Region
How to: Rotate an Image
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to rotate an image 90 degrees by using a Rotation property of a BitmapImage.
Example
<Image Width="150" Margin="5" Grid.Column="0" Grid.Row="1">
<Image.Source>
<BitmapImage UriSource="/sampleImages/watermelon.jpg" Rotation="Rotate90" />
</Image.Source>
</Image>
//Create source
BitmapImage bi = new BitmapImage();
//BitmapImage properties must be in a BeginInit/EndInit block
bi.BeginInit();
bi.UriSource = new Uri(@"pack://application:,,/sampleImages/watermelon.jpg");
//Set image rotation
bi.Rotation = Rotation.Rotate270;
bi.EndInit();
//set image source
rotated270.Source = bi;
'Create source
Dim bi As New BitmapImage()
'BitmapImage properties must be in a BeginInit/EndInit block
bi.BeginInit()
bi.UriSource = New Uri("pack://application:,,/sampleImages/watermelon.jpg")
'Set image rotation
bi.Rotation = Rotation.Rotate270
bi.EndInit()
'set image source
rotated270.Source = bi
Label
8/31/2018 • 2 minutes to read • Edit Online
Label controls usually provide information in the user interface (UI). Historically, a Label has contained only text,
but because the Label that ships with Windows Presentation Foundation (WPF ) is a ContentControl, it can contain
either text or a UIElement.
A Label provides both functional and visual support for access keys. It is frequently used to enable quick keyboard
access to controls such as a TextBox. To assign a Label to a Control, set the Label.Target property to the control that
should get focus when the user presses the access key.
The following image shows a Label "Themes" that targets a ComboBox. When the user presses , the ComboBox
receives focus. For more information, see How to: Set the Target Property of a Label.
In This Section
How to: Set the Target Property of a Label
Reference
Label
How to: Create a Control That Has an Access Key and
Text Wrapping
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to create a control that has an access key and supports text wrapping. The example uses a
Label control to illustrate these concepts.
Example
Add Text Wrapping to Your Label
The Label control does not support text wrapping. If you need a label that wraps across multiple lines, you can nest
another element that does support text wrapping and put the element inside the label. The following example
shows how to use a TextBlock to make a label that wraps several lines of text.
See Also
How to: Set the Target Property of a Label
ListBox
5/4/2018 • 2 minutes to read • Edit Online
Typical ListBox
In This Section
How -to Topics
Reference
ListBox
ListBoxItem
Related Sections
ListBox How-to Topics
8/31/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the ListBox control to display selectable lists of items.
In This Section
Bind a ListBox to Data
Get a ListBoxItem
How to: Add Data to an ItemsControl
Improve the Scrolling Performance of a ListBox
Reference
ListBox
ListBoxItem
Related Sections
How to: Bind a ListBox to Data
5/4/2018 • 2 minutes to read • Edit Online
An application developer can create ListBox controls without specifying the contents of each ListBoxItem
separately. You can use data binding to bind data to the individual items.
The following example shows how to create a ListBox that populates the ListBoxItem elements by data binding to a
data source called Colors. In this case it is not necessary to use ListBoxItem tags to specify the content of each item.
Example
<Canvas.Resources>
<src:myColors x:Key="Colors"/>
</Canvas.Resources>
See Also
ListBox
ListBoxItem
Controls
How to: Get a ListBoxItem
5/4/2018 • 2 minutes to read • Edit Online
If you need to get a specific ListBoxItem at a particular index in a ListBox, you can use an ItemContainerGenerator.
Example
The following example shows a ListBox and its items.
The following example shows how to retrieve the item by specifying the index of the item in the
ContainerFromIndex property of the ItemContainerGenerator.
After you have retrieved the list box item, you can display the contents of the item, as shown in the following
example.
If a ListBox contains many items, the user interface response can be slow when a user scrolls the ListBox by using
the mouse wheel or dragging the thumb of a scrollbar. You can improve the performance of the ListBox when the
user scrolls by setting the VirtualizingStackPanel.VirtualizationMode attached property to
VirtualizationMode.Recycling.
Example
Description
The following example creates a ListBox and sets the VirtualizingStackPanel.VirtualizationMode attached property
to VirtualizationMode.Recycling to improve performance during scrolling.
Code
<StackPanel>
<StackPanel.Resources>
<src:LotsOfItems x:Key="data"/>
</StackPanel.Resources>
</StackPanel>
The following example shows the data that the previous example uses.
The ListView control provides the infrastructure to display a set of data items in different layouts or views.
The following illustration shows a ListView.
In This Section
Overviews
How -to Topics
Reference
ListView
ListViewItem
GridView
Related Sections
Data Binding Overview
Data Templating Overview
ListView Overviews
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section show you how to use a ListView control.
In This Section
ListView Overview
GridView Overview
GridView Column Header Styles and Templates Overview
Reference
ListView
GridView
Related Sections
How -to Topics
ListView Overview
8/31/2018 • 3 minutes to read • Edit Online
The ListView control provides the infrastructure to display a set of data items in different layouts or views. For
example, a user may want to display data items in a table and also to sort its columns.
What Is a ListView?
The ListView control is an ItemsControl that is derived from ListBox. Typically, its items are members of a data
collection and are represented as ListViewItem objects. A ListViewItem is a ContentControl and can contain only
a single child element. However, that child element can be any visual element.
<ListView.View>
<GridView AllowsColumnReorder="true"
ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding=
"{Binding Path=FirstName}"
Header="First Name" Width="100"/>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=LastName}"
Width="100">
<GridViewColumnHeader>Last Name
<GridViewColumnHeader.ContextMenu>
<ContextMenu MenuItem.Click="LastNameCM_Click"
Name="LastNameCM">
<MenuItem Header="Ascending" />
<MenuItem Header="Descending" />
</ContextMenu>
</GridViewColumnHeader.ContextMenu>
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=EmployeeNumber}"
Header="Employee No." Width="100"/>
</GridView>
</ListView.View>
</ListView>
The following illustration shows how the data appears for the previous example.
You can create a custom view mode by defining a class that inherits from the ViewBase class. The ViewBase class
provides the infrastructure that you need to create a custom view. For more information about how to create a
custom view, see Create a Custom View Mode for a ListView.
In a GridView, GridViewColumn objects bind to specified data fields. The following example binds a
GridViewColumn object to a data field by specifying a Binding for the DisplayMemberBinding property.
<GridViewColumn DisplayMemberBinding=
"{Binding Path=FirstName}"
Header="First Name" Width="100"/>
You can also specify a Binding as part of a DataTemplate definition that you use to style the cells in a column. In
the following example, the DataTemplate that is identified with a ResourceKey sets the Binding for a
GridViewColumn. Note that this example does not define the DisplayMemberBinding because doing so
overrides the binding that is specified by DataTemplate.
<DataTemplate x:Key="myCellTemplateMonth">
<DockPanel>
<TextBlock Foreground="DarkBlue" HorizontalAlignment="Center">
<TextBlock.Text>
<Binding Path="Month"/>
</TextBlock.Text>
</TextBlock>
</DockPanel>
</DataTemplate>
See Also
GridView
ListView
ListViewItem
Binding
GridView Overview
How -to Topics
Controls
GridView Overview
5/4/2018 • 5 minutes to read • Edit Online
GridView view mode is one of the view modes for a ListView control. The GridView class and its supporting
classes enable you and your users to view item collections in a table that typically uses buttons as interactive
column headers. This topic introduces the GridView class and outlines its use.
NOTE
The button controls that GridView uses for column headers are derived from ButtonBase.
GridView columns are represented by GridViewColumn objects, which can automatically size to their content.
Optionally, you can explicitly set a GridViewColumn to a specific width. You can resize columns by dragging the
gripper between column headers. You can also dynamically add, remove, replace, and reorder columns because
this functionality is built into GridView. However, GridView cannot directly update the data that it displays.
The following example shows how to define a GridView that displays employee data. In this example, ListView
defines the EmployeeInfoDataSource as the ItemsSource. The property definitions of DisplayMemberBinding bind
GridViewColumn content to EmployeeInfoDataSource data categories.
<ListView ItemsSource="{Binding Source=
{StaticResource EmployeeInfoDataSource}}">
<ListView.View>
<GridView AllowsColumnReorder="true"
ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding=
"{Binding Path=FirstName}"
Header="First Name" Width="100"/>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=LastName}"
Width="100">
<GridViewColumnHeader>Last Name
<GridViewColumnHeader.ContextMenu>
<ContextMenu MenuItem.Click="LastNameCM_Click"
Name="LastNameCM">
<MenuItem Header="Ascending" />
<MenuItem Header="Descending" />
</ContextMenu>
</GridViewColumnHeader.ContextMenu>
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=EmployeeNumber}"
Header="Employee No." Width="100"/>
</GridView>
</ListView.View>
</ListView>
The following illustration shows the table that the previous example creates.
GridView that displays data from an ItemsSource
NOTE
You can set the Width property to Double.NaN to produce the same effect.
See Also
ListView
ListViewItem
GridViewColumn
GridViewColumnHeader
GridViewRowPresenter
GridViewHeaderRowPresenter
ViewBase
ListView Overview
Sort a GridView Column When a Header Is Clicked
How -to Topics
GridView Column Header Styles and Templates
Overview
5/4/2018 • 2 minutes to read • Edit Online
This overview discusses the order of precedence for properties that you use to customize a column header in the
GridView view mode of a ListView control.
Properties
1ForHeader Template Properties, if you set both the template and template selector properties, the template
property takes precedence. For example, if you set both the ContentTemplate and ContentTemplateSelector
properties, the ContentTemplate property takes precedence.
See Also
How -to Topics
ListView Overview
GridView Overview
ListView How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the ListView control to display a set of data items.
In This Section
Sort a GridView Column When a Header Is Clicked
Create a Custom View Mode for a ListView
Use Templates to Style a ListView That Uses GridView
Create a Style for a Dragged GridView Column Header
Display ListView Contents by Using a GridView
Use Triggers to Style Selected Items in a ListView
Create ListViewItems with a CheckBox
Display Data by Using GridViewRowPresenter
Group Items in a ListView That Implements a GridView
Style a Row in a ListView That Implements a GridView
Change the Horizontal Alignment of a Column in a ListView
Handle the MouseDoubleClick Event for Each Item in a ListView
Reference
ListView
ListViewItem
GridView
Related Sections
ListView Overview
How to: Sort a GridView Column When a Header Is
Clicked
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to create a ListView control that implements a GridView view mode and sorts the data
content when a user clicks a column header.
Example
The following example defines a GridView with three columns that bind to the Year, Month, and Day, properties of
the DateTime structure.
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Year}"
Header="Year"
Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Month}"
Header="Month"
Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Day}"
Header="Day"
Width="100"/>
</GridView>
The following example shows the data items that are defined as an ArrayList of DateTime objects. The ArrayList is
defined as the ItemsSource for the ListView control.
<ListView.ItemsSource>
<s:ArrayList>
<p:DateTime>1993/1/1 12:22:02</p:DateTime>
<p:DateTime>1993/1/2 13:2:01</p:DateTime>
<p:DateTime>1997/1/3 2:1:6</p:DateTime>
<p:DateTime>1997/1/4 13:6:55</p:DateTime>
<p:DateTime>1999/2/1 12:22:02</p:DateTime>
<p:DateTime>1998/2/2 13:2:01</p:DateTime>
<p:DateTime>2000/2/3 2:1:6</p:DateTime>
<p:DateTime>2002/2/4 13:6:55</p:DateTime>
<p:DateTime>2001/3/1 12:22:02</p:DateTime>
<p:DateTime>2006/3/2 13:2:01</p:DateTime>
<p:DateTime>2004/3/3 2:1:6</p:DateTime>
<p:DateTime>2004/3/4 13:6:55</p:DateTime>
</s:ArrayList>
</ListView.ItemsSource>
The s and p identifiers in the XAML tags refer to namespace mappings that are defined in the metadata of the
XAML page. The following example shows the metadata definition.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ListViewSort.Window1"
xmlns:s="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:p="clr-namespace:System;assembly=mscorlib">
To sort the data according to the contents of a column, the example defines an event handler to handle the Click
event that occurs when you press the column header button. The following example shows how to specify an
event handler for the GridViewColumnHeader control.
The example defines the event handler so that the sort direction changes between ascending order and
descending order each time you press the column header button. The following example shows the event handler.
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
if (headerClicked != null)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
Sort(sortBy, direction);
if (direction == ListSortDirection.Ascending)
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowUp"] as DataTemplate;
}
else
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowDown"] as DataTemplate;
}
_lastHeaderClicked = headerClicked;
_lastDirection = direction;
}
}
}
}
Partial Public Class Window1
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
Sort(sortBy, direction)
_lastHeaderClicked = headerClicked
_lastDirection = direction
End If
End If
End Sub
End Class
The following example shows the sorting algorithm that is called by the event handler to sort the data. The sort is
performed by creating a new SortDescription structure.
dataView.SortDescriptions.Clear();
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
Private Sub Sort(ByVal sortBy As String, ByVal direction As ListSortDirection)
Dim dataView As ICollectionView = CollectionViewSource.GetDefaultView(lv.ItemsSource)
dataView.SortDescriptions.Clear()
Dim sd As New SortDescription(sortBy, direction)
dataView.SortDescriptions.Add(sd)
dataView.Refresh()
End Sub
See Also
ListView
GridView
ListView Overview
GridView Overview
How -to Topics
How to: Create a Custom View Mode for a ListView
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to create a custom View mode for a ListView control.
Example
You must use the ViewBase class when you create a custom view for the ListView control. The following example
shows a view mode that is called PlainView , which is derived from the ViewBase class.
public class PlainView : ViewBase
{
}
Public Class PlainView
Inherits ViewBase
End Class
To apply a style to the custom view, use the Style class. The following example defines a Style for the PlainView
view mode. In the previous example, this style is set as the value of the DefaultStyleKey property that is defined for
PlainView .
<Style x:Key="{ComponentResourceKey
TypeInTargetAssembly={x:Type l:PlainView},
ResourceId=myPlainViewDSK}"
TargetType="{x:Type ListView}"
BasedOn="{StaticResource {x:Type ListBox}}"
>
<Setter Property="HorizontalContentAlignment"
Value="Center"/>
<Setter Property="ItemContainerStyle"
Value="{Binding (ListView.View).ItemContainerStyle,
RelativeSource={RelativeSource Self}}"/>
<Setter Property="ItemTemplate"
Value="{Binding (ListView.View).ItemTemplate,
RelativeSource={RelativeSource Self}}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource
AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
To define the layout of data in a custom view mode, define a DataTemplate object. The following example defines a
DataTemplate that can be used to display data in the PlainView view mode.
<DataTemplate x:Key="centralTile">
<StackPanel Height="100" Width="90">
<Grid Width="70" Height="70" HorizontalAlignment="Center">
<Image Source="{Binding XPath=@Image}" Margin="6,6,6,9"/>
</Grid>
<TextBlock Text="{Binding XPath=@Name}" FontSize="13"
HorizontalAlignment="Center" Margin="0,0,0,1" />
<TextBlock Text="{Binding XPath=@Type}" FontSize="9"
HorizontalAlignment="Center" Margin="0,0,0,1" />
</StackPanel>
</DataTemplate>
The following example shows how to define a ResourceKey for the PlainView view mode that uses the
DataTemplate that is defined in the previous example.
<l:PlainView x:Key="tileView"
ItemTemplate="{StaticResource centralTile}"
ItemWidth="100"/>
A ListView control can use a custom view if you set the View property to the resource key. The following example
shows how to specify PlainView as the view mode for a ListView.
For the complete sample, see ListView with Multiple Views Sample.
See Also
ListView
GridView
How -to Topics
ListView Overview
GridView Overview
How to: Use Templates to Style a ListView That Uses
GridView
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the DataTemplate and Style objects to specify the appearance of a ListView control
that uses a GridView view mode.
Example
The following examples show Style and DataTemplate objects that customize the appearance of a column header
for a GridViewColumn.
<DataTemplate x:Key="myHeaderTemplate">
<DockPanel>
<CheckBox/>
<TextBlock FontSize="16" Foreground="DarkBlue">
<TextBlock.Text>
<Binding/>
</TextBlock.Text>
</TextBlock>
</DockPanel>
</DataTemplate>
The following example shows how to use these Style and DataTemplate objects to set the HeaderContainerStyle
and HeaderTemplate properties of a GridViewColumn. The DisplayMemberBinding property defines the content
of the column cells.
The HeaderContainerStyle and HeaderTemplate are only two of several properties that you can use to customize
column header appearance for a GridView control. For more information, see GridView Column Header Styles and
Templates Overview.
The following example shows how to define a DataTemplate that customizes the appearance of the cells in a
GridViewColumn.
<DataTemplate x:Key="myCellTemplateMonth">
<DockPanel>
<TextBlock Foreground="DarkBlue" HorizontalAlignment="Center">
<TextBlock.Text>
<Binding Path="Month"/>
</TextBlock.Text>
</TextBlock>
</DockPanel>
</DataTemplate>
The following example shows how to use this DataTemplate to define the content of a GridViewColumn cell. This
template is used instead of the DisplayMemberBinding property that is shown in the previous GridViewColumn
example.
See Also
ListView
GridView
GridView Overview
How -to Topics
ListView Overview
How to: Create a Style for a Dragged GridView
Column Header
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to change the appearance of a dragged GridViewColumnHeader when the user changes
the position of a column.
Example
When you drag a column header to another location in a ListView that uses GridView for its view mode, the
column moves to the new position. While you are dragging the column header, a floating copy of the header
appears in addition to the original header. A column header in a GridView is represented by a
GridViewColumnHeader object.
To customize the appearance of both the floating and original headers, you can set Triggers to modify the
GridViewColumnHeader Style. These Triggers are applied when the IsPressed property value is true and the
Role property value is Floating.
When the user presses the mouse button and holds it down while the mouse pauses on the
GridViewColumnHeader, the IsPressed property value changes to true . Likewise, when the user begins the drag
operation, the Role property changes to Floating.
The following example shows how to set Triggers to change the Foreground and Background colors of the original
and floating headers when the user drags a column to a new position.
<ControlTemplate.Triggers>
<Trigger Property="IsPressed"
Value="true">
<Setter TargetName="HighlightBorder"
Property="Visibility"
Value="Hidden"/>
<Setter TargetName="PART_HeaderGripper"
Property="Visibility"
Value="Hidden"/>
<Setter Property="Background"
Value="SkyBlue"/>
<Setter Property="Foreground"
Value="Yellow"/>
</Trigger>
<Trigger Property="Role"
Value="Floating">
<Setter TargetName="PART_HeaderGripper"
Property="Visibility"
Value="Collapsed"/>
<Setter Property="Background"
Value="Yellow"/>
<Setter Property="Foreground"
Value="SkyBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
See Also
GridViewColumnHeader
GridViewColumnHeaderRole
ListView
GridView
How -to Topics
ListView Overview
GridView Overview
How to: Display ListView Contents by Using a
GridView
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to define a GridView view mode for a ListView control.
Example
You can define the view mode of a GridView by specifying GridViewColumn objects. The following example shows
how to define GridViewColumn objects that bind to the data content that is specified for the ListView control. This
GridView example specifies three GridViewColumn objects that map to the FirstName , LastName , and
EmployeeNumber fields of the EmployeeInfoDataSource that is set as the ItemsSource of the ListView control.
<ListView.View>
<GridView AllowsColumnReorder="true"
ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding=
"{Binding Path=FirstName}"
Header="First Name" Width="100"/>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=LastName}"
Width="100">
<GridViewColumnHeader>Last Name
<GridViewColumnHeader.ContextMenu>
<ContextMenu MenuItem.Click="LastNameCM_Click"
Name="LastNameCM">
<MenuItem Header="Ascending" />
<MenuItem Header="Descending" />
</ContextMenu>
</GridViewColumnHeader.ContextMenu>
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding=
"{Binding Path=EmployeeNumber}"
Header="Employee No." Width="100"/>
</GridView>
</ListView.View>
</ListView>
This example shows how to define Triggers for a ListViewItem control so that when a property value of a
ListViewItem changes, the Style of the ListViewItem changes in response.
Example
If you want the Style of a ListViewItem to change in response to property changes, define Triggers for the Style
change.
The following example defines a Trigger that sets the Foreground property to Blue and changes the Cursor to
display a Hand when the IsMouseOver property changes to true .
<Style.Triggers>
</Style.Triggers>
</Style>
The following example defines a MultiTrigger that sets the Foreground property of a ListViewItem to Yellow when
the ListViewItem is the selected item and has keyboard focus.
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="true" />
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="Yellow" />
</MultiTrigger>
</Style.Triggers>
</Style>
See Also
Control
ListView
GridView
How -to Topics
ListView Overview
GridView Overview
How to: Create ListViewItems with a CheckBox
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to display a column of CheckBox controls in a ListView control that uses a GridView.
Example
To create a column that contains CheckBox controls in a ListView, create a DataTemplate that contains a CheckBox.
Then set the CellTemplate of a GridViewColumn to the DataTemplate.
The following example shows a DataTemplate that contains a CheckBox. The example binds the IsChecked
property of the CheckBox to the IsSelected property value of the ListViewItem that contains it. Therefore, when the
ListViewItem that contains the CheckBox is selected, the CheckBox is checked.
<DataTemplate x:Key="FirstCell">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsSelected,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"/>
</StackPanel>
</DataTemplate>
The following example shows how to create a column of CheckBox controls. To make the column, the example sets
the CellTemplate property of the GridViewColumn to the DataTemplate.
See Also
Control
ListView
GridView
ListView Overview
How -to Topics
GridView Overview
How to: Display Data by Using
GridViewRowPresenter
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the GridViewRowPresenter and GridViewHeaderRowPresenter objects to display
data in columns.
Example
The following example shows how to specify a GridViewColumnCollection that displays the DayOfWeek and Year
of a DateTime object by using GridViewRowPresenter and GridViewHeaderRowPresenter objects. The example
also defines a Style for the Header of a GridViewColumn.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<GridViewColumnCollection x:Key="gvcc">
<GridViewColumn Header="Year"
DisplayMemberBinding="{Binding Year}"
Width="80"/>
<GridViewColumn Header="Day"
DisplayMemberBinding="{Binding DayOfWeek}"
Width="80" />
</GridViewColumnCollection>
</Window.Resources>
<StackPanel>
<GridViewHeaderRowPresenter Name="hrp" Columns="{StaticResource gvcc}"
ColumnHeaderContainerStyle=
"{StaticResource MyHeaderStyle}" />
</Window>
See Also
GridViewHeaderRowPresenter
GridViewRowPresenter
GridViewColumnCollection
GridView Overview
How to: Group Items in a ListView That Implements a
GridView
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to display groups of items in the GridView view mode of a ListView control.
Example
To display groups of items in a ListView, define a CollectionViewSource. The following example shows a
CollectionViewSource that groups data items according to the value of the Catalog data field.
<CollectionViewSource x:Key='src'
Source="{Binding Source={StaticResource MyData},
XPath=Item}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="@Catalog" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
The following example sets the ItemsSource for the ListView to the CollectionViewSource that the previous
example defines. The example also defines a GroupStyle that implements an Expander control.
See Also
ListView
GridView
How -to Topics
ListView Overview
GridView Overview
How to: Style a Row in a ListView That Implements a
GridView
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to style a row in a ListView control that implements a GridViewView mode.
Example
You can style a row in a ListView control by setting an ItemContainerStyle on the ListView control. Set the style for
its items that are represented as ListViewItem objects. The ItemContainerStyle references the ControlTemplate
objects that are used to display the row content.
The complete sample, which the following examples are extracted from, displays a collection of song information
that is stored in an XML database. Each song in the database has a rating field and the value of this field specifies
how to display a row of song information.
The following example shows how to define ItemContainerStyle for the ListViewItem objects that represent the
songs in the song collection. The ItemContainerStyle references ControlTemplate objects that specify how to
display a row of song information.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" >
<Setter Property="Template"
Value="{StaticResource Default}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding XPath=@Rating}" Value="5">
<Setter Property="Template"
Value="{StaticResource StronglyRecommended}"/>
</DataTrigger>
<DataTrigger Binding="{Binding XPath=@Rating}" Value="4">
<Setter Property="Template"
Value="{StaticResource Recommended}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
The following example shows a ControlTemplate that adds the text string "Strongly Recommended" to the row. This
template is referenced in the ItemContainerStyle and displays when the song's rating has a value of 5 (five). The
ControlTemplate includes a GridViewRowPresenter object that lays out the contents of the row in columns as
defined by the GridView view mode.
<ControlTemplate x:Key="StronglyRecommended"
TargetType='{x:Type ListViewItem}'>
<StackPanel Background="Beige">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}"/>
<TextBlock Background="LightBlue" Text="Strongly Recommended" />
</StackPanel>
</ControlTemplate>
See Also
ListView
GridView
How -to Topics
ListView Overview
Styling and Templating
How to: Change the Horizontal Alignment of a
Column in a ListView
5/4/2018 • 2 minutes to read • Edit Online
By default, the content of each column in a ListViewItem is left-aligned. You can change the alignment of each
column by providing a DataTemplate and setting the HorizontalAlignment property on the element within the
DataTemplate. This topic shows how a ListView aligns its content by default and how to change the alignment of
one column in a ListView.
Example
In the following example, the data in the Title and ISBN columns is left-aligned.
To change the alignment of the ISBN column, you need to specify that the HorizontalContentAlignment property
of each ListViewItem is Stretch, so that the elements in each ListViewItem can span or be positioned along the
entire width of each column. Because the ListView is bound to a data source, you need to create a style that sets
the HorizontalContentAlignment. Next, you need to use a DataTemplate to display the content instead of using the
DisplayMemberBinding property. To display the ISBN of each template, the DataTemplate can just contain a
TextBlock that has its HorizontalAlignment property set to Right.
The following example defines the style and DataTemplate necessary to make the ISBN column right-aligned, and
changes the GridViewColumn to reference the DataTemplate.
<DataTemplate x:Key="ISBNTemplate">
<TextBlock HorizontalAlignment="Right"
Text="{Binding XPath=@ISBN}"/>
</DataTemplate>
See Also
Data Binding Overview
Data Templating Overview
Bind to XML Data Using an XMLDataProvider and XPath Queries
ListView Overview
How to: Handle the MouseDoubleClick Event for
Each Item in a ListView
5/4/2018 • 2 minutes to read • Edit Online
To handle an event for an item in a ListView, you need to add an event handler to each ListViewItem. When a
ListView is bound to a data source, you don't explicitly create a ListViewItem, but you can handle the event for each
item by adding an EventSetter to a style of a ListViewItem.
Example
The following example creates a data-bound ListView and creates a Style to add an event handler to each
ListViewItem.
if (book == null)
{
return;
}
if (book.GetAttribute("Stock") == "out")
{
MessageBox.Show("Time to order more copies of " + book["Title"].InnerText);
}
else
{
MessageBox.Show(book["Title"].InnerText + " is available.");
}
}
NOTE
Although it is most common to bind a ListView to a data source, you can use a style to add an event handler to each
ListViewItem in a non-data-bound ListView regardless of whether you explicitly create a ListViewItem. For more information
about explicitly and implicitly created ListViewItem controls, see ItemsControl.
See Also
XmlElement
Data Binding Overview
Styling and Templating
Bind to XML Data Using an XMLDataProvider and XPath Queries
ListView Overview
Menu
5/4/2018 • 2 minutes to read • Edit Online
A Menu is a control that allows hierarchical organization of elements associated with commands or event handlers.
Each Menu can contain multiple MenuItem controls. Each MenuItem can invoke a command or invoke a Click
event handler. A MenuItem can also have multiple MenuItem elements as children, forming a submenu.
The following illustration shows the three different states of a menu control. The default state is when no device
such as a mouse pointer is resting on the Menu. The focus state occurs when the mouse pointer is hovering over
the Menu and pressed state occurs when a mouse button is clicked over the Menu.
In This Section
Menu Overview
Reference
Menu
MenuItem
MenuBase
ContextMenu
Related Sections
Menu Overview
8/31/2018 • 3 minutes to read • Edit Online
The Menu class enables you to organize elements associated with commands and event handlers in a hierarchical
order. Each Menu element contains a collection of MenuItem elements.
Menu Control
The Menu control presents a list of items that specify commands or options for an application. Typically, clicking a
MenuItem opens a submenu or causes an application to carry out a command.
Creating Menus
The following example creates a Menu to manipulate text in a TextBox. The Menu contains MenuItem objects that
use the Command, IsCheckable, and Header properties and the Checked, Unchecked, and Click events.
<Menu>
<MenuItem Header="_Edit">
<MenuItem Command="ApplicationCommands.Copy"/>
<MenuItem Command="ApplicationCommands.Cut"/>
<MenuItem Command="ApplicationCommands.Paste"/>
</MenuItem>
<MenuItem Header="_Font">
<MenuItem Header="_Bold" IsCheckable="True"
Checked="Bold_Checked"
Unchecked="Bold_Unchecked"/>
<MenuItem Header="_Italic" IsCheckable="True"
Checked="Italic_Checked"
Unchecked="Italic_Unchecked"/>
<Separator/>
<MenuItem Header="I_ncrease Font Size"
Click="IncreaseFont_Click"/>
<MenuItem Header="_Decrease Font Size"
Click="DecreaseFont_Click"/>
</MenuItem>
</Menu>
<TextBox Name="textBox1" TextWrapping="Wrap"
Margin="2">
The quick brown fox jumps over the lazy dog.
</TextBox>
private void Bold_Checked(object sender, RoutedEventArgs e)
{
textBox1.FontWeight = FontWeights.Bold;
}
Command
The following example shows how to use the Command property to associate the Open and Save commands
with MenuItem controls. Not only does the command property associate a command with a MenuItem, but it also
supplies the input gesture text to use as a shortcut.
The MenuItem class also has a CommandTarget property, which specifies the element where the command occurs.
If CommandTarget is not set, the element that has keyboard focus receives the command. For more information
about commands, see Commanding Overview.
Menu Styling
With control styling, you can dramatically change the appearance and behavior of Menu controls without having to
write a custom control. In addition to setting visual properties, you can also apply a Style to individual parts of a
control, change the behavior of parts of the control through properties, or add additional parts or change the
layout of a control. The following examples demonstrate several ways to add a Style to a Menu control.
The first code example defines a Style called Simple that shows how to use the current system settings in your
style. The code assigns the color of the MenuHighlightBrush as the menu's background color and the MenuTextBrush
as the menu's foreground color. Notice that you use resource keys to assign the brushes.
The following sample uses Trigger elements that enable you to change the appearance of a MenuItem in response
to events that occur on the Menu. When you move the mouse over the Menu, the foreground color and the font
characteristics of the menu items change.
<Style x:Key="Triggers" TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="MenuItem.IsMouseOver" Value="true">
<Setter Property = "Foreground" Value="Red"/>
<Setter Property = "FontSize" Value="16"/>
<Setter Property = "FontStyle" Value="Italic"/>
</Trigger>
</Style.Triggers>
</Style>
See Also
WPF Controls Gallery Sample
Panel
5/4/2018 • 2 minutes to read • Edit Online
Panel is the base class for all elements that support application layout in Windows Presentation Foundation (WPF ).
In This Section
Panels Overview
How -to Topics
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
Panels Overview
8/31/2018 • 32 minutes to read • Edit Online
Panel elements are components that control the rendering of elements—their size and dimensions, their
position, and the arrangement of their child content. The Windows Presentation Foundation (WPF ) provides a
number of predefined Panel elements as well as the ability to construct custom Panel elements.
This topic contains the following sections.
The Panel Class
Panel Element Common Members
Derived Panel Elements
User Interface Panels
Nested Panel Elements
Custom Panel Elements
Localization/Globalization Support
More detailed descriptions and usage examples of each of these elements can be found below.
Canvas
The Canvas element enables positioning of content according to absolute x- and y-coordinates. Elements can
be drawn in a unique location; or, if elements occupy the same coordinates, the order in which they appear in
markup determines the order in which the elements are drawn.
Canvas provides the most flexible layout support of any Panel. Height and Width properties are used to
define the area of the canvas, and elements inside are assigned absolute coordinates relative to the area of the
parent Canvas. Four attached properties, Canvas.Left, Canvas.Top, Canvas.Right and Canvas.Bottom, allow
fine control of object placement within a Canvas, allowing the developer to position and arrange elements
precisely on the screen.
ClipToBounds Within a Canvas
Canvas can position child elements at any position on the screen, even at coordinates that are outside of its
own defined Height and Width. Furthermore, Canvas is not affected by the size of its children. As a result, it is
possible for a child element to overdraw other elements outside the bounding rectangle of the parent Canvas.
The default behavior of a Canvas is to allow children to be drawn outside the bounds of the parent Canvas. If
this behavior is undesirable, the ClipToBounds property can be set to true . This causes Canvas to clip to its
own size. Canvas is the only layout element that allows children to be drawn outside its bounds.
This behavior is graphically illustrated in the Width Properties Comparison Sample.
Defining and Using a Canvas
A Canvas can be instantiated simply by using Extensible Application Markup Language (XAML ) or code. The
following example demonstrates how to use Canvas to absolutely position content. This code produces three
100-pixel squares. The first square is red, and its top-left (x, y) position is specified as (0, 0). The second square
is green, and its top-left position is (100, 100), just below and to the right of the first square. The third square
is blue, and its top-left position is (50, 50), thus encompassing the lower-right quadrant of the first square and
the upper-left quadrant of the second. Because the third square is laid out last, it appears to be on top of the
other two squares—that is, the overlapping portions assume the color of the third box.
' Add the parent Canvas as the Content of the Window Object
Me.Content = myParentCanvas
DockPanel
The DockPanel element uses the DockPanel.Dock attached property as set in child content elements to
position content along the edges of a container. When DockPanel.Dock is set to Top or Bottom, it positions
child elements above or below each other. When DockPanel.Dock is set to Left or Right, it positions child
elements to the left or right of each other. The LastChildFill property determines the position of the final
element added as a child of a DockPanel.
You can use DockPanel to position a group of related controls, such as a set of buttons. Alternately, you can
use it to create a "paned" UI, similar to that found in Microsoft Outlook.
Sizing to Content
If its Height and Width properties are not specified, DockPanel sizes to its content. The size can increase or
decrease to accommodate the size of its child elements. However, when these properties are specified and
there is no longer room for the next specified child element, DockPanel does not display that child element or
subsequent child elements and does not measure subsequent child elements.
LastChildFill
By default, the last child of a DockPanel element will "fill" the remaining, unallocated space. If this behavior is
not desired, set the LastChildFill property to false .
Defining and Using a DockPanel
The following example demonstrates how to partition space using a DockPanel. Five Border elements are
added as children of a parent DockPanel. Each uses a different positioning property of a DockPanel to
partition space. The final element "fills" the remaining, unallocated space.
Grid
The Grid element merges the functionality of an absolute positioning and tabular data control. A Grid enables
you to easily position and style elements. Grid allows you to define flexible row and column groupings, and
even provides a mechanism to share sizing information between multiple Grid elements.
How is Grid Different from Table?
Table and Grid share some common functionality, but each is best suited for different scenarios. A Table is
designed for use within flow content (see Flow Document Overview for more information on flow content).
Grids are best used inside of forms (basically anywhere outside of flow content). Within a FlowDocument,
Table supports flow content behaviors like pagination, column reflow, and content selection while a Grid does
not. A Grid on the other hand is best used outside of a FlowDocument for many reasons including Grid adds
elements based on a row and column index, Table does not. The Grid element allows layering of child content,
allowing more than one element to exist within a single "cell." Table does not support layering. Child elements
of a Grid can be absolutely positioned relative to the area of their "cell" boundaries. Table does not support
this feature. Finally, a Grid is lighter weight than a Table.
Sizing Behavior of Columns and Rows
Columns and rows defined within a Grid can take advantage of Star sizing in order to distribute remaining
space proportionally. When Star is selected as the Height or Width of a row or column, that column or row
receives a weighted proportion of remaining available space. This is in contrast to Auto, which will distribute
space evenly based on the size of the content within a column or row. This value is expressed as * or 2*
when using Extensible Application Markup Language (XAML ). In the first case, the row or column would
receive one times the available space, in the second case, two times, and so on. By combining this technique to
proportionally distribute space with a HorizontalAlignment and VerticalAlignment value of Stretch it is
possible to partition layout space by percentage of screen space. Grid is the only layout panel that can
distribute space in this manner.
Defining and Using a Grid
The following example demonstrates how to build a UI similar to that found on the Run dialog available on
the Windows Start menu.
grid1.Children.Add(img1);
grid1.Children.Add(txt1);
grid1.Children.Add(txt2);
grid1.Children.Add(tb1);
grid1.Children.Add(button1);
grid1.Children.Add(button2);
grid1.Children.Add(button3);
mainWindow.Content = grid1;
Grid.SetRow(button1, 3)
Grid.SetColumn(button1, 2)
Grid.SetRow(button2, 3)
Grid.SetColumn(button2, 3)
Grid.SetRow(button3, 3)
Grid.SetColumn(button3, 4)
myGrid.Children.Add(button1)
myGrid.Children.Add(button2)
myGrid.Children.Add(button3)
Me.Content = myGrid
StackPanel
A StackPanel enables you to "stack" elements in an assigned direction. The default stack direction is vertical.
The Orientation property can be used to control content flow.
StackPanel vs. DockPanel
Although DockPanel can also "stack" child elements, DockPanel and StackPanel do not produce analogous
results in some usage scenarios. For example, the order of child elements can affect their size in a DockPanel
but not in a StackPanel. This is because StackPanel measures in the direction of stacking at PositiveInfinity,
whereas DockPanel measures only the available size.
The following example demonstrates this key difference.
//Define a StackPanel
myStackPanel = gcnew StackPanel();
myStackPanel->Orientation = Orientation::Horizontal;
Grid::SetRow(myStackPanel, 1);
//Define a StackPanel
myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Horizontal;
Grid.SetRow(myStackPanel, 1);
'Define a StackPanel.
Dim myStackPanel As New StackPanel
myStackPanel.Orientation = Orientation.Horizontal
Grid.SetRow(myStackPanel, 1)
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="StackPanel vs. DockPanel">
<Grid Width="175" Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
Me.Content = myStackPanel
VirtualizingStackPanel
WPF also provides a variation of the StackPanel element that automatically "virtualizes" data-bound child
content. In this context, the word virtualize refers to a technique by which a subset of elements are generated
from a larger number of data items based upon which items are visible on-screen. It is intensive, both in
terms of memory and processor, to generate a large number of UI elements when only a few may be on the
screen at a given time. VirtualizingStackPanel (through functionality provided by VirtualizingPanel) calculates
visible items and works with the ItemContainerGenerator from an ItemsControl (such as ListBox or ListView )
to only create elements for visible items.
The VirtualizingStackPanel element is automatically set as the items host for controls such as the ListBox.
When hosting a data bound collection, content is automatically virtualized, as long as the content is within the
bounds of a ScrollViewer. This greatly improves performance when hosting many child items.
The following markup demonstrates how to use a VirtualizingStackPanel as an items host. The
VirtualizingStackPanel.IsVirtualizingProperty attached property must be set to true (default) for
virtualization to occur.
WrapPanel
WrapPanel is used to position child elements in sequential position from left to right, breaking content to the
next line when it reaches the edge of its parent container. Content can be oriented horizontally or vertically.
WrapPanel is useful for simple flowing user interface (UI) scenarios. It can also be used to apply uniform
sizing to all of its child elements.
The following example demonstrates how to create a WrapPanel to display Button controls that wrap when
they reach the edge of their container.
// Create the application's main window
mainWindow = gcnew System::Windows::Window();
mainWindow->Title = "WrapPanel Sample";
myWrapPanel->ItemWidth = 75;
myWrapPanel->Width = 150;
myWrapPanel->HorizontalAlignment = HorizontalAlignment::Left;
myWrapPanel->VerticalAlignment = VerticalAlignment::Top;
// Define 3 button elements. Each button is sized at width of 75, so the third button wraps to the next
line.
btn1 = gcnew Button();
btn1->Content = "Button 1";
btn2 = gcnew Button();
btn2->Content = "Button 2";
btn3 = gcnew Button();
btn3->Content = "Button 3";
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel->Children->Add(btn1);
myWrapPanel->Children->Add(btn2);
myWrapPanel->Children->Add(btn3);
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
btn1 = new Button();
btn1.Content = "Button 1";
btn1.Width = 200;
btn2 = new Button();
btn2.Content = "Button 2";
btn2.Width = 75;
btn3 = new Button();
btn3.Content = "Button 3";
btn3.Width = 75;
btn4 = new Button();
btn4.Content = "Button 4";
btn4.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
myWrapPanel.Children.Add(btn3);
myWrapPanel.Children.Add(btn4);
myWrapPanel.Width = 200
myWrapPanel.HorizontalAlignment = Windows.HorizontalAlignment.Left
myWrapPanel.VerticalAlignment = Windows.VerticalAlignment.Top
' Define 3 button elements. The last three buttons are sized at width
' of 75, so the forth button wraps to the next line.
Dim btn1 As New Button()
btn1.Content = "Button 1"
btn1.Width = 200
Dim btn2 As New Button()
btn2.Content = "Button 2"
btn2.Width = 75
Dim btn3 As New Button()
btn3.Content = "Button 3"
btn3.Width = 75
Dim btn4 As New Button()
btn4.Content = "Button 4"
btn4.Width = 75
' Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1)
myWrapPanel.Children.Add(btn2)
myWrapPanel.Children.Add(btn3)
myWrapPanel.Children.Add(btn4)
myDockPanel.Children.Add(myBorder2)
myDockPanel.Children.Add(myBorder3)
myDockPanel.Children.Add(myBorder4)
myDockPanel.Children.Add(myBorder5)
public:
PlotPanel () {};
protected:
// Override the default Measure method of Panel
virtual Size MeasureOverride(Size availableSize) override
{
Size^ panelDesiredSize = gcnew Size();
protected:
virtual System::Windows::Size ArrangeOverride (Size finalSize) override
{
for each (UIElement^ child in InternalChildren)
{
double x = 50;
double y = 50;
child->Arrange(Rect(Point(x, y), child->DesiredSize));
}
return finalSize;
};
};
public class PlotPanel : Panel
{
// Default public constructor
public PlotPanel()
: base()
{
}
return panelDesiredSize ;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
double x = 50;
double y = 50;
To view a more complex custom panel implementation, see Create a Custom Content-Wrapping Panel
Sample.
Localization/Globalization Support
WPF supports a number of features that assist in the creation of localizable UI.
All panel elements natively support the FlowDirection property, which can be used to dynamically re-flow
content based on a user's locale or language settings. For more information, see FlowDirection.
The SizeToContent property provides a mechanism that enables application developers to anticipate the
needs of localized UI. Using the WidthAndHeight value of this property, a parent Window always sizes
dynamically to fit content and is not constrained by artificial height or width restrictions.
DockPanel, Grid, and StackPanel are all good choices for localizable UI. Canvas is not a good choice, however,
because it positions content absolutely, making it difficult to localize.
For additional information on creating WPF applications with localizable user interfaces (UIs)s, see the Use
Automatic Layout Overview.
See Also
Walkthrough: My first WPF desktop application
WPF Layout Gallery Sample
Layout
WPF Controls Gallery Sample
Alignment, Margins, and Padding Overview
Create a Custom Content-Wrapping Panel Sample
Attached Properties Overview
Use Automatic Layout Overview
Layout and Design
Panel How-to Topics
8/31/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the Panel element and related APIs.
In This Section
How to: Apply a LayoutTransform to an Element
Create a Custom Panel Element
Override the Panel OnRender Method
Set the Height Properties of an Element
Set the Width Properties of an Element
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
How to: Create a Custom Panel Element
8/31/2018 • 2 minutes to read • Edit Online
Example
This example shows how to override the default layout behavior of the Panel element and create custom layout
elements that are derived from Panel.
The example defines a simple custom Panel element called PlotPanel , which positions child elements according to
two hard-coded x- and y-coordinates. In this example, x and y are both set to 50 ; therefore, all child elements
are positioned at that location on the x and y axes.
To implement custom Panel behaviors, the example uses the MeasureOverride and ArrangeOverride methods.
Each method returns the Size data that is necessary to position and render child elements.
public:
ref class PlotPanel : Panel {
public:
PlotPanel () {};
protected:
// Override the default Measure method of Panel
virtual Size MeasureOverride(Size availableSize) override
{
Size^ panelDesiredSize = gcnew Size();
protected:
virtual System::Windows::Size ArrangeOverride (Size finalSize) override
{
for each (UIElement^ child in InternalChildren)
{
double x = 50;
double y = 50;
child->Arrange(Rect(Point(x, y), child->DesiredSize));
}
return finalSize;
};
};
public class PlotPanel : Panel
{
// Default public constructor
public PlotPanel()
: base()
{
}
return panelDesiredSize ;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
double x = 50;
double y = 50;
See Also
Panel
Panels Overview
Create a Custom Content-Wrapping Panel Sample
How to: Override the Panel OnRender Method
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to override the OnRender method of Panel in order to add custom graphical effects to a
layout element.
Example
Use the OnRender method in order to add graphical effects to a rendered panel element. For example, you can use
this method to add custom border or background effects. A DrawingContext object is passed as an argument,
which provides methods for drawing shapes, text, images, or videos. As a result, this method is useful for
customization of a panel object.
// Override the OnRender call to add a Background and Border to the OffSetPanel
protected override void OnRender(DrawingContext dc)
{
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Colors.LimeGreen;
Pen myPen = new Pen(Brushes.Blue, 10);
Rect myRect = new Rect(0, 0, 500, 500);
dc.DrawRectangle(mySolidColorBrush, myPen, myRect);
}
' Override the OnRender call to add a Background and Border to the OffSetPanel
Protected Overrides Sub OnRender(ByVal dc As DrawingContext)
Dim mySolidColorBrush As New SolidColorBrush()
mySolidColorBrush.Color = Colors.LimeGreen
Dim myPen As New Pen(Brushes.Blue, 10)
Dim myRect As New Rect(0, 0, 500, 500)
dc.DrawRectangle(mySolidColorBrush, myPen, myRect)
End Sub
See Also
Panel
Panels Overview
Custom Radial Panel Sample
How -to Topics
How to: Set the Height Properties of an Element
8/31/2018 • 3 minutes to read • Edit Online
Example
This example visually shows the differences in rendering behavior among the four height-related properties in
Windows Presentation Foundation (WPF ).
The FrameworkElement class exposes four properties that describe the height characteristics of an element. These
four properties can conflict, and when they do, the value that takes precedence is determined as follows: the
MinHeight value takes precedence over the MaxHeight value, which in turn takes precedence over the Height
value. A fourth property, ActualHeight, is read-only, and reports the actual height as determined by interactions
with the layout process.
The following Extensible Application Markup Language (XAML ) examples draw a Rectangle element ( rect1 ) as a
child of Canvas. You can change the height properties of a Rectangle by using a series of ListBox elements that
represent the property values of MinHeight, MaxHeight, and Height. In this manner, the precedence of each
property is visually displayed.
The following code-behind examples handle the events that the SelectionChanged event raises. Each handler takes
the input from the ListBox, parses the value as a Double, and applies the value to the specified height-related
property. The height values are also converted to a string and written to various TextBlock elements (definition of
those elements is not shown in the selected XAML ).
private void changeHeight(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.Height = sz1;
rect1.UpdateLayout();
txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
txt2.Text= "Height is set to " + rect1.Height;
txt3.Text= "MinHeight is set to " + rect1.MinHeight;
txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}
private void changeMinHeight(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.MinHeight = sz1;
rect1.UpdateLayout();
txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
txt2.Text= "Height is set to " + rect1.Height;
txt3.Text= "MinHeight is set to " + rect1.MinHeight;
txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}
private void changeMaxHeight(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.MaxHeight = sz1;
rect1.UpdateLayout();
txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
txt2.Text= "Height is set to " + rect1.Height;
txt3.Text= "MinHeight is set to " + rect1.MinHeight;
txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}
Private Sub changeHeight(ByVal sender As Object, ByVal args As SelectionChangedEventArgs)
Dim li As ListBoxItem = CType(CType(sender, ListBox).SelectedItem, ListBoxItem)
Dim sz1 As Double = Double.Parse(li.Content.ToString())
rect1.Height = sz1
rect1.UpdateLayout()
txt1.Text = "ActualHeight is set to " + rect1.ActualHeight.ToString
txt2.Text = "Height is set to " + rect1.Height.ToString
txt3.Text = "MinHeight is set to " + rect1.MinHeight.ToString
txt4.Text = "MaxHeight is set to " + rect1.MaxHeight.ToString
End Sub
Private Sub changeMinHeight(ByVal sender As Object, ByVal args As SelectionChangedEventArgs)
See Also
FrameworkElement
ListBox
ActualHeight
MaxHeight
MinHeight
Height
Set the Width Properties of an Element
Panels Overview
Height Properties Sample
How to: Set the Width Properties of an Element
8/31/2018 • 3 minutes to read • Edit Online
Example
This example visually shows the differences in rendering behavior among the four width-related properties in
Windows Presentation Foundation (WPF ).
The FrameworkElement class exposes four properties that describe the width characteristics of an element. These
four properties can conflict, and when they do, the value that takes precedence is determined as follows: the
MinWidth value takes precedence over the MaxWidth value, which in turn takes precedence over the Width value.
A fourth property, ActualWidth, is read-only, and reports the actual width as determined by interactions with the
layout process.
The following Extensible Application Markup Language (XAML ) examples draw a Rectangle element ( rect1 ) as a
child of Canvas. You can change the width properties of a Rectangle by using a series of ListBox elements that
represent the property values of MinWidth, MaxWidth, and Width. In this manner, the precedence of each
property is visually displayed.
The following code-behind examples handle the events that the SelectionChanged event raises. Each custom
method takes the input from the ListBox, parses the value as a Double, and applies the value to the specified
width-related property. The width values are also converted to a string and written to various TextBlock elements
(definition of those elements is not shown in the selected XAML ).
private void changeWidth(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.Width = sz1;
rect1.UpdateLayout();
txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
txt2.Text = "Width is set to " + rect1.Width;
txt3.Text = "MinWidth is set to " + rect1.MinWidth;
txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}
private void changeMinWidth(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.MinWidth = sz1;
rect1.UpdateLayout();
txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
txt2.Text = "Width is set to " + rect1.Width;
txt3.Text = "MinWidth is set to " + rect1.MinWidth;
txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}
private void changeMaxWidth(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
Double sz1 = Double.Parse(li.Content.ToString());
rect1.MaxWidth = sz1;
rect1.UpdateLayout();
txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
txt2.Text = "Width is set to " + rect1.Width;
txt3.Text = "MinWidth is set to " + rect1.MinWidth;
txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}
Private Sub changeWidth(ByVal sender As Object, ByVal args As SelectionChangedEventArgs)
Dim li As ListBoxItem = CType(CType(sender, ListBox).SelectedItem, ListBoxItem)
Dim sz1 As Double = Double.Parse(li.Content.ToString())
rect1.Width = sz1
rect1.UpdateLayout()
txt1.Text = "ActualWidth is set to " + rect1.ActualWidth.ToString
txt2.Text = "Width is set to " + rect1.Width.ToString
txt3.Text = "MinWidth is set to " + rect1.MinWidth.ToString
txt4.Text = "MaxWidth is set to " + rect1.MaxWidth.ToString
End Sub
Private Sub changeMinWidth(ByVal sender As Object, ByVal args As SelectionChangedEventArgs)
See Also
ListBox
FrameworkElement
ActualWidth
MaxWidth
MinWidth
Width
Panels Overview
Set the Height Properties of an Element
Width Properties Comparison Sample
PasswordBox
5/4/2018 • 2 minutes to read • Edit Online
See Also
TextBox
RichTextBox
Control Library
Popup
5/4/2018 • 2 minutes to read • Edit Online
The Popup control displays content in a separate window that floats over the current application window.
The following illustration shows a Popup control that is positioned with respect to a Button that is its parent.
In This Section
Popup Overview
Popup Placement Behavior
How -to Topics
Reference
Popup
Related Sections
Popup Overview
5/4/2018 • 4 minutes to read • Edit Online
The Popup control provides a way to display content in a separate window that floats over the current application
window relative to a designated element or screen coordinate. This topic introduces the Popup control and
provides information about its use.
What Is a Popup?
A Popup control displays content in a separate window relative to an element or point on the screen. When the
Popup is visible, the IsOpen property is set to true .
NOTE
A Popup does not automatically open when the mouse pointer moves over its parent object. If you want a Popup to
automatically open, use the ToolTip or ToolTipService class. For more information, see ToolTip Overview.
Creating a Popup
The following example shows how to define a Popup control that is the child element of a Button control. Because
a Button can have only one child element, this example places the text for the Button and the Popup controls in a
StackPanel. The content of the Popup appears in a TextBlock control, which displays its text in a separate window
that floats over the application window near the related Button control.
You can also apply animations like Storyboard to the Popup control.
Opacity and Bitmap Effects
The Opacity property for a Popup control has no effect on its content. By default, the Popup content window is
opaque. To create a transparent Popup, set the AllowsTransparency property to true .
The content of a Popup does not inherit bitmap effects, such as DropShadowBitmapEffect, that you directly set on
the Popup control or on any other element in the parent window. For bitmap effects to appear on the content of a
Popup, you must set the bitmap effect directly on its content. For example, if the child of a Popup is a StackPanel,
set the bitmap effect on the StackPanel.
Popup Size
By default, a Popup is automatically sized to its content. When auto-sizing occurs, some bitmap effects may be
hidden because the default size of the screen area that is defined for the Popup content does not provide enough
space for the bitmap effects to display.
Popup content can also be obscured when you set a RenderTransform on the content. In this scenario, some
content might be hidden if the content of the transformed Popup extends beyond the area of the original Popup. If
a bitmap effect or transform requires more space, you can define a margin around the Popup content in order to
provide more area for the control.
See Also
Popup
PopupPrimaryAxis
PlacementMode
CustomPopupPlacement
CustomPopupPlacementCallback
ToolTip
ToolTipService
How -to Topics
How -to Topics
Popup Placement Behavior
8/31/2018 • 12 minutes to read • Edit Online
A Popup control displays content in a separate window that floats over an application. You can specify the position
of a Popup relative to a control, the mouse, or the screen by using the PlacementTarget, Placement,
PlacementRectangle, HorizontalOffset, and VerticalOffset properties. These properties work together to give you
flexibility in specifying the position of the Popup.
NOTE
The ToolTip and ContextMenu classes also define these five properties and behave similarly.
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Top">
<TextBlock FontSize="14" Background="LightGreen">Placement=Top</TextBlock>
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Left">
<TextBlock FontSize="14" Background="LightGreen">Placement=Left</TextBlock>
</Popup>
<Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
Placement="Right">
<TextBlock FontSize="14" Background="LightGreen">Placement=Right</TextBlock>
</Popup>
</Canvas>
The following illustration shows the image and the Popup controls
Image with four Popups
This simple example demonstrates how to set the PlacementTarget and Placement properties, but by using the
PlacementRectangle, HorizontalOffset, and VerticalOffset properties, you have even more control over where the
Popup is positioned.
The following illustration shows that the Popup is positioned relative to the Canvas.
<Ellipse Name="ellipse1"
Canvas.Top="60" Canvas.Left="50"
Height="85" Width="60"
Fill="Black"/>
The following illustration shows that the Popup is positioned relative to the Ellipse.
NOTE
For ToolTip, the default value of Placement is Mouse. For ContextMenu, the default value of Placement is MousePoint. These
values are explained later, in "How the Properties Work Together."
Target Area
The target area is the area on the screen that the Popup is relative to. In the previous examples, the Popup is
aligned with the bounds of the target object, but in some cases, the Popup is aligned to other bounds, even if the
Popup has a target object. If the PlacementRectangle property is set, the target area is different than the bounds of
the target object.
The following example creates two Canvas objects, each one containing a Rectangle and a Popup. In both cases,
the target object for the Popup is the Canvas. The Popup in the first Canvas has the PlacementRectangle set, with
its X, Y, Width, and Height properties set to 50, 50, 50, and 100, respectively. The Popup in the second Canvas
does not have the PlacementRectangle set. As a result, the first Popup is positioned below the PlacementRectangle
and the second Popup is positioned below the Canvas. Each Canvas also contains a Rectangle that has the same
bounds as the PlacementRectangle for the first Popup. Note that the PlacementRectangle does not create a visible
element in the application; the example creates a Rectangle to represent the PlacementRectangle.
<StackPanel Orientation="Horizontal" Margin="50,50,0,0">
</StackPanel>
POPUP ALIGNMENT
PLACEMENTMODE TARGET OBJECT TARGET AREA TARGET ORIGIN POINT
Absolute Not applicable. The screen, or The top-left corner of The top-left corner of
PlacementTarget is PlacementRectangle if the target area. the Popup.
ignored. it is set. The
PlacementRectangle is
relative to the screen.
AbsolutePoint Not applicable. The screen, or The top-left corner of The top-left corner of
PlacementTarget is PlacementRectangle if the target area. the Popup.
ignored. it is set. The
PlacementRectangle is
relative to the screen.
Bottom PlacementTarget or The target object, or The bottom-left The top-left corner of
parent. PlacementRectangle if corner of the target the Popup.
it is set. The area.
PlacementRectangle is
relative to the target
object.
Center PlacementTarget or The target object, or The center of the The center of the
parent. PlacementRectangle if target area. Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
POPUP ALIGNMENT
PLACEMENTMODE TARGET OBJECT TARGET AREA TARGET ORIGIN POINT
Left PlacementTarget or The target object, or The top-left corner of The top-right corner
parent. PlacementRectangle if the target area. of the Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
Mouse Not applicable. The bounds of the The bottom-left The top-left corner of
PlacementTarget is mouse pointer. corner of the target the Popup.
ignored. PlacementRectangle is area.
ignored.
MousePoint Not applicable. The bounds of the The top-left corner of The top-left corner of
PlacementTarget is mouse pointer. the target area. the Popup.
ignored. PlacementRectangle is
ignored.
Relative PlacementTarget or The target object, or The top-left corner of The top-left corner of
parent. PlacementRectangle if the target area. the Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
RelativePoint PlacementTarget or The target object, or The top-left corner of The top-left corner of
parent. PlacementRectangle if the target area. the Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
Right PlacementTarget or The target object, or The top-right corner The top-left corner of
parent. PlacementRectangle if of the target area. the Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
Top PlacementTarget or The target object, or The top-left corner of The bottom-left
parent. PlacementRectangle if the target area. corner of the Popup.
it is set. The
PlacementRectangle is
relative to the target
object.
The following illustrations show the Popup, target area, target origin, and popup alignment point for each
PlacementMode value. In each figure, the target area is yellow, and the Popup is blue.
Placement is Absolute or AbsolutePoint
Placement is Bottom
Placement is Center
Placement is Left
Placement is Mouse
Placement is MousePoint
Placement is Relative or RelativePoint
Placement is Right
Placement is Top
Absolute Aligns to the top Aligns to the bottom Aligns to the left Aligns to the right
edge. edge. edge. edge.
AbsolutePoint Aligns to the top The popup alignment Aligns to the left The popup alignment
edge. point changes to the edge. point changes to the
bottom-left corner of top-right corner of
the Popup. the Popup.
Bottom Aligns to the top The target origin Aligns to the left Aligns to the right
edge. changes to the top- edge. edge.
left corner of the
target area and the
popup alignment
point changes to the
bottom-left corner of
the Popup.
Center Aligns to the top Aligns to the bottom Aligns to the left Aligns to the right
edge. edge. edge. edge.
PLACEMENTMODE TOP EDGE BOTTOM EDGE LEFT EDGE RIGHT EDGE
Left Aligns to the top Aligns to the bottom The target origin Aligns to the right
edge. edge. changes to the top- edge.
right corner of the
target area and the
popup alignment
point changes to the
top-left corner of the
Popup.
Mouse Aligns to the top The target origin Aligns to the left Aligns to the right
edge. changes to the top- edge. edge.
left corner of the
target area (the
bounds of the mouse
pointer) and the
popup alignment
point changes to the
bottom-left corner of
the Popup.
MousePoint Aligns to the top The popup alignment Aligns to the left The popup alignment
edge. point changes to the edge. point changes to the
bottom-left corner of top-right corner of
the Popup. the popup.
Relative Aligns to the top Aligns to the bottom Aligns to the left Aligns to the right
edge. edge. edge. edge.
RelativePoint Aligns to the top The popup alignment Aligns to the left The popup alignment
edge. point changes to the edge. point changes to the
bottom-left corner of top-right corner of
the Popup. the popup.
Right Aligns to the top Aligns to the bottom Aligns to the left The target origin
edge. edge. edge. changes to the top-
left corner of the
target area and the
popup alignment
point changes to the
top-right corner of
the Popup.
Top The target origin Aligns to the bottom Aligns to the left Aligns to the right
changes to the edge. edge. edge.
bottom-left corner of
the target area and
the popup alignment
point changes to the
top-left corner of the
Popup. In effect, this
is the same as when
Placement is Bottom.
Popup encounters bottom edge of the screen and changes the popup alignment point
The following illustration demonstrates that when the Popup is hidden by the right screen edge, the popup
alignment point is the top-right corner of the Popup.
Popup encounters right edge of the screen and changes the popup alignment point
If the Popup encounters the bottom and right screen edges, the popup alignment point is the bottom-right corner
of the Popup.
Changing the Target Origin and Popup Alignment Point
When Placement is Bottom, Left, Mouse, Right, or Top, the target origin and popup alignment point change if a
certain screen edge is encountered. The screen edge that causes the position to change depends on the
PlacementMode value.
The following illustration demonstrates that when Placement is Bottom and the Popup encounters the bottom
screen edge, the target origin is the top-left corner of the target area and the popup alignment point is the bottom-
left corner of the Popup.
Placement is Bottom and the popup encounters the bottom edge of the screen
The following illustration demonstrates that when Placement is Left and the Popup encounters the left screen
edge, the target origin is the top-right corner of the target area and the popup alignment point is the top-left
corner of the Popup.
Placement is Left and the popup encounters the left edge of the screen
The following illustration demonstrates that when Placement is Right and the Popup encounters the right screen
edge, the target origin is the top-left corner of the target area and the popup alignment point is the top-right
corner of the Popup.
Placement is Right and the popup encounters the right edge of the screen
The following illustration demonstrates that when Placement is Top and the Popup encounters the top screen
edge, the target origin is the bottom-left corner of the target area and the popup alignment point is the top-left
corner of the Popup.
Placement is Top and the popup encounters the top edge of the screen
The following illustration demonstrates that when Placement is Mouse and the Popup encounters the bottom
screen edge, the target origin is the top-left corner of the target area (the bounds of the mouse pointer) and the
popup alignment point is the bottom-left corner of the Popup.
Placement is Mouse and the popup encounters the bottom edge of the screen
Customizing Popup Placement
You can customize the target origin and popup alignment point by setting the Placement property to Custom.
Then define a CustomPopupPlacementCallback delegate that returns a set of possible placement points and
primary axes (in order of preference) for the Popup. The point that shows the largest portion of the Popup is
selected. The position of the Popup is automatically adjusted if the Popup is hidden by the edge of the screen. For
an example, see Specify a Custom Popup Position.
See Also
Popup Placement Sample
Popup How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the Popup control to display content in a separate window that
floats over the current application window.
In This Section
Animate a Popup
Specify a Custom Popup Position
Reference
Popup
Related Sections
Popup Overview
How to: Animate a Popup
5/4/2018 • 2 minutes to read • Edit Online
Example
The following example sets the PopupAnimation property to a value of Slide, which causes the Popup to "slide-in"
when it appears.
In order to rotate the Popup, this example assigns a RotateTransform to the RenderTransform property on the
Canvas, which is the child element of the Popup.
For the transform to work correctly, the example must set the AllowsTransparency property to true . In addition,
the Margin on the Canvas content must specify enough space for the Popup to rotate.
The following example shows how a Click event, which occurs when a Button is clicked, triggers the Storyboard
that starts the animation.
This example shows how to specify a custom position for a Popup control when the Placement property is set to
Custom.
Example
When the Placement property is set to Custom, the Popup calls a defined instance of the
CustomPopupPlacementCallback delegate. This delegate returns a set of possible points that are relative to the
top left corner of the target area and the top left corner of the Popup. The Popup placement occurs at the point
that provides the best visibility.
The following example shows how to define the position of a Popup by setting the Placement property to Custom.
It also shows how to create and assign a CustomPopupPlacementCallback delegate in order to position the
Popup. The callback delegate returns two CustomPopupPlacement objects. If the Popup is hidden by a screen
edge at the first position, the Popup is placed at the second position.
<Popup Name="popup1"
PlacementTarget ="{Binding ElementName=myButton}"
Placement="Custom">
<TextBlock Height="60" Width="200"
Background="LightGray"
TextWrapping="Wrap">Popup positioned by using
CustomPopupPlacement callback delegate</TextBlock>
</Popup>
CustomPopupPlacement placement2 =
new CustomPopupPlacement(new Point(10, 20), PopupPrimaryAxis.Horizontal);
CustomPopupPlacement[] ttplaces =
new CustomPopupPlacement[] { placement1, placement2 };
return ttplaces;
}
Public Function placePopup(ByVal popupSize As Size, ByVal targetSize As Size, ByVal offset As Point) As
CustomPopupPlacement()
Dim placement1 As New CustomPopupPlacement(New Point(-50, 100), PopupPrimaryAxis.Vertical)
See Also
Popup
Popup Overview
How -to Topics
ProgressBar
5/4/2018 • 2 minutes to read • Edit Online
A ProgressBar indicates the progress of an operation. The ProgressBar control consists of a window that is filled
with the system highlight color as an operation progresses.
The following illustration shows a typical ProgressBar.
In This Section
Reference
ProgressBar
StatusBar
Related Sections
PrintDialog
5/4/2018 • 2 minutes to read • Edit Online
The PrintDialog control is used to instantiate a standard print dialog box that automatically configures a PrintTicket
and PrintQueue according to user input.
Reference
PrintDialog
PrintTicket
PrintQueue
See Also
Printing Overview
Documents in WPF
RadioButton
5/4/2018 • 2 minutes to read • Edit Online
RadioButton controls are usually grouped together to offer users a single choice among several options; only one
button at a time can be selected.
The following illustration shows an example of a RadioButton control.
Typical RadioButton
Reference
ToggleButton
Related Sections
RepeatButton
5/4/2018 • 2 minutes to read • Edit Online
The RepeatButton is similar to a Button. However, RepeatButton elements give you control over when and how the
Click event occurs.
The following graphic shows an example of the three states of a repeat button control, Default, PointerFocused,
and Pressed. The first button shows the default state of the RepeatButton. The second shows how the appearance
of the button changes when the mouse pointer hovers over the button, giving it focus. The last button shows the
appearance of the RepeatButton when the user presses the mouse button over the control.
Typical RepeatButton
In This Section
Reference
RepeatButton
Related Sections
RichTextBox
5/4/2018 • 2 minutes to read • Edit Online
The RichTextBox element defines an editing control with built-in support for features such as cut and paste, rich
document presentation, and content selection.
In This Section
RichTextBox Overview
How -to Topics
See Also
TextBox
Documents in WPF
Flow Document Overview
RichTextBox Overview
5/4/2018 • 8 minutes to read • Edit Online
The RichTextBox control enables you to display or edit flow content including paragraphs, images, tables, and
more. This topic introduces the TextBox class and provides examples of how to use it in both Extensible
Application Markup Language (XAML ) and C#.
TextBox or RichTextBox?
Both RichTextBox and TextBox allow users to edit text, however, the two controls are used in different scenarios.
A RichTextBox is a better choice when it is necessary for the user to edit formatted text, images, tables, or other
rich content. For example, editing a document, article, or blog that requires formatting, images, etc is best
accomplished using a RichTextBox. A TextBox requires less system resources then a RichTextBox and it is ideal
when only plain text needs to be edited (i.e. usage in forms). See TextBox Overview for more information on
TextBox. The table below summarizes the main features of TextBox and RichTextBox.
FLOWDOCUMENT
FORMATTING CONTENT LIKE IMAGES,
REAL-TIME COMMANDS LIKE PARAGRAPHS, TABLES,
CONTROL SPELLCHECKING CONTEX T MENU TOGGLEBOLD (CTR+B) ETC.
Note: Although TextBox does not support formatting related commands like ToggleBold (Ctr+B ), many basic
commands are supported by both controls such as MoveToLineEnd.
The features from the table above are covered in more detail later.
Creating a RichTextBox
The code below shows how to create a RichTextBox that a user can edit rich content in.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Page>
Specifically, the content edited in a RichTextBox is flow content. Flow content can contain many types of
elements including formatted text, images, lists, and tables. See Flow Document Overview for in depth
information on flow documents. In order to contain flow content, a RichTextBox hosts a FlowDocument object
which in turn contains the editable content. To demonstrate flow content in a RichTextBox, the following code
shows how to create a RichTextBox with a paragraph and some bolded text.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<RichTextBox>
<FlowDocument>
<Paragraph>
This is flow content and you can <Bold>edit me!</Bold>
</Paragraph>
</FlowDocument>
</RichTextBox>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
namespace SDKSample
{
public partial class BasicRichTextBoxWithContentExample : Page
{
public BasicRichTextBoxWithContentExample()
{
StackPanel myStackPanel = new StackPanel();
myStackPanel.Children.Add(myRichTextBox);
this.Content = myStackPanel;
}
}
}
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class BasicRichTextBoxWithContentExample
Inherits Page
Public Sub New()
Dim myStackPanel As New StackPanel()
' Create a paragraph and add the Run and Bold to it.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(myRun)
myParagraph.Inlines.Add(myBold)
myStackPanel.Children.Add(myRichTextBox)
Me.Content = myStackPanel
End Sub
End Class
End Namespace
Elements like Paragraph and Bold determine how the content inside a RichTextBox appears. As a user edits
RichTextBox content, they change this flow content. To learn more about the features of flow content and how to
work with it, see Flow Document Overview.
Note: Flow content inside a RichTextBox does not behave exactly like flow content contained in other controls.
For example, there are no columns in a RichTextBox and hence no automatic resizing behavior. Also, built in
features like search, viewing mode, page navigation, and zoom are not available within a RichTextBox.
See Enable Spell Checking in a Text Editing Control to learn how to enable spellchecking.
Context Menu
By default, both TextBox and RichTextBox have a context menu that appears when a user right-clicks inside the
control. The context menu allows the user to cut, copy, or paste (see illustration below ).
You can create your own custom context menu to override the default one. See Position a Custom Context
Menu in a RichTextBox for more information.
Editing Commands
Editing commands enable users to format editable content inside a RichTextBox. Besides basic editing
commands, RichTextBox includes formatting commands that TextBox does not support. For example, when
editing in a RichTextBox, a user could press Ctr+B to toggle bold text formatting. See EditingCommands for a
complete list of commands available. In addition to using keyboard shortcuts, you can hook commands up to
other controls like buttons. The following example shows how to create a simple tool bar containing buttons
that the user can use to change text formatting.
<Window x:Class="RichTextBoxInputPanelDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="600"
>
<Grid>
<DockPanel Name="mainPanel">
<!-- This tool bar contains all the editing buttons. -->
<ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">
</ToolBar>
<!-- By default pressing tab moves focus to the next control. Setting AcceptsTab to true allows the
RichTextBox to accept tab characters. -->
<RichTextBox Name="mainRTB" AcceptsTab="True"></RichTextBox>
</DockPanel>
</Grid>
</Window>
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.SaveLoadPrintRTB" >
<StackPanel>
<RichTextBox Name="richTB">
<FlowDocument>
<Paragraph>
<Run>Paragraph 1</Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
</Page>
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace SDKSample
{
Imports System
Imports System.IO
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Documents
Imports System.Windows.Media
Namespace SDKSample
See Also
How -to Topics
TextBox Overview
RichTextBox How-to Topics
8/31/2018 • 2 minutes to read • Edit Online
This section provides examples that demonstrate how to accomplish common tasks using the RichTextBox control.
In This Section
Extract the Text Content from a RichTextBox
Change Selection in a RichTextBox Programmatically
Save, Load, and Print RichTextBox Content
Position a Custom Context Menu in a RichTextBox
How to: Replace the Default Content Host for a RichTextBox
See Also
TextBox
Documents in WPF
Flow Document Overview
How to: Extract the Text Content from a RichTextBox
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to extract the contents of a RichTextBox as plain text.
Example
The following Extensible Application Markup Language (XAML ) code describes a named RichTextBox control with
simple content.
<RichTextBox Name="richTB">
<FlowDocument>
<Paragraph>
<Run>Paragraph 1</Run>
</Paragraph>
<Paragraph>
<Run>Paragraph 2</Run>
</Paragraph>
<Paragraph>
<Run>Paragraph 3</Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
Example
The following code implements a method that takes a RichTextBox as an argument, and returns a string
representing the plain text contents of the RichTextBox.
The method creates a new TextRange from the contents of the RichTextBox, using the ContentStart and
ContentEnd to indicate the range of the contents to extract. ContentStart and ContentEnd properties each return a
TextPointer, and are accessible on the underlying FlowDocument that represents the contents of the RichTextBox.
TextRange provides a Text property, which returns the plain text portions of the TextRange as a string.
See Also
RichTextBox Overview
TextBox Overview
Change Selection in a RichTextBox Programmatically
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to programmatically change the current selection in a RichTextBox. This selection is the
same as if the user had selected the content by using the user interface.
Example
The following Extensible Application Markup Language (XAML ) code describes a named RichTextBox control with
simple content.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.ChangeSelectionProgrammaticaly" >
<StackPanel>
<RichTextBox GotMouseCapture="ChangeSelection" Name="richTB">
<FlowDocument>
<Paragraph Name="myParagraph">
<Run>
When the user clicks in the RichTextBox, the selected
text changes programmatically.
</Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
</StackPanel>
</Page>
Example
The following code programmatically selects some arbitrary text when the user clicks inside the RichTextBox.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ChangeSelectionProgrammaticaly : Page
{
Namespace SDKSample
Partial Public Class ChangeSelectionProgrammaticaly
Inherits Page
See Also
RichTextBox Overview
TextBox Overview
How to: Save, Load, and Print RichTextBox Content
5/4/2018 • 2 minutes to read • Edit Online
The following example shows how to save content of a RichTextBox to a file, load that content back into the
RichTextBox, and print the contents.
Example
Below is the markup for the example.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.SaveLoadPrintRTB" >
<StackPanel>
<RichTextBox Name="richTB">
<FlowDocument>
<Paragraph>
<Run>Paragraph 1</Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
</Page>
Example
Below is the code behind for the example.
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace SDKSample
{
Imports System
Imports System.IO
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Media
Namespace SDKSample
See Also
RichTextBox Overview
TextBox Overview
How to: Position a Custom Context Menu in a
RichTextBox
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to position a custom context menu for a RichTextBox.
When you implement a custom context menu for a RichTextBox, you are responsible for handling the placement
of the context menu. By default, a custom context menu is opened at the center of the RichTextBox.
Example
To override the default placement behavior, add a listener for the ContextMenuOpening event. The following
example shows how to do this programmatically.
Example
The following example shows an implementation the corresponding ContextMenuOpening event listener.
// This method is intended to listen for the ContextMenuOpening event from a RichTextBox.
// It will position the custom context menu at the end of the current selection.
void richTextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
// Sender must be RichTextBox.
RichTextBox rtb = sender as RichTextBox;
if (rtb == null) return;
// Compute horizontal and vertical offsets to place the menu relative to selection end.
TextPointer position = rtb.Selection.End;
' This uses HorizontalOffset and VerticalOffset properties to position the menu,
' relative to the upper left corner of the parent element (RichTextBox in this case).
contextMenu.Placement = PlacementMode.RelativePoint
' Compute horizontal and vertical offsets to place the menu relative to selection end.
Dim position As TextPointer = rtb.Selection.End
See Also
RichTextBox Overview
TextBox Overview
ScrollBar
5/4/2018 • 2 minutes to read • Edit Online
A ScrollBar allows you to view content that is outside of the current viewing area by sliding the Thumb to make the
content visible.
In This Section
Customize the Thumb Size on a ScrollBar
Reference
ScrollBar
Track
Thumb
ScrollViewer
How to: Customize the Thumb Size on a ScrollBar
5/4/2018 • 2 minutes to read • Edit Online
This topic explains how to set the Thumb of a ScrollBar to a fixed size and how to specify a minimum size for the
Thumb of a ScrollBar.
Example
Description
The following example creates a ScrollBar that has a Thumb with a fixed size. The example sets the ViewportSize
property of the Thumb to NaN and sets the height of the Thumb. To create a horizontal ScrollBar with a Thumb
that has a fixed width, set the width of the Thumb.
Code
<Style TargetType="ScrollBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Name="Bg"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="{DynamicResource
{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition MaxHeight="{DynamicResource
{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
</Grid.RowDefinitions>
<RepeatButton Style="{StaticResource ScrollBarButton}"
IsEnabled="{TemplateBinding IsMouseOver}"
Height="18"
Command="ScrollBar.LineUpCommand"
Content="M 0 4 L 8 4 L 4 0 Z" />
<!-- Set the ViewporSize to NaN to disable autosizing of the Thumb. -->
<Track Name="PART_Track"
ViewportSize="NaN"
IsDirectionReversed="true"
Grid.Row="1"
Grid.ZIndex="-1">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
Command="ScrollBar.PageUpCommand"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
Command="ScrollBar.PageDownCommand"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<!-- Set the height of the Thumb.-->
<Thumb Height="30"/>
</Track.Thumb>
</Track>
<RepeatButton
Grid.Row="2"
Style="{StaticResource ScrollBarButton}"
Height="18"
Command="ScrollBar.LineDownCommand"
Content="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="PART_Track" Property="IsEnabled" Value="false">
<Setter TargetName="PART_Track" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Description
The following example creates a ScrollBar that has a Thumb with a minimum size. The example sets the value of
VerticalScrollBarButtonHeightKey. To create a horizontal ScrollBar with a Thumb that has a minimum width, set
the HorizontalScrollBarButtonWidthKey.
Code
<Style TargetType="ScrollBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Name="Bg"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="{DynamicResource
{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition MaxHeight="{DynamicResource
{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
</Grid.RowDefinitions>
<RepeatButton Style="{StaticResource ScrollBarButton}"
IsEnabled="{TemplateBinding IsMouseOver}"
Height="18"
Command="ScrollBar.LineUpCommand"
Content="M 0 4 L 8 4 L 4 0 Z" />
<Track Name="PART_Track"
IsDirectionReversed="true"
Grid.Row="1"
Grid.ZIndex="-1">
<Track.Resources>
<!-- Set the Thumb's minimum height to 50.
The Thumb's minimum height is half the
value of VerticalScrollBarButtonHeightKey. -->
<sys:Double
x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">
100
</sys:Double>
</Track.Resources>
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
Command="ScrollBar.PageUpCommand"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
Command="ScrollBar.PageDownCommand"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb/>
</Track.Thumb>
</Track>
<RepeatButton
Grid.Row="2"
Style="{StaticResource ScrollBarButton}"
Height="18"
Command="ScrollBar.LineDownCommand"
Content="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="PART_Track"
Property="IsEnabled" Value="false">
<Setter TargetName="PART_Track"
Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
See Also
ScrollBar Styles and Templates
ScrollViewer
5/4/2018 • 2 minutes to read • Edit Online
The ScrollViewer control creates a scrollable region wherein content can be scrolled horizontally or vertically.
In This Section
ScrollViewer Overview
How -to Topics
Reference
ScrollBar
ScrollViewer
See Also
Panels Overview
Layout
ScrollViewer Overview
8/31/2018 • 4 minutes to read • Edit Online
Content within a user interface is often larger than a computer screen's display area. The ScrollViewer control
provides a convenient way to enable scrolling of content in Windows Presentation Foundation (WPF )
applications. This topic introduces the ScrollViewer element and provides several usage examples.
CType(sp1, IScrollInfo).LineUp()
End Sub
Private Sub spLineDown(ByVal sender As Object, ByVal args As RoutedEventArgs)
CType(sp1, IScrollInfo).LineDown()
End Sub
// Define a ScrollViewer
myScrollViewer = gcnew ScrollViewer();
myScrollViewer->HorizontalScrollBarVisibility = ScrollBarVisibility::Auto;
// Define a ScrollViewer
myScrollViewer = new ScrollViewer();
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
'Define a ScrollViewer.
Dim myScrollViewer As New ScrollViewer
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
Styling a ScrollViewer
Like all controls in Windows Presentation Foundation, the ScrollViewer can be styled in order to change the
default rendering behavior of the control. For additional information on control styling, see Styling and
Templating.
Paginating Documents
For document content, an alternative to scrolling is to choose a document container that supports pagination.
FlowDocument is for documents that are designed to be hosted within a viewing control, such as
FlowDocumentPageViewer, that supports paginating content across multiple pages, preventing the need for
scrolling. DocumentViewer provides a solution for viewing FixedDocument content, which uses traditional
scrolling to display content outside the realm of the display area.
For additional information about document formats and presentation options, see Documents in WPF.
See Also
ScrollViewer
ScrollBar
IScrollInfo
Create a Scroll Viewer
Documents in WPF
ScrollBar Styles and Templates
Controls
ScrollViewer How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section demonstrate how to use the ScrollViewer element to create scrollable regions in your
applications.
In This Section
Handle the ScrollChanged Event
Scroll Content by Using the IScrollInfo Interface
Use the Content-Scrolling Methods of ScrollViewer
Reference
ScrollBar
ScrollViewer
See Also
Panels Overview
Layout
How to: Handle the ScrollChanged Event
5/4/2018 • 2 minutes to read • Edit Online
Example
This example shows how to handle the ScrollChanged event of a ScrollViewer.
A FlowDocument element with Paragraph parts is defined in XAML. When the ScrollChanged event occurs due to
user interaction, a handler is invoked, and text is written to a TextBlock indicating that the event has occurred.
<Paragraph>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation
ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation
ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation
ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
</FlowDocument>
</ScrollViewer>
private void sChanged(object sender, ScrollChangedEventArgs e)
{
if (sv1.CanContentScroll == true)
{
tBlock1.Foreground = System.Windows.Media.Brushes.Red;
tBlock1.Text = "ScrollChangedEvent just Occurred";
tBlock2.Text = "ExtentHeight is now " + e.ExtentHeight.ToString();
tBlock3.Text = "ExtentWidth is now " + e.ExtentWidth.ToString();
tBlock4.Text = "ExtentHeightChange was " + e.ExtentHeightChange.ToString();
tBlock5.Text = "ExtentWidthChange was " + e.ExtentWidthChange.ToString();
tBlock6.Text = "HorizontalOffset is now " + e.HorizontalOffset.ToString();
tBlock7.Text = "VerticalOffset is now " + e.VerticalOffset.ToString();
tBlock8.Text = "HorizontalChange was " + e.HorizontalChange.ToString();
tBlock9.Text = "VerticalChange was " + e.VerticalChange.ToString();
tBlock10.Text = "ViewportHeight is now " + e.ViewportHeight.ToString();
tBlock11.Text = "ViewportWidth is now " + e.ViewportWidth.ToString();
tBlock12.Text = "ViewportHeightChange was " + e.ViewportHeightChange.ToString();
tBlock13.Text = "ViewportWidthChange was " + e.ViewportWidthChange.ToString();
}
else
{
tBlock1.Text = "";
}
Else
tBlock1.Text = ""
End If
See Also
ScrollViewer
ScrollChanged
ScrollChangedEventHandler
ScrollChangedEventArgs
How to: Scroll Content by Using the IScrollInfo
Interface
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to scroll content by using the IScrollInfo interface.
Example
The following example demonstrates the features of the IScrollInfo interface. The example creates a StackPanel
element in Extensible Application Markup Language (XAML ) that is nested in a parent ScrollViewer. The child
elements of the StackPanel can be scrolled logically by using the methods defined by the IScrollInfo interface and
cast to the instance of StackPanel ( sp1 ) in code.
Each Button in the XAML file triggers an associated custom method that controls scrolling behavior in StackPanel.
The following example shows how to use the LineUp and LineDown methods; it also generically shows how to use
all the positioning methods that the IScrollInfo class defines.
CType(sp1, IScrollInfo).LineUp()
End Sub
Private Sub spLineDown(ByVal sender As Object, ByVal args As RoutedEventArgs)
CType(sp1, IScrollInfo).LineDown()
End Sub
See Also
ScrollViewer
IScrollInfo
StackPanel
ScrollViewer Overview
How -to Topics
Panels Overview
How to: Use the Content-Scrolling Methods of
ScrollViewer
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the scrolling methods of the ScrollViewer element. These methods provide
incremental scrolling of content, either by line or by page, in a ScrollViewer.
Example
The following example creates a ScrollViewer named sv1 , which hosts a child TextBlock element. Because the
TextBlock is larger than the parent ScrollViewer, scroll bars appear in order to enable scrolling. Button elements
that represent the various scrolling methods are docked on the left in a separate StackPanel. Each Button in the
XAML file calls a related custom method that controls scrolling behavior in ScrollViewer.
sv1.LineUp()
End Sub
Private Sub svLineDown(ByVal sender As Object, ByVal args As RoutedEventArgs)
sv1.LineDown()
End Sub
See Also
ScrollViewer
StackPanel
Separator
5/4/2018 • 2 minutes to read • Edit Online
A Separator control draws a line, horizontal or vertical, between items in controls, such as ListBox, Menu, and
ToolBar.
In This Section
Reference
Separator
Slider
5/4/2018 • 2 minutes to read • Edit Online
The Slider allows you select from a range of values by moving a Thumb along a Track.
The following illustration shows an example of a horizontal Slider control.
In This Section
Customize the Ticks on a Slider
Reference
Slider
Track
Thumb
How to: Customize the Ticks on a Slider
8/31/2018 • 2 minutes to read • Edit Online
This example shows how to create a Slider control that has tick marks.
Example
The TickBar displays when you set the TickPlacement property to a value other than None, which is the default
value.
The following example shows how to create a Slider with a TickBar that displays tick marks. The TickPlacement
and TickFrequency properties define the location of the tick marks and the interval between them. When you
move the Thumb, tooltips display the value of the Slider. The AutoToolTipPlacement property defines where the
tooltips occur. The Thumb movements correspond to the location of the tick marks because IsSnapToTickEnabled
is set to true .
The following example shows how to use the Ticks property to create tick marks along the Slider at irregular
intervals.
See Also
Slider
TickBar
TickPlacement
Slider How -to Topics
StackPanel
5/4/2018 • 2 minutes to read • Edit Online
In This Section
How -to Topics
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
StackPanel How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the StackPanel element to stack content horizontally or vertically.
In This Section
Choose Between StackPanel and DockPanel
Create a StackPanel
Horizontally or Vertically Align Content in a StackPanel
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
How to: Choose Between StackPanel and DockPanel
5/4/2018 • 4 minutes to read • Edit Online
This example shows how to choose between using a StackPanel or a DockPanel when you stack content in a Panel.
Example
Although you can use either DockPanel or StackPanel to stack child elements, the two controls do not always
produce the same results. For example, the order that you place child elements can affect the size of child elements
in a DockPanel but not in a StackPanel. This different behavior occurs because StackPanel measures in the
direction of stacking at Double.PositiveInfinity; however, DockPanel measures only the available size.
The following example demonstrates this key difference between DockPanel and StackPanel.
//Define a StackPanel
//Define a StackPanel
myStackPanel = gcnew StackPanel();
myStackPanel->Orientation = Orientation::Horizontal;
Grid::SetRow(myStackPanel, 1);
//Define a StackPanel
myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Horizontal;
Grid.SetRow(myStackPanel, 1);
'Define a StackPanel.
Dim myStackPanel As New StackPanel
myStackPanel.Orientation = Orientation.Horizontal
Grid.SetRow(myStackPanel, 1)
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="StackPanel vs. DockPanel">
<Grid Width="175" Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
See Also
StackPanel
DockPanel
Panels Overview
How to: Create a StackPanel
5/4/2018 • 2 minutes to read • Edit Online
Example
A StackPanel allows you to stack elements in a specified direction. By using properties that are defined on
StackPanel, content can flow both vertically, which is the default setting, or horizontally.
The following example vertically stacks five TextBlock controls, each with a different Border and Background, by
using StackPanel. The child elements that have no specified Width stretch to fill the parent window; however, the
child elements that have a specified Width, are centered within the window.
The default stack direction in a StackPanel is vertical. To control content flow in a StackPanel, use the Orientation
property. You can control horizontal alignment by using the HorizontalAlignment property.
See Also
StackPanel
Panels Overview
How -to Topics
How to: Horizontally or Vertically Align Content in a
StackPanel
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to adjust the Orientation of content within a StackPanel element, and also how to adjust
the HorizontalAlignment and VerticalAlignment of child content.
Example
The following example creates three ListBox elements in Extensible Application Markup Language (XAML ). Each
ListBox represents the possible values of the Orientation, HorizontalAlignment, and VerticalAlignment properties
of a StackPanel. When a user selects a value in any of the ListBox elements, the associated property of the
StackPanel and its child Button elements change.
The following code-behind file defines the changes to the events that are associated with the ListBox selection
changes. StackPanel is identified by the Name sp1 .
private void changeOrientation(object sender, SelectionChangedEventArgs args)
{
ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
if (li.Content.ToString() == "Horizontal")
{
sp1.Orientation = System.Windows.Controls.Orientation.Horizontal;
}
else if (li.Content.ToString() == "Vertical")
{
sp1.Orientation = System.Windows.Controls.Orientation.Vertical;
}
See Also
StackPanel
ListBox
HorizontalAlignment
VerticalAlignment
Panels Overview
StatusBar
5/4/2018 • 2 minutes to read • Edit Online
A StatusBar is a horizontal area at the bottom of a window where an application can display status information.
The following illustration shows an example of a StatusBar.
In This Section
Reference
StatusBar
StatusBarItem
Related Sections
TabControl
5/4/2018 • 2 minutes to read • Edit Online
TabControl elements display content on discrete pages accessed by selecting the appropriate tab. Each tab contains
a TabItem.
The following illustration shows a TabControl.
Typical TabControl
Reference
TabControl
TabItem
Related Sections
TextBlock
5/4/2018 • 2 minutes to read • Edit Online
The TextBlock control provides flexible text support for WPF applications. The element is targeted primarily toward
basic UI scenarios that do not require more than one paragraph of text.
In This Section
TextBlock Overview
Reference
Label
Related Sections
Documents in WPF
Flow Document Overview
TextBlock Overview
5/4/2018 • 2 minutes to read • Edit Online
The TextBlock control provides flexible text support for WPF applications. The element is targeted primarily toward
basic UI scenarios that do not require more than one paragraph of text. It supports a number of properties that
enable precise control of presentation, such as FontFamily, FontSize, FontWeight, TextEffects, and TextWrapping.
Text content can be added using the Text property. When used in XAML, content between the open and closing tag
is implicitly added as the text of the element.
A TextBlock element can be instantiated very simply using XAML.
See Also
Label
TextBox
8/31/2018 • 2 minutes to read • Edit Online
The TextBox control provides support for basic text input in WPF applications.
In This Section
TextBox Overview
How -to Topics
Reference
TextBox
RichTextBox
TextBlock
PasswordBox
See Also
WPF Controls Gallery Sample
TextBox Styles and Templates
TextBox Overview
5/4/2018 • 3 minutes to read • Edit Online
The TextBox class enables you to display or edit unformatted text. A common use of a TextBox is editing
unformatted text in a form. For example, a form asking for the user's name, phone number, etc would use
TextBox controls for text input. This topic introduces the TextBox class and provides examples of how to use it in
both Extensible Application Markup Language (XAML ) and C#.
TextBox or RichTextBox?
Both TextBox and RichTextBox allow users to input text but the two controls are used for different scenarios. A
TextBox requires less system resources then a RichTextBox so it is ideal when only plain text needs to be edited
(i.e., usage in a form). A RichTextBox is a better choice when it is necessary for the user to edit formatted text,
images, tables, or other supported content. For example, editing a document, article, or blog that requires
formatting, images, etc is best accomplished using a RichTextBox. The table below summarizes the primary
features of TextBox and TextBox.
FLOWDOCUMENT
FORMATTING CONTENT LIKE IMAGES,
REAL-TIME COMMANDS LIKE PARAGRAPHS, TABLES,
CONTROL SPELLCHECKING CONTEX T MENU TOGGLEBOLD (CTR+B) ETC.
NOTE
Although TextBox does not support formatting related editing commands like ToggleBold (Ctr+B), many basic commands
are supported by both controls such as MoveToLineEnd. See EditingCommands for more information.
Features supported by TextBox are covered in the sections below. For more information about RichTextBox, see
RichTextBox Overview.
Real-time Spellchecking
You can enable real-time spellchecking in a TextBox or RichTextBox. When spellchecking is turned on, a red line
appears underneath any misspelled words (see picture below ).
See Enable Spell Checking in a Text Editing Control to learn how to enable spellchecking.
Context Menu
By default, both TextBox and RichTextBox have a context menu that appears when a user right-clicks inside the
control. The context menu allows the user to cut, copy, or paste (see picture below ).
You can create your own custom context menu to override the default behavior. See Use a Custom Context
Menu with a TextBox for more information.
Creating TextBoxes
A TextBox can be a single line in height or comprise multiple lines. A single line TextBox is best for inputting
small amounts of plain text (i.e. "Name", "Phone Number", etc. in a form). The following example shows how to
create a single line TextBox.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBox Width="200" MaxLength="100" />
</StackPanel>
</Page>
You can also create a TextBox that allows the user to enter multiple lines of text. For example, if your form asked
for a biographical sketch of the user, you would want to use a TextBox that supports multiple lines of text. The
following example shows how to use Extensible Application Markup Language (XAML ) to define a TextBox
control that automatically expands to accommodate multiple lines of text.
<TextBox
Name="tbMultiLine"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
>
This TextBox will allow the user to enter multiple lines of text. When the RETURN key is pressed,
or when typed text reaches the edge of the text box, a new line is automatically inserted.
</TextBox>
Setting the TextWrapping attribute to Wrap causes text to wrap to a new line when the edge of the TextBox
control is reached, automatically expanding the TextBox control to include room for a new line, if necessary.
Setting the AcceptsReturn attribute to true causes a new line to be inserted when the RETURN key is pressed,
once again automatically expanding the TextBox to include room for a new line, if necessary.
The VerticalScrollBarVisibility attribute adds a scroll bar to the TextBox, so that the contents of the TextBox can
be scrolled through if the TextBox expands beyond the size of the frame or window that encloses it.
For more information on different tasks associated with using a TextBox, see How -to Topics.
See Also
How -to Topics
RichTextBox Overview
TextBox How-to Topics
8/31/2018 • 2 minutes to read • Edit Online
This section provides examples that demonstrate how to accomplish common tasks using the TextBox control.
In This Section
Create a Multiline TextBox Control
Detect When Text in a TextBox Has Changed
Enable Tab Characters in a TextBox Control
Get a Collection of Lines from a TextBox
Make a TextBox Control Read-Only
Position the Cursor at the Beginning or End of Text in a TextBox Control
Retrieve a Text Selection
Set Focus in a TextBox Control
Set the Text Content of a TextBox Control
Enable Spell Checking in a Text Editing Control
Use a Custom Context Menu with a TextBox
Use Spell Checking with a Context Menu
Add a Watermark to a TextBox
Reference
TextBox
RichTextBox
TextBlock
PasswordBox
See Also
WPF Controls Gallery Sample
TextBox Styles and Templates
How to: Create a Multiline TextBox Control
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use Extensible Application Markup Language (XAML ) to define a TextBox control that
will automatically expand to accommodate multiple lines of text.
Example
Setting the TextWrapping attribute to Wrap will cause entered text to wrap to a new line when the edge of the
TextBox control is reached, automatically expanding the TextBox control to include room for a new line, if necessary.
Setting the AcceptsReturn attribute to true causes a new line to be inserted when the RETURN key is pressed,
once again automatically expanding the TextBox to include room for a new line, if necessary.
The VerticalScrollBarVisibility attribute adds a scroll bar to the TextBox, so that the contents of the TextBox can be
scrolled through if the TextBox expands beyond the size of the frame or window that encloses it.
<TextBox
Name="tbMultiLine"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
>
This TextBox will allow the user to enter multiple lines of text. When the RETURN key is pressed,
or when typed text reaches the edge of the text box, a new line is automatically inserted.
</TextBox>
See Also
TextWrapping
TextBox Overview
RichTextBox Overview
How to: Detect When Text in a TextBox Has Changed
5/4/2018 • 2 minutes to read • Edit Online
This example shows one way to use the TextChanged event to execute a method whenever the text in a TextBox
control has changed.
In the code-behind class for the XAML that contains the TextBox control that you want to monitor for changes,
insert a method to call whenever the TextChanged event fires. This method must have a signature that matches
what is expected by the TextChangedEventHandler delegate.
The event handler is called whenever the contents of the TextBox control are changed, either by a user or
programmatically.
Note: This event fires when the TextBox control is created and initially populated with text.
Example
In the Extensible Application Markup Language (XAML ) that defines your TextBox control, specify the
TextChanged attribute with a value that matches the event handler method name.
<TextBox TextChanged="textChangedEventHandler">
Here is the initial text in my TextBox. Each time the contents of this TextBox are changed,
the TextChanged event fires and textChangedEventHandler is called.
</TextBox>
Example
In the code-behind class for the XAML that contains the TextBox control that you want to monitor for changes,
insert a method to call whenever the TextChanged event fires. This method must have a signature that matches
what is expected by the TextChangedEventHandler delegate.
The event handler is called whenever the contents of the TextBox control are changed, either by a user or
programmatically.
Note: This event fires when the TextBox control is created and initially populated with text.
Comments
See Also
TextChangedEventArgs
TextBox Overview
RichTextBox Overview
How to: Enable Tab Characters in a TextBox Control
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to enable the acceptance of tab characters as normal input in a TextBox control.
Example
To enable the acceptance of tab characters as input in a TextBox control, set the AcceptsTab attribute to true.
<TextBox AcceptsTab="True">
If the AcceptsTab element is "True", the TextBox control will accept tab characters as regular input when
the TAB key is pressed.
If AcceptsTab is "False" (the default), pressing TAB moves the focus to the next focusable control.
</TextBox>
See Also
TextBox Overview
RichTextBox Overview
How to: Get a Collection of Lines from a TextBox
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to get a collection of lines of text from a TextBox.
Example
The following example shows a simple method that takes a TextBox as the argument, and returns a
StringCollection containing the lines of text in the TextBox. The LineCount property is used to determine how
many lines are currently in the TextBox, and the GetLineText method is then used to extract each line and add it to
the collection of lines.
return lines;
}
See Also
TextBox Overview
RichTextBox Overview
How to: Make a TextBox Control Read-Only
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to configure a TextBox control to not allow user input or modification.
Example
To prevent users from modifying the contents of a TextBox control, set the IsReadOnly attribute to true.
<TextBox
IsReadOnly="True"
>
The user may not modify the contents of this TextBox.
</TextBox>
The IsReadOnly attribute affects user input only; it does not affect text set in the Extensible Application Markup
Language (XAML ) description of a TextBox control, or text set programmatically through the Text property.
The default value of IsReadOnly is false.
See Also
TextBox Overview
RichTextBox Overview
How to: Position the Cursor at the Beginning or End
of Text in a TextBox Control
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to position the cursor at the beginning or end of the text contents of a TextBox control.
Example
The following Extensible Application Markup Language (XAML ) code describes a TextBox control and assigns it a
Name.
<TextBox
Name="tbPositionCursor"
>
Here is some text in my text box...
</TextBox>
Example
To position the cursor at the beginning of the contents of a TextBox control, call the Select method and specify the
selection start position of 0, and a selection length of 0.
tbPositionCursor.Select(0, 0);
tbPositionCursor.Select(0, 0)
Example
To position the cursor at the end of the contents of a TextBox control, call the Select method and specify the
selection start position equal to the length of the text content, and a selection length of 0.
tbPositionCursor.Select(tbPositionCursor.Text.Length, 0);
tbPositionCursor.Select(tbPositionCursor.Text.Length, 0)
See Also
TextBox Overview
RichTextBox Overview
How to: Retrieve a Text Selection
5/4/2018 • 2 minutes to read • Edit Online
This example shows one way to use the SelectedText property to retrieve text that the user has selected in a
TextBox control.
Example
The following Extensible Application Markup Language (XAML ) example shows the definition of a TextBox control
that contains some text to select, and a Button control with a specified OnClick method.
In this example, a button with an associated Click event handler is used to retrieve the text selection. When the user
clicks the button, the OnClick method copies any selected text in the textbox into a string. The particular
circumstances by which the text selection is retrieved (clicking a button), as well as the action taken with that
selection (copying the text selection to a string), can easily be modified to accommodate a wide variety of scenarios.
<TextBox Name="tbSelectSomeText">
Some text to select...
</TextBox>
Example
The following C# example shows an OnClick event handler for the button defined in the XAML for this example.
See Also
TextBox Overview
RichTextBox Overview
How to: Set Focus in a TextBox Control
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the Focus method to set focus on a TextBox control.
Example
The following Extensible Application Markup Language (XAML ) example describes a simple TextBox control
named tbFocusMe
<TextBox Name="tbFocusMe">
This is the text in my text box.
</TextBox>
Example
The following example calls the Focus method to set the focus on the TextBox control with the Name tbFocusMe.
tbFocusMe.Focus();
tbFocusMe.Focus()
See Also
Focusable
IsFocused
TextBox Overview
RichTextBox Overview
How to: Set the Text Content of a TextBox Control
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the Text property to set the initial text contents of a TextBox control.
Note Although the Extensible Application Markup Language (XAML ) version of the example could use the
<TextBox.Text> tags around the text of each button's TextBox content, it is not necessary because the TextBox
applies the ContentPropertyAttribute attribute to the Text property. For more information, see XAML Overview
(WPF ).
Example
<TextBox Name="tbSettingText">
Initial text contents of the TextBox.
</TextBox>
Example
tbSettingText.Text = "Initial text contents of the TextBox.";
See Also
TextBox Overview
RichTextBox Overview
How to: Enable Spell Checking in a Text Editing
Control
5/4/2018 • 2 minutes to read • Edit Online
The following example shows how to enable real-time spell checking in a TextBox by using the IsEnabled property
of the SpellCheck class.
Example
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBox SpellCheck.IsEnabled="True" Name="myTextBox"></TextBox>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
namespace SDKSample
{
public partial class SpellCheckExample : Page
{
public SpellCheckExample()
{
StackPanel myStackPanel = new StackPanel();
//Create TextBox
TextBox myTextBox = new TextBox();
myTextBox.Width = 200;
myStackPanel.Children.Add(myTextBox);
this.Content = myStackPanel;
}
}
}
Imports System
Imports System.Windows
Imports System.Windows.Controls
Namespace SDKSample
Partial Public Class SpellCheckExample
Inherits Page
Public Sub New()
Dim myStackPanel As New StackPanel()
'Create TextBox
Dim myTextBox As New TextBox()
myTextBox.Width = 200
myStackPanel.Children.Add(myTextBox)
Me.Content = myStackPanel
End Sub
End Class
End Namespace
See Also
Use Spell Checking with a Context Menu
TextBox Overview
RichTextBox Overview
How to: Use a Custom Context Menu with a TextBox
5/4/2018 • 3 minutes to read • Edit Online
This example shows how to define and implement a simple custom context menu for a TextBox.
Example
The following Extensible Application Markup Language (XAML ) example defines a TextBox control that includes a
custom context menu.
The context menu is defined using a ContextMenu element. The context menu itself consists of a series of
MenuItem elements and Separator elements. Each MenuItem element defines a command in the context menu;
the Header attribute defines the display text for the menu command, and the Click attribute specifies a handler
method for each menu item. The Separator element simply causes a separating line to be rendered between the
previous and subsequent menu items.
<TextBox
Name="cxmTextBox"
Grid.Row="1"
AcceptsReturn="True"
AcceptsTab="True"
VerticalScrollBarVisibility="Visible"
TextWrapping="Wrap"
>
<TextBox.ContextMenu>
<ContextMenu
Name="cxm"
Opened="CxmOpened"
>
<MenuItem
Header="Cut"
Name="cxmItemCut"
Click="ClickCut"
/>
<MenuItem
Header="Copy"
Name="cxmItemCopy"
Click="ClickCopy"
/>
<MenuItem
Header="Paste"
Name="cxmItemPaste"
Click="ClickPaste"
/>
<Separator/>
<MenuItem
Header="Select All"
Name="cxmItemSelectAll"
Click="ClickSelectAll"
/>
<MenuItem
Header="Select Current Line"
Name="cxmItemSelectLine"
Click="ClickSelectLine"
/>
<Separator/>
<MenuItem
Header="Undo Last Action"
Name="cxmItemUndo"
Click="ClickUndo"
/>
<MenuItem
Header="Redo Last Action"
Name="cxmItemRedo"
Click="ClickRedo"
/>
<Separator/>
<MenuItem
Header="Clear All Text"
Name="cxmItemClear"
Click="ClickClear"
/>
</ContextMenu>
</TextBox.ContextMenu>
This TextBox uses a simple custom context menu. The context menu can be disabled by checking
the CheckBox above, which simply sets the TextBox.ContextMenu property to null.
</TextBox>
Example
The following example shows the implementation code for the preceding context menu definition, as well as the
code that enables and disables the context menu. The Opened event is used to dynamically enable or disable
certain commands depending on the current state of the TextBox.
To restore the default context menu, use the ClearValue method to clear the value of the ContextMenu property. To
disable the context menu altogether, set the ContextMenu property to a null reference ( Nothing in Visual Basic).
switch (rb.Name)
{
case "rbCustom":
cxmTextBox.ContextMenu = cxm;
break;
case "rbDefault":
// Clearing the value of the ContextMenu property
// restores the default TextBox context menu.
cxmTextBox.ClearValue(ContextMenuProperty);
break;
case "rbDisabled":
// Setting the ContextMenu propety to
// null disables the context menu.
cxmTextBox.ContextMenu = null;
break;
default:
break;
}
See Also
Use Spell Checking with a Context Menu
TextBox Overview
RichTextBox Overview
How to: Use Spell Checking with a Context Menu
5/4/2018 • 3 minutes to read • Edit Online
By default, when you enable spell checking in an editing control like TextBox or RichTextBox, you get spell-
checking choices in the context menu. For example, when users right-click a misspelled word, they get a set of
spelling suggestions or the option to Ignore All. However, when you override the default context menu with your
own custom context menu, this functionality is lost, and you need to write code to reenable the spell-checking
feature in the context menu. The following example shows how to enable this on a TextBox.
Example
The following example shows the Extensible Application Markup Language (XAML ) that creates a TextBox with
some events that are used to implement the context menu.
<Page x:Class="SDKSample.SpellerCustomContextMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="OnWindowLoaded">
<TextBox
Name="myTextBox"
TextWrapping="Wrap"
SpellCheck.IsEnabled="True"
ContextMenuOpening="tb_ContextMenuOpening">
In a custum menu you need to write code to add speler choices
because everything in a custom context menu has to be added explicitly.
</TextBox>
</Page>
Example
The following example shows the code that implements the context menu.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SDKSample
{
public partial class SpellerCustomContextMenu : Page
{
myTextBox.ContextMenu = GetContextMenu();
caretIndex = myTextBox.CaretIndex;
cmdIndex = 0;
spellingError = myTextBox.GetSpellingError(caretIndex);
if (spellingError != null)
{
foreach (string str in spellingError.Suggestions)
{
MenuItem mi = new MenuItem();
mi.Header = str;
mi.FontWeight = FontWeights.Bold;
mi.Command = EditingCommands.CorrectSpellingError;
mi.CommandParameter = str;
mi.CommandTarget = myTextBox;
myTextBox.ContextMenu.Items.Insert(cmdIndex, mi);
cmdIndex++;
}
Separator separatorMenuItem1 = new Separator();
myTextBox.ContextMenu.Items.Insert(cmdIndex, separatorMenuItem1);
cmdIndex++;
MenuItem ignoreAllMI = new MenuItem();
ignoreAllMI.Header = "Ignore All";
ignoreAllMI.Command = EditingCommands.IgnoreSpellingError;
ignoreAllMI.CommandTarget = myTextBox;
myTextBox.ContextMenu.Items.Insert(cmdIndex, ignoreAllMI);
cmdIndex++;
Separator separatorMenuItem2 = new Separator();
myTextBox.ContextMenu.Items.Insert(cmdIndex, separatorMenuItem2);
}
}
cm.Items.Add(m1);
cm.Items.Add(m2);
cm.Items.Add(m3);
cm.Items.Add(m4);
return cm;
}
}
}
Namespace SDKSample
Partial Public Class SpellerCustomContextMenu
Inherits Page
Private Sub OnWindowLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
myTextBox.ContextMenu = GetContextMenu()
caretIndex = myTextBox.CaretIndex
cmdIndex = 0
spellingError = myTextBox.GetSpellingError(caretIndex)
If spellingError IsNot Nothing Then
For Each str As String In spellingError.Suggestions
Dim mi As New MenuItem()
mi.Header = str
mi.FontWeight = FontWeights.Bold
mi.Command = EditingCommands.CorrectSpellingError
mi.CommandParameter = str
mi.CommandTarget = myTextBox
myTextBox.ContextMenu.Items.Insert(cmdIndex, mi)
cmdIndex += 1
Next str
Dim separatorMenuItem1 As New Separator()
myTextBox.ContextMenu.Items.Insert(cmdIndex, separatorMenuItem1)
cmdIndex += 1
Dim ignoreAllMI As New MenuItem()
ignoreAllMI.Header = "Ignore All"
ignoreAllMI.Command = EditingCommands.IgnoreSpellingError
ignoreAllMI.CommandTarget = myTextBox
myTextBox.ContextMenu.Items.Insert(cmdIndex, ignoreAllMI)
cmdIndex += 1
Dim separatorMenuItem2 As New Separator()
myTextBox.ContextMenu.Items.Insert(cmdIndex, separatorMenuItem2)
End If
End Sub
cm.Items.Add(m1)
cm.Items.Add(m2)
cm.Items.Add(m3)
cm.Items.Add(m4)
Return cm
End Function
End Class
End Class
End Namespace
The code used for doing this with a RichTextBox is similar. The main difference is in the parameter passed to the
GetSpellingError method. For a TextBox, pass the integer index of the caret position:
spellingError = myTextBox.GetSpellingError(caretIndex);
For a RichTextBox, pass the TextPointer that specifies the caret position:
spellingError = myRichTextBox.GetSpellingError(myRichTextBox.CaretPosition);
See Also
TextBox Overview
RichTextBox Overview
Enable Spell Checking in a Text Editing Control
Use a Custom Context Menu with a TextBox
How to: Add a Watermark to a TextBox
5/4/2018 • 2 minutes to read • Edit Online
The following example shows how to aid usability of a TextBox by displaying an explanatory background image
inside of the TextBox until the user inputs text, at which point the image is removed. In addition, the background
image is restored again if the user removes their input. See illustration below.
NOTE
The reason a background image is used in this example rather then simply manipulating the Text property of TextBox, is that
a background image will not interfere with data binding.
Example
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.TextBoxBackgroundExample"
>
<StackPanel>
<TextBox Name="myTextBox" TextChanged="OnTextBoxTextChanged" Width="200">
<TextBox.Background>
<ImageBrush ImageSource="TextBoxBackground.gif" AlignmentX="Left" Stretch="None" />
</TextBox.Background>
</TextBox>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace SDKSample
{
public partial class TextBoxBackgroundExample : Page
{
if (myTextBox.Text == "")
{
// Create an ImageBrush.
ImageBrush textImageBrush = new ImageBrush();
textImageBrush.ImageSource =
new BitmapImage(
new Uri(@"TextBoxBackground.gif", UriKind.Relative)
);
textImageBrush.AlignmentX = AlignmentX.Left;
textImageBrush.Stretch = Stretch.None;
// Use the brush to paint the button's background.
myTextBox.Background = textImageBrush;
}
else
{
myTextBox.Background = null;
}
}
Namespace SDKSample
Partial Public Class TextBoxBackgroundExample
Inherits Page
textImageBrush.ImageSource =
New BitmapImage(New Uri("TextBoxBackground.gif", UriKind.Relative))
textImageBrush.AlignmentX = AlignmentX.Left
textImageBrush.Stretch = Stretch.None
Else
myTextBox.Background = Nothing
End If
End Sub
End Class
End Namespace
See Also
TextBox Overview
RichTextBox Overview
ToolBar
5/4/2018 • 2 minutes to read • Edit Online
The ToolBar control is a container for a group of commands or controls that are typically related in their function.
The following illustrations show horizontal and vertical ToolBar controls.
Horizontal Toolbar
Vertical Toolbar
In This Section
ToolBar Overview
Style Controls on a ToolBar
Reference
ToolBar
ToolBarTray
Related Sections
ToolBar Overview
8/31/2018 • 2 minutes to read • Edit Online
ToolBar controls are containers for a group of commands or controls which are typically related in their function. A
ToolBar usually contains buttons which invoke commands.
ToolBar Control
The ToolBar control takes its name from the bar-like arrangement of buttons or other controls into a single row or
column. WPF ToolBar controls provide an overflow mechanism which places any items that do not fit naturally
within a size-constrained ToolBar into a special overflow area. Also, WPF ToolBar controls are usually used with the
related ToolBarTray control, which provides special layout behavior as well as support for user-initiated sizing and
arranging of toolbars.
The ToolBar uses a ToolBarPanel and a ToolBarOverflowPanel in its ControlTemplate. The ToolBarPanel is
responsible for the layout of the items on the toolbar. The ToolBarOverflowPanel is responsible for the layout of
the items that do not fit on the ToolBar. For an example of a ControlTemplate for a ToolBar, see
ToolBar Styles and Templates.
See Also
ToolBarPanel
ToolBarOverflowPanel
Style Controls on a ToolBar
WPF Controls Gallery Sample
How to: Style Controls on a ToolBar
5/4/2018 • 2 minutes to read • Edit Online
The ToolBar defines ResourceKey objects to specify the style of controls within the ToolBar. To style a control in a
ToolBar, set the x:key attribute of the style to a ResourceKey defined in ToolBar.
The ToolBar defines the following ResourceKey objects:
ButtonStyleKey
CheckBoxStyleKey
ComboBoxStyleKey
MenuStyleKey
RadioButtonStyleKey
SeparatorStyleKey
TextBoxStyleKey
ToggleButtonStyleKey
Example
The following example defines styles for the controls within a ToolBar.
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Foreground" Value="DarkSlateBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="Menu">
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="LightSteelBlue"/>
</Style>
<Style TargetType="RadioButton">
<Setter Property="Background" Value="LightSteelBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="Background" Value="DarkBlue"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Width" Value="75"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Background" Value="LightSteelBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinWidth" Value="60"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Window.Resources>
<ToolBarTray Margin="10,10,3,3"
Grid.Column="0" Grid.Row="2"
Background="LightBlue">
<ToolBar >
<Button Content="Button 1"/>
<Button Content="Button 2"/>
<Separator/>
<CheckBox Content="CheckBox 1"/>
<CheckBox Content="CheckBox 2"/>
<Separator/>
<RadioButton>One</RadioButton>
<RadioButton>Two</RadioButton>
<Separator/>
<ComboBox>
<ComboBoxItem IsSelected="True">Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBoxItem>Item 3</ComboBoxItem>
<ComboBoxItem>Item 4</ComboBoxItem>
</ComboBox>
<TextBox/>
<Separator/>
<Menu>
<MenuItem Header="Menu">
<MenuItem Header="File">
<MenuItem Header="Copy"/>
<MenuItem Header="Paste"/>
</MenuItem>
</MenuItem>
</Menu>
</ToolBar>
</ToolBarTray>
See Also
Styling and Templating
ToolTip
5/4/2018 • 2 minutes to read • Edit Online
A tooltip is a small pop-up window that appears when a user pauses the mouse pointer over an element, such as
over a Button.
The following illustration shows a mouse pointer that points to the CloseButton, which then displays its identifying
ToolTip.
Close button with its tooltip displayed
In This Section
ToolTip Overview
How -to Topics
Reference
ToolTip
ToolTipService
Popup
Related Sections
Popup Overview
How -to Topics
ToolTip Overview
8/31/2018 • 3 minutes to read • Edit Online
A tooltip is a small pop-up window that appears when a user pauses the mouse pointer over an element, such as
over a Button. This topic introduces the tooltip and discusses how to create and customize tooltip content.
What Is a Tooltip?
When a user moves the mouse pointer over an element that has a tooltip, a window that contains tooltip content
(for example, text content that describes the function of a control) appears for a specified amount of time. If the
user moves the mouse pointer away from the control, the window disappears because the tooltip content cannot
receive focus.
The content of a tooltip can contain one or more lines of text, images, shapes, or other visual content. You define a
tooltip for a control by setting one of the following properties to the tooltip content.
FrameworkContentElement.ToolTip
FrameworkElement.ToolTip
Which property you use depends on whether the control that defines the tooltip inherits from the
FrameworkContentElement or FrameworkElement class.
Creating a ToolTip
The following example shows how to create a simple tooltip by setting the ToolTip property for a Button control to
a text string.
You can also define a tooltip as a ToolTip object. The following example uses XAML to specify a ToolTip object as
the tooltip of a TextBox element. Note that the example specifies the ToolTip by setting the
FrameworkElement.ToolTip property.
The following example uses code to generate a ToolTip object. The example creates a ToolTip ( tt ) and associates
it with a Button.
button = new Button();
button.Content = "Hover over me.";
tt = new ToolTip();
tt.Content = "Created with C#";
button.ToolTip = tt;
cv2.Children.Add(button);
You can also create tooltip content that is not defined as a ToolTip object by enclosing the tooltip content in a
layout element, such as a DockPanel. The following example shows how to set the ToolTip property of a TextBox to
content that is enclosed in a DockPanel control.
<TextBox>
ToolTip with image and text
<TextBox.ToolTip>
<StackPanel>
<Image Source="data\flower.jpg"/>
<TextBlock>Useful information goes here.</TextBlock>
</StackPanel>
</TextBox.ToolTip>
Styling a ToolTip
You can style a ToolTip by defining a custom Style. The following example defines a Style called Simple that
shows how to offset the placement of the ToolTip and change its appearance by setting the Background,
Foreground, FontSize, and FontWeight.
<Style TargetType="ToolTip">
<Setter Property = "HorizontalOffset" Value="10"/>
<Setter Property = "VerticalOffset" Value="10"/>
<Setter Property = "Background" Value="LightBlue"/>
<Setter Property = "Foreground" Value="Purple"/>
<Setter Property = "FontSize" Value="14"/>
<Setter Property = "FontWeight" Value="Bold"/>
</Style>
See Also
ToolTipService
ToolTip
ToolTipEventArgs
ToolTipEventHandler
How -to Topics
ToolTip How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
In This Section
Position a ToolTip
Use the BetweenShowDelay Property
Reference
ToolTip
ToolTipService
Popup
Related Sections
Popup Overview
How -to Topics
How to: Position a ToolTip
8/31/2018 • 3 minutes to read • Edit Online
This example shows how to specify the position of a tooltip on the screen.
Example
You can position a tooltip by using a set of five properties that are defined in both the ToolTip and ToolTipService
classes. The following table shows these two sets of five properties and provides links to their reference
documentation according to class.
Corresponding tooltip properties according to class
SYSTEM.WINDOWS.CONTROLS.TOOLTIPSERVICE CLASS
SYSTEM.WINDOWS.CONTROLS.TOOLTIP CLASS PROPERTIES PROPERTIES
ToolTip.Placement ToolTipService.Placement
ToolTip.PlacementTarget ToolTipService.PlacementTarget
ToolTip.PlacementRectangle ToolTipService.PlacementRectangle
ToolTip.HorizontalOffset ToolTipService.HorizontalOffset
ToolTip.VerticalOffset ToolTipService.VerticalOffset
If you define the contents of a tooltip by using a ToolTip object, you can use the properties of either class; however,
the ToolTipService properties take precedence. Use the ToolTipService properties for tooltips that are not defined
as ToolTip objects.
The following illustrations show how to position a tooltip by using these properties. Although, the Extensible
Application Markup Language (XAML ) examples in these illustrations show how to set the properties that are
defined by the ToolTip class, the corresponding properties of the ToolTipService class follow the same layout rules.
For more information about the possible values for the Placement property, see Popup Placement Behavior.
The following example shows how to use the ToolTipService properties to specify the position of a tooltip whose
content is not a ToolTip object.
<Ellipse Height="25" Width="50"
Fill="Gray"
HorizontalAlignment="Left"
ToolTipService.InitialShowDelay="1000"
ToolTipService.ShowDuration="7000"
ToolTipService.BetweenShowDelay="2000"
ToolTipService.Placement="Right"
ToolTipService.PlacementRectangle="50,0,0,0"
ToolTipService.HorizontalOffset="10"
ToolTipService.VerticalOffset="20"
ToolTipService.HasDropShadow="false"
ToolTipService.ShowOnDisabled="true"
ToolTipService.IsEnabled="true"
ToolTipOpening="whenToolTipOpens"
ToolTipClosing="whenToolTipCloses"
>
<Ellipse.ToolTip>
<BulletDecorator>
<BulletDecorator.Bullet>
<Ellipse Height="10" Width="20" Fill="Blue"/>
</BulletDecorator.Bullet>
<TextBlock>Uses the ToolTipService class</TextBlock>
</BulletDecorator>
</Ellipse.ToolTip>
</Ellipse>
//Create and Ellipse with the BulletDecorator as
//the tooltip
Ellipse ellipse2 = new Ellipse();
ellipse2.Name = "ellipse2";
this.RegisterName(ellipse2.Name, ellipse2);
ellipse2.Height = 25;
ellipse2.Width = 50;
ellipse2.Fill = Brushes.Gray;
ellipse2.HorizontalAlignment = HorizontalAlignment.Left;
ToolTipService.SetPlacement(ellipse2, PlacementMode.Right);
ToolTipService.SetPlacementRectangle(ellipse2,
new Rect(50, 0, 0, 0));
ToolTipService.SetHorizontalOffset(ellipse2, 10.0);
ToolTipService.SetVerticalOffset(ellipse2, 20.0);
ToolTipService.SetHasDropShadow(ellipse2, false);
ToolTipService.SetIsEnabled(ellipse2, true);
ToolTipService.SetShowOnDisabled(ellipse2, true);
ellipse2.AddHandler(ToolTipService.ToolTipOpeningEvent,
new RoutedEventHandler(whenToolTipOpens));
ellipse2.AddHandler(ToolTipService.ToolTipClosingEvent,
new RoutedEventHandler(whenToolTipCloses));
ToolTipService.SetPlacement(ellipse2, PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ellipse2, 10.0)
ToolTipService.SetVerticalOffset(ellipse2, 20.0)
ToolTipService.SetHasDropShadow(ellipse2, False)
ToolTipService.SetIsEnabled(ellipse2, True)
ToolTipService.SetShowOnDisabled(ellipse2, True)
See Also
ToolTip
ToolTipService
How -to Topics
ToolTip Overview
Use the ContextMenuService and ToolTipService
How to: Use the BetweenShowDelay Property
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the BetweenShowDelay time property so that tooltips appear quickly—with little
or no delay—when a user moves the mouse pointer from one tooltip directly to another.
Example
In the following example, the InitialShowDelay property is set to one second (1000 milliseconds) and the
BetweenShowDelay is set to two seconds (2000 milliseconds) for the tooltips of both Ellipse controls. If you
display the tooltip for one of the ellipses and then move the mouse pointer to another ellipse within two seconds
and pause on it, the tooltip of the second ellipse displays immediately.
In either of the following scenarios, the InitialShowDelay applies, which causes the tooltip for the second ellipse to
wait one second before it appears:
If the time it takes to move to the second button is more than two seconds.
If the tooltip is not visible at the beginning of the time interval for the first ellipse.
See Also
ToolTip
ToolTipService
How -to Topics
ToolTip Overview
TreeView
5/4/2018 • 2 minutes to read • Edit Online
The TreeView control displays information in a hierarchical structure by using collapsible nodes.
The following illustration is an example of a TreeView control that has nested TreeViewItem controls.
In This Section
TreeView Overview
How -to Topics
Reference
TreeView
TreeViewItem
Related Sections
Data Binding Overview
Data Templating Overview
TreeView Overview
5/4/2018 • 3 minutes to read • Edit Online
The TreeView control provides a way to display information in a hierarchical structure by using collapsible nodes.
This topic introduces the TreeView and TreeViewItem controls, and provides simple examples of their use.
What Is a TreeView?
TreeView is an ItemsControl that nests the items by using TreeViewItem controls. The following example creates a
TreeView.
Creating a TreeView
The TreeView control contains a hierarchy of TreeViewItem controls. A TreeViewItem control is a
HeaderedItemsControl that has a Header and an Items collection.
If you are defining a TreeView by using Extensible Application Markup Language (XAML ), you can explicitly define
the Header content of a TreeViewItem control and the items that make up its collection. The previous illustration
demonstrates this method.
You can also specify an ItemsSource as a data source and then specify a HeaderTemplate and ItemTemplate to
define the TreeViewItem content.
To define the layout of a TreeViewItem control, you can also use HierarchicalDataTemplate objects. For more
information and an example, see Use SelectedValue, SelectedValuePath, and SelectedItem.
If an item is not a TreeViewItem control, it is automatically enclosed by a TreeViewItem control when the TreeView
control is displayed.
TreeViewItem Selection
When a user clicks a TreeViewItem control to select it, the Selected event occurs, and its IsSelected property is set
to true . The TreeViewItem also becomes the SelectedItem of the TreeView control. Conversely, when the
selection changes from a TreeViewItem control, its Unselected event occurs and its IsSelected property is set to
false .
The SelectedItem property on the TreeView control is a read-only property; hence, you cannot explicitly set it. The
SelectedItem property is set if the user clicks on a TreeViewItem control or when the IsSelected property is set to
true on the TreeViewItem control.
Use the SelectedValuePath property to specify a SelectedValue of a SelectedItem. For more information, see Use
SelectedValue, SelectedValuePath, and SelectedItem.
You can register an event handler on the SelectedItemChanged event in order to determine when a selected
TreeViewItem changes. The RoutedPropertyChangedEventArgs<T> that is provided to the event handler specifies
the OldValue, which is the previous selection, and the NewValue, which is the current selection. Either value can be
null if the application or user has not made a previous or current selection.
TreeView Style
The default style for a TreeView control places it inside a StackPanel object that contains a ScrollViewer control.
When you set the Width and Height properties for a TreeView, these values are used to size the StackPanel object
that displays the TreeView. If the content to display is larger than the display area, a ScrollViewer automatically
displays so that the user can scroll through the TreeView content.
To customize the appearance of a TreeViewItem control, set the Style property to a custom Style.
The following example shows how to set the Foreground and FontSize property values for a TreeViewItem control
by using a Style.
The following example shows how to define a DataTemplate that contains an Image and a TextBlock that are
enclosed in a DockPanel control. You can use a DataTemplate to set the HeaderTemplate or ItemTemplate for a
TreeViewItem.
<DataTemplate x:Key="NewspaperTVItem">
<DockPanel>
<Image Source="images\icon.jpg"/>
<TextBlock VerticalAlignment="center" Text ="{Binding Path=Name}"/>
</DockPanel>
</DataTemplate>
See Also
TreeView
TreeViewItem
How -to Topics
WPF Content Model
TreeView How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The topics in this section describe how to use the TreeView control to display information in a hierarchical
structure.
In This Section
Create Simple or Complex TreeViews
Use SelectedValue, SelectedValuePath, and SelectedItem
Bind a TreeView to Data That Has an Indeterminable Depth
Improve the Performance of a TreeView
Find a TreeViewItem in a TreeView
Reference
TreeView
TreeViewItem
Related Sections
How to: Create Simple or Complex TreeViews
5/4/2018 • 2 minutes to read • Edit Online
Example
The Header property of the TreeViewItem contains the content that the TreeView displays for that item. A
TreeViewItem can also have TreeViewItem controls as its child elements and you can define these child elements
by using the Items property.
The following example shows how to explicitly define TreeViewItem content by setting the Header property to a
text string.
<TreeView>
<TreeViewItem Header="Employee1">
<TreeViewItem Header="Jesper"/>
<TreeViewItem Header="Aaberg"/>
<TreeViewItem Header="12345"/>
</TreeViewItem>
<TreeViewItem Header="Employee2">
<TreeViewItem Header="Dominik"/>
<TreeViewItem Header="Paiha"/>
<TreeViewItem Header="98765"/>
</TreeViewItem>
</TreeView>
The following example show how to define child elements of a TreeViewItem by defining Items that are Button
controls.
<TreeView>
<TreeViewItem Header ="Employee1">
<TreeViewItem.Items>
<Button>Jesper</Button>
<Button>Aaberg</Button>
<Button>12345</Button>
</TreeViewItem.Items>
</TreeViewItem>
<TreeViewItem Header="Employee2">
<TreeViewItem.Items>
<Button>Dominik</Button>
<Button>Paiha</Button>
<Button>98765</Button>
</TreeViewItem.Items>
</TreeViewItem>
</TreeView>
The following example shows how to create a TreeView where an XmlDataProvider provides TreeViewItem
content and a HierarchicalDataTemplate defines the appearance of the content.
<XmlDataProvider x:Key="myEmployeeData" XPath="/EmployeeData">
<x:XData>
<EmployeeData xmlns="">
<EmployeeInfo>
<EmployeeInfoData>Employee1</EmployeeInfoData>
<Item Type="FirstName">Jesper</Item>
<Item Type="LastName">Aaberg</Item>
<Item Type="EmployeeNumber">12345</Item>
</EmployeeInfo>
<EmployeeInfo>
<EmployeeInfoData>Employee2</EmployeeInfoData>
<Item Type="FirstName">Dominik</Item>
<Item Type="LastName">Paiha</Item>
<Item Type="EmployeeNumber">98765</Item>
</EmployeeInfo>
</EmployeeData>
</x:XData>
</XmlDataProvider>
<HierarchicalDataTemplate DataType="EmployeeInfo"
ItemsSource ="{Binding XPath=Item}">
<TextBlock Text="{Binding XPath=EmployeeInfoData}" />
</HierarchicalDataTemplate>
The following example shows how to create a TreeView where the TreeViewItem content contains DockPanel
controls that have embedded content.
<TreeView>
<TreeViewItem Header="Animals">
<TreeViewItem.Items>
<DockPanel>
<Image Source="data\fish.png"/>
<TextBlock Margin="5" Foreground="Brown"
FontSize="12">Fish</TextBlock>
</DockPanel>
<DockPanel>
<Image Source="data\dog.png"/>
<TextBlock Margin="5" Foreground="Brown"
FontSize="12">Dog</TextBlock>
</DockPanel>
<DockPanel>
<Image Source="data\cat.png"/>
<TextBlock Margin="5" Foreground="Brown"
FontSize="12">Cat</TextBlock>
</DockPanel>
</TreeViewItem.Items>
</TreeViewItem>
</TreeView>
See Also
TreeView
TreeViewItem
TreeView Overview
How -to Topics
How to: Use SelectedValue, SelectedValuePath, and
SelectedItem
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to use the SelectedValue and SelectedValuePath properties to specify a value for the
SelectedItem of a TreeView.
Example
The SelectedValuePath property provides a way to specify a SelectedValue for the SelectedItem in a TreeView. The
SelectedItem represents an object in the Items collection and the TreeView displays the value of a single property
of the selected item. The SelectedValuePath property specifies the path to the property that is used to determine
the value of the SelectedValue property. The examples in this topic illustrate this concept.
The following example shows an XmlDataProvider that contains employee information.
The following example defines a HierarchicalDataTemplate that displays the EmployeeName and EmployeeWorkDay
of the Employee . Note that the HierarchicalDataTemplate does not specify the EmployeeNumber as part of the
template.
The following example shows a TreeView that uses the previously defined HierarchicalDataTemplate and that sets
the SelectedValue property to the EmployeeNumber . When you select an EmployeeName in the TreeView, the
SelectedItem property returns the EmployeeInfo data item that corresponds to the selected EmployeeName .
However, because the SelectedValuePath of this TreeView is set to EmployeeNumber , the SelectedValue is set to the
EmployeeNumber .
<TreeView ItemsSource="{Binding Source={StaticResource myEmployeeData},
ItemTemplate={StaticResource SampleTemplate},
XPath=EmployeeInfo}"
Name="myTreeView"
SelectedValuePath="EmployeeNumber"
/>
See Also
TreeView
TreeViewItem
TreeView Overview
How -to Topics
How to: Bind a TreeView to Data That Has an
Indeterminable Depth
5/4/2018 • 2 minutes to read • Edit Online
There might be times when you want to bind a TreeView to a data source whose depth is not known. This can
occur when the data is recursive in nature, such as a file system, where folders can contain folders, or a company's
organizational structure, where employees have other employees as direct reports.
The data source must have a hierarchical object model. For example, an Employee class might contain a collection
of Employee objects that are the direct reports of an employee. If the data is represented in a way that is not
hierarchical, you must build a hierarchical representation of the data.
When you set the ItemsControl.ItemTemplate property and if the ItemsControl generates an ItemsControl for each
child item, then the child ItemsControl uses the same ItemTemplate as the parent. For example, if you set the
ItemTemplate property on a data-bound TreeView, each TreeViewItem that is generated uses the DataTemplate
that was assigned to the ItemTemplate property of the TreeView.
The HierarchicalDataTemplate enables you to specify the ItemsSource for a TreeViewItem, or any
HeaderedItemsControl, on the data template. When you set the HierarchicalDataTemplate.ItemsSource property,
that value is used when the HierarchicalDataTemplate is applied. By using a HierarchicalDataTemplate, you can
recursively set the ItemsSource for each TreeViewItem in the TreeView.
Example
The following example demonstrates how to bind a TreeView to hierarchical data and use a
HierarchicalDataTemplate to specify the ItemsSource for each TreeViewItem. The TreeView binds to XML data that
represents the employees in a company. Each Employee element can contain other Employee elements to indicate
who reports to whom. Because the data is recursive, the HierarchicalDataTemplate can be applied to each level.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<XmlDataProvider x:Key="myCompany" XPath="Company/Employee">
<x:XData>
<Company xmlns="">
<Employee Name="Don Hall">
<Employee Name="Alice Ciccu">
<Employee Name="David Pelton">
<Employee Name="Vivian Atlas"/>
</Employee>
<Employee Name="Jeff Price"/>
<Employee Name="Andy Jacobs"/>
</Employee>
<Employee Name="Bill Malone">
<Employee Name="Maurice Taylor"/>
<Employee Name="Sunil Uppal"/>
<Employee Name="Qiang Wang"/>
</Employee>
</Employee>
</Company>
</x:XData>
</XmlDataProvider>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</Page.Resources>
<Grid>
<TreeView ItemsSource="{Binding Source={StaticResource myCompany}}"
ItemTemplate="{StaticResource EmployeeTemplate}"/>
</Grid>
</Page>
See Also
Data Binding Overview
Data Templating Overview
How to: Improve the Performance of a TreeView
5/4/2018 • 2 minutes to read • Edit Online
If a TreeView contains many items, the amount of time it takes to load may cause a significant delay in the user
interface. You can improve the load time by setting the VirtualizingStackPanel.IsVirtualizing attached property
to true . The UI might also be slow to react when a user scrolls the TreeView by using the mouse wheel or
dragging the thumb of a scrollbar. You can improve the performance of the TreeView when the user scrolls by
setting the VirtualizingStackPanel.VirtualizationMode attached property to VirtualizationMode.Recycling.
Example
Description
The following example creates a TreeView that sets the VirtualizingStackPanel.IsVirtualizing attached property
to true and the VirtualizingStackPanel.VirtualizationMode attached property to VirtualizationMode.Recycling to
optimize its performance.
Code
<StackPanel>
<StackPanel.Resources>
<src:TreeViewData x:Key="dataItems"/>
<TreeView Height="200"
ItemsSource="{Binding Source={StaticResource dataItems}}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemContainerStyle>
The following example shows the data that the previous example uses.
public class TreeViewData : ObservableCollection<ItemsForTreeView>
{
public TreeViewData()
{
for (int i = 0; i < 100; ++i)
{
ItemsForTreeView item = new ItemsForTreeView();
item.TopLevelName = "item " + i.ToString();
Add(item);
}
}
}
public ItemsForTreeView()
{
for (int i = 0; i < 10; ++i)
{
SecondLevelItems.Add("Second Level " + i.ToString());
}
}
}
Public Class TreeViewData
Inherits ObservableCollection(Of ItemsForTreeView)
See Also
Controls
How to: Find a TreeViewItem in a TreeView
5/4/2018 • 6 minutes to read • Edit Online
The TreeView control provides a convenient way to display hierarchical data. If your TreeView is bound to a data
source, the SelectedItem property provides a convenient way for you to quickly retrieve the selected data object. It
is typically best to work with the underlying data object, but sometimes you may need to programmatically
manipulate the data's containing TreeViewItem. For example, you may need to programmatically expand the
TreeViewItem, or select a different item in the TreeView.
To find a TreeViewItem that contains a specific data object, you must traverse each level of the TreeView. The items
in a TreeView can also be virtualized to improve performance. In the case where items might be virtualized, you
also must realize a TreeViewItem to check whether it contains the data object.
Example
Description
The following example searches a TreeView for a specific object and returns the object's containing TreeViewItem.
The example ensures that each TreeViewItem is instantiated so that its child items can be searched. This example
also works if the TreeView does not use virtualized items.
NOTE
The following example works for any TreeView, regardless of the underlying data model, and searches every TreeViewItem
until the object is found. Another technique that has better performance is to search the data model for the specified object,
keep track of its location within the data hierarchy, and then find the corresponding TreeViewItem in the TreeView. However,
the technique that has better performance requires knowledge of the data model and cannot be generalized for any given
TreeView.
Code
/// <summary>
/// Recursively search for an item in this subtree.
/// </summary>
/// <param name="container">
/// The parent ItemsControl. This can be a TreeView or a TreeViewItem.
/// </param>
/// <param name="item">
/// The item to search for.
/// </param>
/// <returns>
/// The TreeViewItem that contains the specified item.
/// </returns>
private TreeViewItem GetTreeViewItem(ItemsControl container, object item)
{
if (container != null)
{
if (container.DataContext == item)
{
return container as TreeViewItem;
}
container.ApplyTemplate();
ItemsPresenter itemsPresenter =
(ItemsPresenter)container.Template.FindName("ItemsHost", container);
if (itemsPresenter != null)
{
itemsPresenter.ApplyTemplate();
}
else
{
// The Tree template has not named the ItemsPresenter,
// so walk the descendents and find the child.
itemsPresenter = FindVisualChild<ItemsPresenter>(container);
if (itemsPresenter == null)
{
container.UpdateLayout();
itemsPresenter = FindVisualChild<ItemsPresenter>(container);
}
}
// Ensure that the generator for this panel has been created.
UIElementCollection children = itemsHostPanel.Children;
MyVirtualizingStackPanel virtualizingPanel =
itemsHostPanel as MyVirtualizingStackPanel;
subContainer =
(TreeViewItem)container.ItemContainerGenerator.
ContainerFromIndex(i);
}
else
{
subContainer =
(TreeViewItem)container.ItemContainerGenerator.
ContainerFromIndex(i);
if (subContainer != null)
{
// Search the next level for the object.
TreeViewItem resultContainer = GetTreeViewItem(subContainer, item);
if (resultContainer != null)
{
{
return resultContainer;
}
else
{
// The object is not under this TreeViewItem
// so collapse it.
subContainer.IsExpanded = false;
}
}
}
}
return null;
}
/// <summary>
/// Search for an element of a certain type in the visual tree.
/// </summary>
/// <typeparam name="T">The type of element to find.</typeparam>
/// <param name="visual">The parent element.</param>
/// <returns></returns>
private T FindVisualChild<T>(Visual visual) where T : Visual
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
{
Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
if (child != null)
{
T correctlyTyped = child as T;
if (correctlyTyped != null)
{
return correctlyTyped;
}
T descendent = FindVisualChild<T>(child);
if (descendent != null)
{
return descendent;
}
}
}
return null;
}
''' <summary>
''' Recursively search for an item in this subtree.
''' </summary>
''' <param name="container">
''' The parent ItemsControl. This can be a TreeView or a TreeViewItem.
''' </param>
''' <param name="item">
''' The item to search for.
''' </param>
''' <returns>
''' The TreeViewItem that contains the specified item.
''' </returns>
Private Function GetTreeViewItem(ByVal container As ItemsControl,
ByVal item As Object) As TreeViewItem
container.SetValue(TreeViewItem.IsExpandedProperty, True)
End If
' Do this to ensure that the generator for this panel has been created.
Dim children As UIElementCollection = itemsHostPanel.Children
subContainer =
DirectCast(container.ItemContainerGenerator.ContainerFromIndex(index),
TreeViewItem)
Else
subContainer =
DirectCast(container.ItemContainerGenerator.ContainerFromIndex(index),
TreeViewItem)
Return Nothing
End Function
''' <summary>
''' Search for an element of a certain type in the visual tree.
''' </summary>
''' <typeparam name="T">The type of element to find.</typeparam>
''' <param name="visual">The parent element.</param>
''' <returns></returns>
Private Function FindVisualChild(Of T As Visual)(ByVal visual As Visual) As T
Return Nothing
End Function
The previous code relies on a custom VirtualizingStackPanel that exposes a method named BringIntoView . The
following code defines the custom VirtualizingStackPanel.
this.BringIndexIntoView(index);
}
}
Public Class MyVirtualizingStackPanel
Inherits VirtualizingStackPanel
''' <summary>
''' Publically expose BringIndexIntoView.
''' </summary>
Public Overloads Sub BringIntoView(ByVal index As Integer)
Me.BringIndexIntoView(index)
End Sub
End Class
The following XAML shows how to create a TreeView that uses the custom VirtualizingStackPanel.
<TreeView VirtualizingStackPanel.IsVirtualizing="True">
See Also
Improve the Performance of a TreeView
WrapPanel
5/4/2018 • 2 minutes to read • Edit Online
The WrapPanel element positions child elements in sequential position from left to right, breaking content to the
next line at the edge of its containing box.
Reference
Panel
Canvas
DockPanel
Grid
StackPanel
VirtualizingStackPanel
WrapPanel
Related Sections
Layout
Walkthrough: My first WPF desktop application
ScrollViewer Overview
Viewbox
8/31/2018 • 2 minutes to read • Edit Online
In This Section
Apply Stretch Properties to the Contents of a Viewbox
Reference
Viewbox
Image
See Also
WPF Controls Gallery Sample
How to: Apply Stretch Properties to the Contents of a
Viewbox
5/4/2018 • 2 minutes to read • Edit Online
Example
This example shows how to change the value of the StretchDirection and Stretch properties of a Viewbox.
The first example uses Extensible Application Markup Language (XAML ) to define a Viewbox element. It assigns a
MaxWidth and MaxHeight of 400. The example nests an Image element within the Viewbox. Button elements that
correspond to the property values for the Stretch and StretchDirection enumerations manipulate the stretching
behavior of the nested Image.
The following code-behind file handles the Button Click events that the previous XAML example defines.
private void stretchNone(object sender, RoutedEventArgs e)
{
vb1.Stretch = System.Windows.Media.Stretch.None;
txt1.Text = "Stretch is now set to None.";
}
vb1.Stretch = System.Windows.Media.Stretch.None
txt1.Text = "Stretch is now set to None."
End Sub
vb1.Stretch = System.Windows.Media.Stretch.Fill
txt1.Text = "Stretch is now set to Fill."
End Sub
vb1.Stretch = System.Windows.Media.Stretch.Uniform
txt1.Text = "Stretch is now set to Uniform."
End Sub
vb1.Stretch = System.Windows.Media.Stretch.UniformToFill
txt1.Text = "Stretch is now set to UniformToFill."
End Sub
vb1.StretchDirection = System.Windows.Controls.StretchDirection.UpOnly
txt2.Text = "StretchDirection is now UpOnly."
End Sub
vb1.StretchDirection = System.Windows.Controls.StretchDirection.DownOnly
txt2.Text = "StretchDirection is now DownOnly."
End Sub
vb1.StretchDirection = System.Windows.Controls.StretchDirection.Both
txt2.Text = "StretchDirection is now Both."
End Sub
See Also
Viewbox
Stretch
StretchDirection
Styles and Templates
5/4/2018 • 2 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) styling and templating refer to a suite of features (styles, templates,
triggers, and storyboards) that allow an application, document, or user interface (UI) designer to create visually
compelling applications and to standardize on a particular look for their product.
In This Section
Styling and Templating
How to: Find ControlTemplate-Generated Elements
Reference
Style
ControlTemplate
DataTemplate
Related Sections
Advanced
Control Customization
Graphics and Multimedia
Styling and Templating
5/22/2018 • 11 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) styling and templating refer to a suite of features (styles,
templates, triggers, and storyboards) that allow developers and designers to create visually compelling
effects and to create a consistent appearance for their product. Although developers and or designers can
customize the appearance extensively on an application-by-application basis, a strong styling and
templating model is necessary to allow maintenance and sharing of the appearance within and among
applications. Windows Presentation Foundation (WPF ) provides that model.
Another feature of the WPF styling model is the separation of presentation and logic. This means that
designers can work on the appearance of an application by using only XAML at the same time that
developers work on the programming logic by using C# or Visual Basic.
This overview focuses on the styling and templating aspects of the application and does not discuss any
data binding concepts. For information about data binding, see Data Binding Overview.
In addition, it is important to understand resources, which are what enable styles and templates to be
reused. For more information about resources, see XAML Resources.
This simple photo sample uses styling and templating to create a visually compelling user experience. The
sample has two TextBlock elements and a ListBox control that is bound to a list of images. For the complete
sample, see Introduction to Styling and Templating Sample.
Style Basics
You can think of a Style as a convenient way to apply a set of property values to more than one element.
For example, consider the following TextBlock elements and their default appearance:
<TextBlock>My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
You can change the default appearance by setting properties, such as FontSize and FontFamily, on each
TextBlock element directly. However, if you want your TextBlock elements to share some properties, you
can create a Style in the Resources section of your XAML file, as shown here:
<Window.Resources>
</Window.Resources>
When you set the TargetType of your style to the TextBlock type, the style is applied to all the TextBlock
elements in the window.
Now the TextBlock elements appear as follows:
Extending Styles
Perhaps you want your two TextBlock elements to share some property values, such as the FontFamily and
the centered HorizontalAlignment, but you also want the text "My Pictures" to have some additional
properties. You can do that by creating a new style that is based on the first style, as shown here:
<Window.Resources>
</Window.Resources>
Notice that the previous style is given an x:Key . To apply the style, you set the Style property on your
TextBlock to the x:Key value, as shown here:
<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
This TextBlock style now has a HorizontalAlignment value of Center, a FontFamily value of Comic Sans MS ,
a FontSize value of 26, and a Foreground value set to the LinearGradientBrush shown in the example.
Notice that it overrides the FontSize value of the base style. If there is more than one Setter setting the
same property in a Style, the Setter that is declared last takes precedence.
The following shows what the TextBlock elements now look like:
This TitleText style extends the style that has been created for the TextBlock type. You can also extend a
style that has an x:Key by using the x:Key value. For an example, see the example provided for the
BasedOn property.
Relationship of the TargetType Property and the x:Key Attribute
As shown in the first example, setting the TargetType property to TextBlock without assigning the style an
x:Key causes the style to be applied to all TextBlock elements. In this case, the x:Key is implicitly set to
{x:Type TextBlock} . This means that if you explicitly set the x:Key value to anything other than
{x:Type TextBlock} , the Style is not applied to all TextBlock elements automatically. Instead, you must
apply the style (by using the x:Key value) to the TextBlock elements explicitly. If your style is in the
resources section and you do not set the TargetType property on your style, then you must provide an
x:Key .
In addition to providing a default value for the x:Key , the TargetType property specifies the type to which
setter properties apply. If you do not specify a TargetType, you must qualify the properties in your Setter
objects with a class name by using the syntax Property="ClassName.Property" . For example, instead of
setting Property="FontSize" , you must set Property to "TextBlock.FontSize" or "Control.FontSize" .
Also note that many WPF controls consist of a combination of other WPF controls. If you create a style that
applies to all controls of a type, you might get unexpected results. For example, if you create a style that
targets the TextBlock type in a Window, the style is applied to all TextBlock controls in the window, even if
the TextBlock is part of another control, such as a ListBox.
Styles and Resources
You can use a style on any element that derives from FrameworkElement or FrameworkContentElement.
The most common way to declare a style is as a resource in the Resources section in a XAML file, as shown
in the previous examples. Because styles are resources, they obey the same scoping rules that apply to all
resources; where you declare a style affects where the style can be applied. For example, if you declare the
style in the root element of your application definition XAML file, the style can be used anywhere in your
application. If you create a navigation application and declare the style in one of the application's XAML
files, the style can be used only in that XAML file. For more information about scoping rules for resources,
see XAML Resources.
In addition, you can find more information about styles and resources in Shared Resources and Themes
later in this overview.
Setting Styles Programmatically
To assign a named style to an element programmatically, get the style from the resources collection and
assign it to the element's Style property. Note that the items in a resources collection are of type Object.
Therefore, you must cast the retrieved style to a Style before assigning it to the Style property. For example,
to set the defined TitleText style on a TextBlock named textblock1 , do the following:
textblock1.Style = (Style)(this.Resources["TitleText"]);
Note that once a style has been applied, it is sealed and cannot be changed. If you want to dynamically
change a style that has already been applied, you must create a new style to replace the existing one. For
more information, see the IsSealed property.
You can create an object that chooses a style to apply based on custom logic. For an example, see the
example provided for the StyleSelector class.
Bindings, Dynamic Resources, and Event Handlers
Note that you can use the Setter.Value property to specify a Binding Markup Extension or a
DynamicResource Markup Extension. For more information, see the examples provided for the Setter.Value
property.
So far, this overview only discusses the use of setters to set property value. You can also specify event
handlers in a style. For more information, see EventSetter.
Data Templates
In this sample application, there is a ListBox control that is bound to a list of photos:
Most controls have some type of content, and that content often comes from data that you are binding to.
In this sample, the data is the list of photos. In WPF, you use a DataTemplate to define the visual
representation of data. Basically, what you put into a DataTemplate determines what the data looks like in
the rendered application.
In our sample application, each custom Photo object has a Source property of type string that specifies
the file path of the image. Currently, the photo objects appear as file paths.
For the photos to appear as images, you create a DataTemplate as a resource:
<Window.Resources>
<!--DataTemplate to display Photos as images
instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
<Border Margin="3">
<Image Source="{Binding Source}"/>
</Border>
</DataTemplate>
</Window.Resources>
Notice that the DataType property is very similar to the TargetType property of the Style. If your
DataTemplate is in the resources section, when you specify the DataType property to a type and not assign
it an x:Key , the DataTemplate is applied whenever that type appears. You always have the option to assign
the DataTemplate with an x:Key and then set it as a StaticResource for properties that take DataTemplate
types, such as the ItemTemplate property or the ContentTemplate property.
Essentially, the DataTemplate in the above example defines that whenever there is a Photo object, it should
appear as an Image within a Border. With this DataTemplate, our application now looks like this:
The data templating model provides other features. For example, if you are displaying collection data that
contains other collections using a HeaderedItemsControl type such as a Menu or a TreeView, there is the
HierarchicalDataTemplate. Another data templating feature is the DataTemplateSelector, which allows you
to choose a DataTemplate to use based on custom logic. For more information, see Data Templating
Overview, which provides a more in-depth discussion of the different data templating features.
Control Templates
In WPF, the ControlTemplate of a control defines the appearance of the control. You can change the
structure and appearance of a control by defining a new ControlTemplate for the control. In many cases,
this gives you enough flexibility so that you do not have to write your own custom controls. For more
information, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate.
Triggers
A trigger sets properties or starts actions, such as an animation, when a property value changes or when an
event is raised. Style, ControlTemplate, and DataTemplate all have a Triggers property that can contain a
set of triggers. There are various types of triggers.
Property Triggers
A Trigger that sets property values or starts actions based on the value of a property is called a property
trigger.
To demonstrate how to use property triggers, you can make each ListBoxItem partially transparent unless it
is selected. The following style sets the Opacity value of a ListBoxItem to 0.5 . When the IsSelected
property is true , however, the Opacity is set to 1.0 :
<Style TargetType="ListBoxItem">
<Setter Property="Opacity" Value="0.5" />
<Setter Property="MaxHeight" Value="75" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Opacity" Value="1.0" />
</Trigger>
</Style.Triggers>
</Style>
This example uses a Trigger to set a property value, but note that the Trigger class also has the EnterActions
and ExitActions properties that enable a trigger to perform actions.
Notice that the MaxHeight property of the ListBoxItem is set to 75 . In the following illustration, the third
item is the selected item:
If you look at the XAML files in the sample, you will notice that the files all have the following:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>
It is the sharing of shared.xaml , which defines a ResourceDictionary that contains a set of style and brush
resources that enables the controls in the sample to have a consistent look.
For more information, see Merged Resource Dictionaries.
If you are creating a theme for you custom control, see the External Control Library section of the Control
Authoring Overview.
See Also
Pack URIs in WPF
How to: Find ControlTemplate-Generated Elements
Find DataTemplate-Generated Elements
Customizing the Appearance of an Existing
Control by Creating a ControlTemplate
8/31/2018 • 22 minutes to read • Edit Online
A ControlTemplate specifies the visual structure and visual behavior of a control. You can customize the
appearance of a control by giving it a new ControlTemplate. When you create a ControlTemplate, you
replace the appearance of an existing control without changing its functionality. For example, you can
make the buttons in your application round instead of the default square shape, but the button will still
raise the Click event.
This topic explains the various parts of a ControlTemplate, demonstrates creating a simple
ControlTemplate for a Button, and explains how to understand the control contract of a control so that
you can customize its appearance. Because you create a ControlTemplate in XAML, you can change a
control's appearance without writing any code. You can also use a designer, such as Microsoft Expression
Blend, to create custom control templates. This topic shows examples in the XAML that customize the
appearance of a Button and lists the complete example at the end of the topic. For more information
about using Expression Blend, see Styling a control that supports templates.
The following illustrations show a Button that uses the ControlTemplate that is created in this topic.
A button that uses a custom control template and has the mouse pointer over it
Prerequisites
This topic assumes that you understand how to create and use controls and styles as discussed in
Controls. The concepts discussed in this topic apply to elements that inherit from the Control class, except
for the UserControl. You cannot apply a ControlTemplate to a UserControl.
</Border>
</ControlTemplate>
In this example, the Grid has its Panel.Background property template bound to Control.Background.
Because Panel.Background is template bound, you can create multiple buttons that use the same
ControlTemplate and set the Control.Background to different values on each button. If
Control.Background was not template bound to a property of an element in the ControlTemplate, setting
the Control.Background of a button would have no impact on the button's appearance.
Note that the names of the two properties do not need to be identical. In the preceding example, the
Control.HorizontalContentAlignment property of the Button is template bound to the
FrameworkElement.HorizontalAlignment property of the ContentPresenter. This enables the content of
the button to be positioned horizontally. ContentPresenter does not have a property named
HorizontalContentAlignment , but Control.HorizontalContentAlignment can be bound to
FrameworkElement.HorizontalAlignment. When you template bind a property, be sure that the target and
source properties are the same type.
The Control class defines several properties that must be used by the control template to have an effect
on the control when they are set. How the ControlTemplate uses the property depends on the property.
The ControlTemplate must use the property in one of the following ways:
An element in the ControlTemplate template binds to the property.
An element in the ControlTemplate inherits the property from a parent FrameworkElement.
The following table lists the visual properties inherited by a control from the Control class. It also
indicates whether the default control template of a control uses the inherited property value or if it must
be template bound.
The table lists only the visual properties inherited from the Control class. Apart from the properties listed
in the table, a control may also inherit the DataContext, Language, and TextDecorations properties from
the parent framework element.
Also, if the ContentPresenter is in the ControlTemplate of a ContentControl, the ContentPresenter will
automatically bind to the ContentTemplate and Content properties. Likewise, an ItemsPresenter that is in
the ControlTemplate of an ItemsControl will automatically bind to the Items and ItemsPresenter
properties.
The following example creates two buttons that use the ControlTemplate defined in the preceding
example. The example sets the Background, Foreground, and FontSize properties on each button. Setting
the Background property has an effect because it is template bound in the ControlTemplate. Even though
the Foreground and FontSize properties are not template bound, setting them has an effect because their
values are inherited.
<StackPanel>
<Button Style="{StaticResource newTemplate}"
Background="Navy" Foreground="White" FontSize="14"
Content="Button1"/>
The preceding example produces output that is similar to the following illustration.
</Storyboard>
</VisualState>
The control is responsible for defining the states as part of its control contract, which is discussed in detail
in Customizing Other Controls by Understanding the Control Contract later in this topic. The following
table lists the states that are specified for the Button.
VISUALSTATE NAME VISUALSTATEGROUP NAME DESCRIPTION
The Button defines two state groups: the CommonStates group contains the Normal , MouseOver , Pressed ,
and Disabled states. The FocusStates group contains the Focused and Unfocused states. States in the
same state group are mutually exclusive. The control is always in exactly one state per group. For example,
a Button can have focus even when the mouse pointer is not over it, so a Button in the Focused state can
be in the MouseOver , Pressed , or Normal state.
You add VisualState objects to VisualStateGroup objects. You add VisualStateGroup objects to the
VisualStateGroups attached property. The following example defines the VisualState objects for the
Normal , MouseOver , and Pressed states, which are all in the CommonStates group. The Name of each
VisualState matches the name in the preceding table. The Disabled state and the states in the
FocusStates group are omitted to keep the example short, but they are included in the entire example at
the end of this topic.
NOTE
Be sure to set the VisualStateGroups attached property on the root FrameworkElement of the ControlTemplate.
<ControlTemplate TargetType="Button">
<Border Name="RootElement">
<VisualStateManager.VisualStateGroups>
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Black"/>
</Border.Background>
The preceding example produces output that is similar to the following illustrations.
A button that uses a custom control template in the mouse over state
<ColorAnimationUsingKeyFrames.KeyFrames>
<LinearColorKeyFrame Value="Blue"
KeyTime="0:0:0.5" />
<LinearColorKeyFrame Value="Yellow"
KeyTime="0:0:1" />
<LinearColorKeyFrame Value="Black"
KeyTime="0:0:1.5" />
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
From a specified state to another The name of a VisualState The name of a VisualState
specified state
From any state to a specified state Not set The name of a VisualState
From a specified state to any state The name of a VisualState Not set
From any state to any other state Not set Not set
You can have multiple VisualTransition objects in a VisualStateGroup that refer to the same state, but they
will be used in the order that the previous table specifies. In the following example, there are two
VisualTransition objects. When the control transitions from the Pressed state to the MouseOver state, the
VisualTransition that has both From and To set is used. When the control transitions from a state that is
not Pressed to the MouseOver state, the other state is used.
<!--Take one half second to trasition to the MouseOver state.-->
<VisualTransition To="MouseOver"
GeneratedDuration="0:0:0.5" />
The VisualStateGroup has a Transitions property that contains the VisualTransition objects that apply to
the VisualState objects in the VisualStateGroup. As the ControlTemplate author, you are free to include
any VisualTransition you want. However, if the To and From properties are set to state names that are not
in the VisualStateGroup, the VisualTransition is ignored.
The following example shows the VisualStateGroup for the CommonStates . The example defines a
VisualTransition for each of the button's following transitions.
To the Pressed state.
To the MouseOver state.
From the Pressed state to the MouseOver state.
From the MouseOver state to the Normal state.
<VisualStateGroup x:Name="CommonStates">
<ColorAnimationUsingKeyFrames.KeyFrames>
<LinearColorKeyFrame Value="Blue"
KeyTime="0:0:0.5" />
<LinearColorKeyFrame Value="Yellow"
KeyTime="0:0:1" />
<LinearColorKeyFrame Value="Black"
KeyTime="0:0:1.5" />
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation
Storyboard.TargetName="BorderBrush"
Storyboard.TargetProperty="Color"
To="Red" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation
Storyboard.TargetName="BorderBrush"
Storyboard.TargetProperty="Color"
To="Transparent"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<TemplatePartAttribute(Name:="PART_EditableTextBox", Type:=GetType(TextBox))> _
<TemplatePartAttribute(Name:="Part_Popup", Type:=GetType(Popup))> _
Public Class ComboBox
Inherits ItemsControl
End Class
The following example shows a simplified ControlTemplate for the ComboBox that includes the elements
that are specified by the TemplatePartAttribute objects on the ComboBox class.
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton x:Name="DropDownToggle"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="-1" HorizontalContentAlignment="Right"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}">
<Path x:Name="BtnArrow" Height="4" Width="8"
Stretch="Uniform" Margin="0,0,6,0" Fill="Black"
Data="F1 M 300,-190L 310,-190L 305,-183L 301,-190 Z " />
</ToggleButton>
<ContentPresenter x:Name="ContentPresenter" Margin="6,2,25,2"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}">
</ContentPresenter>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Focusable="False"
Background="{TemplateBinding Background}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup x:Name="PART_Popup"
IsOpen="{TemplateBinding IsDropDownOpen}">
<Border x:Name="PopupBorder"
HorizontalAlignment="Stretch" Height="Auto"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Black" Background="White" CornerRadius="3">
<ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</ControlTemplate>
States in the Control Contract
The states of a control are also a part of the control contract. The example of creating a ControlTemplate
for a Button shows how to specify the appearance of a Button depending on its states. You create a
VisualState for each specified state and put all VisualState objects that share a GroupName in a
VisualStateGroup, as described in Changing the Appearance of a Control Depending on Its State earlier in
this topic. Third-party controls should specify states by using the TemplateVisualStateAttribute, which
enables designer tools, such as Expression Blend, to expose the control's states for authoring control
templates.
To find the control contract for controls that are included with WPF, see Control Styles and Templates.
Properties in the Control Contract
The public properties that visually affect the control are also included in the control contract. You can set
these properties to change the appearance of the control without creating a new ControlTemplate. You
can also use the TemplateBinding markup extension to bind properties of elements that are in the
ControlTemplate to public properties that are defined by the Button.
The following example shows the control contract for the button.
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
public class Button : ButtonBase
{
public static readonly DependencyProperty BackgroundProperty;
public static readonly DependencyProperty BorderBrushProperty;
public static readonly DependencyProperty BorderThicknessProperty;
public static readonly DependencyProperty ContentProperty;
public static readonly DependencyProperty ContentTemplateProperty;
public static readonly DependencyProperty FontFamilyProperty;
public static readonly DependencyProperty FontSizeProperty;
public static readonly DependencyProperty FontStretchProperty;
public static readonly DependencyProperty FontStyleProperty;
public static readonly DependencyProperty FontWeightProperty;
public static readonly DependencyProperty ForegroundProperty;
public static readonly DependencyProperty HorizontalContentAlignmentProperty;
public static readonly DependencyProperty PaddingProperty;
public static readonly DependencyProperty TextAlignmentProperty;
public static readonly DependencyProperty TextDecorationsProperty;
public static readonly DependencyProperty TextWrappingProperty;
public static readonly DependencyProperty VerticalContentAlignmentProperty;
When creating a ControlTemplate, it is often easiest to begin with an existing ControlTemplate and make
changes to it. You can do one of the following to change an existing ControlTemplate:
Use a designer, such as Expression Blend, which provides a graphical user interface for creating
control templates. For more information, see Styling a control that supports templates.
Get the default ControlTemplate and edit it. To find the default control templates that are included
with WPF, see Default WPF Themes.
Complete Example
The following example shows the complete ButtonControlTemplate that is discussed in this topic.
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button" x:Key="newTemplate">
<!--Set the Background, Foreground, FontSize, Width,
Height, Margin, and Template properties for
the Button.-->
<Setter Property="Background" Value="Navy"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="RootElement">
<VisualStateManager.VisualStateGroups>
<ColorAnimationUsingKeyFrames.KeyFrames>
<LinearColorKeyFrame Value="Blue"
KeyTime="0:0:0.5" />
<LinearColorKeyFrame Value="Yellow"
KeyTime="0:0:1" />
<LinearColorKeyFrame Value="Black"
KeyTime="0:0:1.5" />
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
</Storyboard>
</VisualState>
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="FocusVisual"
Storyboard.TargetProperty="Visibility"
Duration="0">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</StackPanel.Resources>
See Also
Styling and Templating
How to: Find ControlTemplate-Generated Elements
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to find elements that are generated by a ControlTemplate.
Example
The following example shows a style that creates a simple ControlTemplate for the Button class:
To find an element within the template after the template has been applied, you can call the FindName method of
the Template. The following example creates a message box that shows the actual width value of the Grid within
the control template:
' Finding the grid that is generated by the ControlTemplate of the Button
Dim gridInTemplate As Grid = CType(myButton1.Template.FindName("grid", myButton1), Grid)
See Also
Find DataTemplate-Generated Elements
Styling and Templating
WPF XAML Namescopes
Trees in WPF
Control Customization
5/4/2018 • 2 minutes to read • Edit Online
This category covers the various base classes, interfaces and other elements and concepts used in creating a
fully functional Windows Presentation Foundation (WPF ) control.
In This Section
Control Authoring Overview
Guidelines for Designing Stylable Controls
Adorners
Control Styles and Templates
UI Automation of a WPF Custom Control
See Also
Styling and Templating
Control Authoring Overview
8/31/2018 • 21 minutes to read • Edit Online
The extensibility of the Windows Presentation Foundation (WPF ) control model greatly reduces the need to create
a new control. However, in certain cases you may still need to create a custom control. This topic discusses the
features that minimize your need to create a custom control and the different control authoring models in
Windows Presentation Foundation (WPF ). This topic also demonstrates how to create a new control.
Triggers. A Trigger allows you to dynamically change the appearance and behavior of a control without
creating a new control. For example, suppose you have multiple ListBox controls in your application and
want the items in each ListBox to be bold and red when they are selected. Your first instinct might be to
create a class that inherits from ListBox and override the OnSelectionChanged method to change the
appearance of the selected item, but a better approach is to add a trigger to a style of a ListBoxItem that
changes the appearance of the selected item. A trigger enables you to change property values or take
actions based on the value of a property. An EventTrigger enables you to take actions when an event occurs.
For more information about styles, templates, and triggers, see Styling and Templating.
In general, if your control mirrors the functionality of an existing control, but you want the control to look different,
you should first consider whether you can use any of the methods discussed in this section to change the existing
control's appearance.
/// <summary>
/// Gets or sets the value assigned to the control.
/// </summary>
public decimal Value
{
get { return (decimal)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
return newValue;
}
''' <summary>
''' Gets or sets the value assigned to the control.
''' </summary>
Public Property Value() As Decimal
Get
Return CDec(GetValue(ValueProperty))
End Get
Set(ByVal value As Decimal)
SetValue(ValueProperty, value)
End Set
End Property
Private Shared Overloads Function CoerceValue(ByVal element As DependencyObject, ByVal value As Object) As
Object
Dim newValue As Decimal = CDec(value)
Dim control As NumericUpDown = CType(element, NumericUpDown)
Return newValue
End Function
/// <summary>
/// Identifies the ValueChanged routed event.
/// </summary>
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
"ValueChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<decimal>), typeof(NumericUpDown));
/// <summary>
/// Occurs when the Value property changes.
/// </summary>
public event RoutedPropertyChangedEventHandler<decimal> ValueChanged
{
add { AddHandler(ValueChangedEvent, value); }
remove { RemoveHandler(ValueChangedEvent, value); }
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="args">Arguments associated with the ValueChanged event.</param>
protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs<decimal> args)
{
RaiseEvent(args);
}
''' <summary>
''' Identifies the ValueChanged routed event.
''' </summary>
Public Shared ReadOnly ValueChangedEvent As RoutedEvent = EventManager.RegisterRoutedEvent("ValueChanged",
RoutingStrategy.Bubble, GetType(RoutedPropertyChangedEventHandler(Of Decimal)), GetType(NumericUpDown))
''' <summary>
''' Occurs when the Value property changes.
''' </summary>
Public Custom Event ValueChanged As RoutedPropertyChangedEventHandler(Of Decimal)
AddHandler(ByVal value As RoutedPropertyChangedEventHandler(Of Decimal))
MyBase.AddHandler(ValueChangedEvent, value)
End AddHandler
RemoveHandler(ByVal value As RoutedPropertyChangedEventHandler(Of Decimal))
MyBase.RemoveHandler(ValueChangedEvent, value)
End RemoveHandler
RaiseEvent(ByVal sender As System.Object, ByVal e As RoutedPropertyChangedEventArgs(Of Decimal))
End RaiseEvent
End Event
''' <summary>
''' Raises the ValueChanged event.
''' </summary>
''' <param name="args">Arguments associated with the ValueChanged event.</param>
Protected Overridable Sub OnValueChanged(ByVal args As RoutedPropertyChangedEventArgs(Of Decimal))
MyBase.RaiseEvent(args)
End Sub
For more information, see Routed Events Overview and Create a Custom Routed Event.
Use Binding
To decouple the UI of your control from its logic, consider using data binding. This is particularly important if you
define the appearance of your control by using a ControlTemplate. When you use data binding, you might be able
to eliminate the need to reference specific parts of the UI from the code. It's a good idea to avoid referencing
elements that are in the ControlTemplate because when the code references elements that are in the
ControlTemplate and the ControlTemplate is changed, the referenced element needs to be included in the new
ControlTemplate.
The following example updates the TextBlock of the NumericUpDown control, assigning a name to it and referencing
the textbox by name in code.
</Border>
For more information about data binding, see Data Binding Overview.
Design for Designers
To receive support for custom WPF controls in the WPF Designer for Visual Studio (for example, property editing
with the Properties window ), follow these guidelines. For more information on developing for the WPF Designer,
see Design XAML in Visual Studio.
Dependency Properties
Be sure to implement CLR get and set accessors as described earlier, in "Use Dependency Properties."
Designers may use the wrapper to detect the presence of a dependency property, but they, like WPF and clients of
the control, are not required to call the accessors when getting or setting the property.
Attached Properties
You should implement attached properties on custom controls using the following guidelines:
Have a public static readonly DependencyProperty of the form PropertyName Property that was
creating using the RegisterAttached method. The property name that is passed to RegisterAttached must
match PropertyName.
Implement a pair of public static CLR methods named Set PropertyName and Get PropertyName.
Both methods should accept a class derived from DependencyProperty as their first argument. The Set
PropertyName method also accepts an argument whose type matches the registered data type for the
property. The Get PropertyName method should return a value of the same type. If the Set
PropertyName method is missing, the property is marked read-only.
Set PropertyName and Get PropertyName must route directly to the GetValue and SetValue methods on
the target dependency object, respectively. Designers may access the attached property by calling through
the method wrapper or making a direct call to the target dependency object.
For more information on attached properties, see Attached Properties Overview.
Define and Use Shared Resources
You can include your control in the same assembly as your application, or you can package your control in a
separate assembly that can be used in multiple applications. For the most part, the information discussed in this
topic applies regardless of the method you use. There is one difference worth noting, however. When you put a
control in the same assembly as an application, you are free to add global resources to the App.xaml file. But an
assembly that contains only controls does not have an Application object associated with it, so an App.xaml file is
not available.
When an application looks for a resource, it looks at three levels in the following order:
1. The element level.
The system starts with the element that references the resource and then searches resources of the logical
parent and so forth until the root element is reached.
2. The application level.
Resources defined by the Application object.
3. The theme level.
Theme-level dictionaries are stored in a subfolder named Themes. The files in the Themes folder
correspond to themes. For example, you might have Aero.NormalColor.xaml, Luna.NormalColor.xaml,
Royale.NormalColor.xaml, and so on. You can also have a file named generic.xaml. When the system looks
for a resource at the themes level, it first looks for it in the theme-specific file and then looks for it in
generic.xaml.
When your control is in an assembly that is separate from the application, you must put your global resources at
the element level or at the theme level. Both methods have their advantages.
Defining Resources at the Element Level
You can define shared resources at the element level by creating a custom resource dictionary and merging it with
your control’s resource dictionary. When you use this method, you can name your resource file anything you want,
and it can be in the same folder as your controls. Resources at the element level can also use simple strings as
keys. The following example creates a LinearGradientBrush resource file named Dictionary1.xaml.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<LinearGradientBrush
x:Key="myBrush"
StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
</LinearGradientBrush>
</ResourceDictionary>
Once you have defined your dictionary, you need to merge it with your control's resource dictionary. You can do
this by using XAML or code.
The following example merges a resource dictionary by using XAML.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
The disadvantage to this approach is that a ResourceDictionary object is created each time you reference it. For
example, if you have 10 custom controls in your library and merge the shared resource dictionaries for each
control by using XAML, you create 10 identical ResourceDictionary objects. You can avoid this by creating a static
class that merges the resources in code and returns the resulting ResourceDictionary.
The following example creates a class that returns a shared ResourceDictionary.
internal static class SharedDictionaryManager
{
internal static ResourceDictionary SharedDictionary
{
get
{
if (_sharedDictionary == null)
{
System.Uri resourceLocater =
new System.Uri("/ElementResourcesCustomControlLibrary;component/Dictionary1.xaml",
System.UriKind.Relative);
_sharedDictionary =
(ResourceDictionary)Application.LoadComponent(resourceLocater);
}
return _sharedDictionary;
}
}
The following example merges the shared resource with the resources of a custom control in the control's
constructor before it calls InitializeComponent . Because the SharedDictionaryManager.SharedDictionary is a static
property, the ResourceDictionary is created only once. Because the resource dictionary was merged before
InitializeComponent was called, the resources are available to the control in its XAML file.
public NumericUpDown()
{
this.Resources.MergedDictionaries.Add(SharedDictionaryManager.SharedDictionary);
InitializeComponent();
You do not need to define a resource for every theme. If a resource is not defined for a specific theme, then the
control checks Classic.xaml for the resource. If the resource is not defined in the file that corresponds to the
current theme or in Classic.xaml , the control uses the generic resource, which is in a resource dictionary file
named generic.xaml . The generic.xaml file is located in the same folder as the theme-specific resource
dictionary files. Although generic.xaml does not correspond to a specific Windows theme, it is still a theme-level
dictionary.
NumericUpDown Custom Control with Theme and UI Automation Support Sample contains two resource
dictionaries for the NumericUpDown control: one is in generic.xaml and one is in Luna.NormalColor.xaml. You can
run the application and switch between the Silver theme in Windows XP and another theme to see the difference
between the two control templates. (If you are running Windows Vista, you can rename Luna.NormalColor.xaml
to Aero.NormalColor.xaml and switch between two themes, such as Windows Classic and the default theme for
Windows Vista.)
When you put a ControlTemplate in any of the theme-specific resource dictionary files, you must create a static
constructor for your control and call the OverrideMetadata(Type, PropertyMetadata) method on the
DefaultStyleKey, as shown in the following example.
static NumericUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown),
new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}
D e fi n i n g a n d R e fe r e n c i n g K e y s fo r T h e m e R e so u r c e s
When you define a resource at the element level, you can assign a string as its key and access the resource via the
string. When you define a resource at the theme level, you must use a ComponentResourceKey as the key. The
following example defines a resource in generic.xaml.
<LinearGradientBrush
x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:Painter},
ResourceId=MyEllipseBrush}"
StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Red" Offset="0.5" />
<GradientStop Color="Green" Offset="1"/>
</LinearGradientBrush>
The following example references the resource by specifying the ComponentResourceKey as the key.
<RepeatButton
Grid.Column="1" Grid.Row="0"
Background="{StaticResource {ComponentResourceKey
TypeInTargetAssembly={x:Type local:NumericUpDown},
ResourceId=ButtonBrush}}">
Up
</RepeatButton>
<RepeatButton
Grid.Column="1" Grid.Row="1"
Background="{StaticResource {ComponentResourceKey
TypeInTargetAssembly={x:Type local:NumericUpDown},
ResourceId=ButtonBrush}}">
Down
</RepeatButton>
Sp e c i fy i n g t h e L o c a t i o n o f T h e m e R e so u r c e s
To find the resources for a control, the hosting application needs to know that the assembly contains control-
specific resources. You can accomplish that by adding the ThemeInfoAttribute to the assembly that contains the
control. The ThemeInfoAttribute has a GenericDictionaryLocation property that specifies the location of generic
resources, and a ThemeDictionaryLocation property that specifies the location of the theme-specific resources.
The following example sets the GenericDictionaryLocation and ThemeDictionaryLocation properties to
SourceAssembly, to specify that the generic and theme-specific resources are in the same assembly as the control.
[assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly,
ResourceDictionaryLocation.SourceAssembly)]
See Also
Design XAML in Visual Studio
Pack URIs in WPF
Control Customization
Creating a Control That Has a Customizable
Appearance
5/4/2018 • 24 minutes to read • Edit Online
Windows Presentation Foundation (WPF ) gives you the ability to create a control whose appearance can be
customized. For example, you can change the appearance of a CheckBox beyond what setting properties will do by
creating a new ControlTemplate. The following illustration shows a CheckBox that uses a default ControlTemplate
and a CheckBox that uses a custom ControlTemplate.
Prerequisites
This topic assumes that you know how to create a new ControlTemplate for an existing control, are familiar with
what the elements on a control contract are, and understand the concepts discussed in Customizing the
Appearance of an Existing Control by Creating a ControlTemplate.
NOTE
To create a control that can have its appearance customized, you must create a control that inherits from the Control class or
one of its subclasses other than UserControl. A control that inherits from UserControl is a control that can be quickly created,
but it does not use a ControlTemplate and you cannot customize its appearance.
</Grid>
</ControlTemplate>
A visual behavior of the NumericUpDown control is that the value is in a red font if it is negative. If you change the
Foreground of the TextBlock in code when the Value is negative, the NumericUpDown will always show a red
negative value. You specify the visual behavior of the control in the ControlTemplate by adding VisualState objects
to the ControlTemplate. The following example shows the VisualState objects for the Positive and Negative
states. Positive and Negative are mutually exclusive (the control is always in exactly one of the two), so the
example puts the VisualState objects into a single VisualStateGroup. When the control goes into the Negative
state, the Foreground of the TextBlock turns red. When the control is in the Positive state, the Foreground returns
to it original value. Defining VisualState objects in a ControlTemplate is further discussed in Customizing the
Appearance of an Existing Control by Creating a ControlTemplate.
NOTE
Be sure to set the VisualStateGroups attached property on the root FrameworkElement of the ControlTemplate.
<ControlTemplate TargetType="local:NumericUpDown">
<Grid Margin="3"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValueStates">
</VisualState>
set
{
if (upButtonElement != null)
{
upButtonElement.Click -=
new RoutedEventHandler(upButtonElement_Click);
}
upButtonElement = value;
if (upButtonElement != null)
{
upButtonElement.Click +=
new RoutedEventHandler(upButtonElement_Click);
}
}
}
The following example shows the OnApplyTemplate for the NumericUpDown control. The example uses the
GetTemplateChild method to get the FrameworkElement objects from the ControlTemplate. Notice that the
example guards against cases where GetTemplateChild finds a FrameworkElement with the specified name that is
not of the expected type. It is also a best practice to ignore elements that have the specified x:Name but are of the
wrong type.
public override void OnApplyTemplate()
{
UpButtonElement = GetTemplateChild("UpButton") as RepeatButton;
DownButtonElement = GetTemplateChild("DownButton") as RepeatButton;
//TextElement = GetTemplateChild("TextBlock") as TextBlock;
UpdateStates(false);
}
UpdateStates(False)
End Sub
By following the practices that are shown in the previous examples, you ensure that your control will continue to
run when the ControlTemplate is missing a FrameworkElement.
Use the VisualStateManager to Manage States
The VisualStateManager keeps track of the states of a control and performs the logic necessary to transition
between states. When you add VisualState objects to the ControlTemplate, you add them to a VisualStateGroup
and add the VisualStateGroup to the VisualStateGroups attached property so that the VisualStateManager has
access to them.
The following example repeats the previous example that shows the VisualState objects that corresponds to the
Positive and Negative states of the control. The Storyboard in the Negative VisualState turns the Foreground of
the TextBlock red. When the NumericUpDown control is in the Negative state, the storyboard in the Negative state
begins. Then the Storyboard in the Negative state stops when the control returns to the Positive state. The
Positive VisualState does not need to contain a Storyboard because when the Storyboard for the Negative stops,
the Foreground returns to its original color.
<ControlTemplate TargetType="local:NumericUpDown">
<Grid Margin="3"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValueStates">
</VisualState>
Note that the TextBlock is given a name, but the TextBlock is not in the control contract for NumericUpDown because
the control's logic never references the TextBlock. Elements that are referenced in the ControlTemplate have names,
but do not need to be part of the control contract because a new ControlTemplate for the control might not need to
reference that element. For example, someone who creates a new ControlTemplate for NumericUpDown might decide
to not indicate that Value is negative by changing the Foreground. In that case, neither the code nor the
ControlTemplate references the TextBlock by name.
The control's logic is responsible for changing the control's state. The following example shows that the
NumericUpDown control calls the GoToState method to go into the Positive state when Value is 0 or greater, and
the Negative state when Value is less than 0.
if (Value >= 0)
{
VisualStateManager.GoToState(this, "Positive", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Negative", useTransitions);
}
The GoToState method performs the logic necessary to start and stop the storyboards appropriately. When a
control calls GoToState to change its state, the VisualStateManager does the following:
If the VisualState that the control is going to has a Storyboard, the storyboard begins. Then, if the
VisualState that the control is coming from has a Storyboard, the storyboard ends.
If the control is already in the state that is specified, GoToState takes no action and returns true .
If state that is specified doesn't exist in the ControlTemplate of control , GoToState takes no action and
returns false .
Best Practices for Working with the VisualStateManager
It is recommended that you do the following to maintain your control's states:
Use properties to track its state.
Create a helper method to transition between states.
The NumericUpDown control uses its Value property to track whether it is in the Positive or Negative state. The
NumericUpDown control also defines the Focused and UnFocused states, which tracks the IsFocused property. If you
use states that do not naturally correspond to a property of the control, you can define a private property to track
the state.
A single method that updates all the states centralizes calls to the VisualStateManager and keeps your code
manageable. The following example shows the NumericUpDown control's helper method, UpdateStates . When
Value is greater than or equal to 0, the Control is in the Positive state. When Value is less than 0, the control is
in the Negative state. When IsFocused is true , the control is in the Focused state; otherwise, it is in the
Unfocused state. The control can call UpdateStates whenever it needs to change its state, regardless of what state
changes.
private void UpdateStates(bool useTransitions)
{
if (Value >= 0)
{
VisualStateManager.GoToState(this, "Positive", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Negative", useTransitions);
}
if (IsFocused)
{
VisualStateManager.GoToState(this, "Focused", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Unfocused", useTransitions);
}
}
If IsFocused Then
VisualStateManager.GoToState(Me, "Focused", useTransitions)
Else
VisualStateManager.GoToState(Me, "Unfocused", useTransitions)
End If
End Sub
If you pass a state name to GoToState when the control is already in that state, GoToState does nothing, so you
don't need to check for the control's current state. For example, if Value changes from one negative number to
another negative number, the storyboard for the Negative state is not interrupted and the user will not see a
change in the control.
The VisualStateManager uses VisualStateGroup objects to determine which state to exit when you call GoToState.
The control is always in one state for each VisualStateGroup that is defined in its ControlTemplate and only leaves
a state when it goes into another state from the same VisualStateGroup. For example, the ControlTemplate of the
NumericUpDown control defines the Positive and Negative VisualState objects in one VisualStateGroup and the
Focused and Unfocused VisualState objects in another. ( You can see the Focused and Unfocused VisualState
defined in the Complete Example section in this topic When the control goes from the Positive state to the
Negative state, or vice versa, the control remains in either the Focused or Unfocused state.
There are three typical places where the state of a control might change:
When the ControlTemplate is applied to the Control.
When a property changes.
When an event occurs.
The following examples demonstrate updating the state of the NumericUpDown control in these cases.
You should update the state of the control in the OnApplyTemplate method so that the control appears in the
correct state when the ControlTemplate is applied. The following example calls UpdateStates in OnApplyTemplate
to ensure that the control is in the appropriate states. For example, suppose that you create a NumericUpDown
control, and then set its Foreground to green and Value to -5. If you do not call UpdateStates when the
ControlTemplate is applied to the NumericUpDown control, the control is not in the Negative state and the value is
green instead of red. You must call UpdateStates to put the control in the Negative state.
UpdateStates(false);
}
UpdateStates(False)
End Sub
You often need to update the states of a control when a property changes. The following example shows the entire
ValueChangedCallback method. Because ValueChangedCallback is called when Value changes, the method calls
UpdateStates in case Value changed from positive to negative or vice versa. It is acceptable to call UpdateStates
when Value changes but remains positive or negative because in that case, the control will not change states.
' Call UpdateStates because the Value might have caused the
' control to change ValueStates.
ctl.UpdateStates(True)
The VisualStateManager helps you manage your control's states. By using the VisualStateManager, you ensure
that your control correctly transitions between states. If you follow the recommendations described in this section
for working with the VisualStateManager, your control's code will remain readable and maintainable.
Negative
Unfocused
To specify what FrameworkElement objects the control expects, you use the TemplatePartAttribute, which specifies
the name and type of the expected elements. To specify the possible states of a control, you use the
TemplateVisualStateAttribute, which specifies the state's name and which VisualStateGroup it belongs to. Put the
TemplatePartAttribute and TemplateVisualStateAttribute on the class definition of the control.
Any public property that affects the appearance of your control is also a part of the control contract.
The following example specifies the FrameworkElement object and states for the NumericUpDown control.
<TemplatePart(Name:="UpButtonElement", Type:=GetType(RepeatButton))> _
<TemplatePart(Name:="DownButtonElement", Type:=GetType(RepeatButton))> _
<TemplateVisualState(Name:="Positive", GroupName:="ValueStates")> _
<TemplateVisualState(Name:="Negative", GroupName:="ValueStates")> _
<TemplateVisualState(Name:="Focused", GroupName:="FocusedStates")> _
<TemplateVisualState(Name:="Unfocused", GroupName:="FocusedStates")> _
Public Class NumericUpDown
Inherits Control
Public Shared ReadOnly BackgroundProperty As DependencyProperty
Public Shared ReadOnly BorderBrushProperty As DependencyProperty
Public Shared ReadOnly BorderThicknessProperty As DependencyProperty
Public Shared ReadOnly FontFamilyProperty As DependencyProperty
Public Shared ReadOnly FontSizeProperty As DependencyProperty
Public Shared ReadOnly FontStretchProperty As DependencyProperty
Public Shared ReadOnly FontStyleProperty As DependencyProperty
Public Shared ReadOnly FontWeightProperty As DependencyProperty
Public Shared ReadOnly ForegroundProperty As DependencyProperty
Public Shared ReadOnly HorizontalContentAlignmentProperty As DependencyProperty
Public Shared ReadOnly PaddingProperty As DependencyProperty
Public Shared ReadOnly TextAlignmentProperty As DependencyProperty
Public Shared ReadOnly TextDecorationsProperty As DependencyProperty
Public Shared ReadOnly TextWrappingProperty As DependencyProperty
Public Shared ReadOnly VerticalContentAlignmentProperty As DependencyProperty
Complete Example
The following example is the entire ControlTemplate for the NumericUpDown control.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValueStates">
</VisualState>
<VisualStateGroup Name="FocusStates">
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace VSMCustomControl
{
[TemplatePart(Name = "UpButtonElement", Type = typeof(RepeatButton))]
[TemplatePart(Name = "UpButtonElement", Type = typeof(RepeatButton))]
[TemplatePart(Name = "DownButtonElement", Type = typeof(RepeatButton))]
[TemplateVisualState(Name = "Positive", GroupName = "ValueStates")]
[TemplateVisualState(Name = "Negative", GroupName = "ValueStates")]
[TemplateVisualState(Name = "Focused", GroupName = "FocusedStates")]
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusedStates")]
public class NumericUpDown : Control
{
public NumericUpDown()
{
DefaultStyleKey = typeof(NumericUpDown);
this.IsTabStop = true;
}
set
{
SetValue(ValueProperty, value);
}
}
if (IsFocused)
{
VisualStateManager.GoToState(this, "Focused", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Unfocused", useTransitions);
}
}
UpdateStates(false);
}
set
{
if (downButtonElement != null)
{
downButtonElement.Click -=
new RoutedEventHandler(downButtonElement_Click);
}
downButtonElement = value;
if (downButtonElement != null)
{
downButtonElement.Click +=
new RoutedEventHandler(downButtonElement_Click);
}
}
}
if (upButtonElement != null)
{
upButtonElement.Click +=
new RoutedEventHandler(upButtonElement_Click);
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Controls.Primitives
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media
<TemplatePart(Name:="UpButtonElement", Type:=GetType(RepeatButton))> _
<TemplatePart(Name:="DownButtonElement", Type:=GetType(RepeatButton))> _
<TemplateVisualState(Name:="Positive", GroupName:="ValueStates")> _
<TemplateVisualState(Name:="Negative", GroupName:="ValueStates")> _
<TemplateVisualState(Name:="Focused", GroupName:="FocusedStates")> _
<TemplateVisualState(Name:="Unfocused", GroupName:="FocusedStates")> _
Public Class NumericUpDown
Inherits Control
Get
Return CInt(GetValue(ValueProperty))
End Get
SetValue(ValueProperty, value)
End Set
End Property
' Call UpdateStates because the Value might have caused the
' control to change ValueStates.
ctl.UpdateStates(True)
End Event
#Region "NUDCode"
Private Sub UpdateStates(ByVal useTransitions As Boolean)
If IsFocused Then
VisualStateManager.GoToState(Me, "Focused", useTransitions)
Else
VisualStateManager.GoToState(Me, "Unfocused", useTransitions)
End If
End Sub
UpdateStates(False)
End Sub
_value = num
RoutedEvent = id
End Sub
See Also
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Control Customization
Guidelines for Designing Stylable Controls
5/4/2018 • 8 minutes to read • Edit Online
This document summarizes a set of best practices to consider when designing a control which you intend to be
easily stylable and templatable. We came to this set of best practices through a lot of trial and error while working
on the theme control styles for the built-in WPF control set. We learned that successful styling is as much a
function of a well-designed object model as it is of the style itself. The intended audience for this document is the
control author, not the style author.
Terminology
"Styling and templating" refer to the suite of technologies that enable a control author to defer the visual aspects of
the control to the style and template of the control. This suite of technologies includes:
Styles (including property setters, triggers, and storyboards).
Resources.
Control templates.
Data templates.
For an introduction to styling and templating, see Styling and Templating.
General Guidelines
Do not strictly enforce template contracts. The template contract of a control might consist of elements,
commands, bindings, triggers, or even property settings that are required or expected for a control to
function properly.
Minimize contracts as much as possible.
Design around the expectation that during design time (that is, when using a design tool) it is
common for a control template to be in an incomplete state. WPF does not offer a "composing" state
infrastructure, so controls have to be built with the expectation that such a state might be valid.
Do not throw exceptions when any aspect of a template contract is not followed. Along these lines,
panels should not throw exceptions if they have too many or too few children.
Factor peripheral functionality into template helper elements. Each control should be focused on its
core functionality and true value proposition and defined by the control's common usage. To that end, use
composition and helper elements within the template to enable peripheral behaviors and visualizations, that
is, those behaviors and visualizations that do not contribute to the core functionality of the control. Helper
elements fall into three categories:
Standalone helper types are public and reusable controls or primitives that are used "anonymously"
in a template, meaning that neither the helper element nor the styled control is aware of the other.
Technically, any element can be an anonymous type, but in this context the term describes those
types that encapsulate specialized functionality to enable targeted scenarios.
Type-based helper elements are new types that encapsulate specialized functionality. These
elements are typically designed with a narrower range of functionality than common controls or
primitives. Unlike standalone helper elements, type-based helper elements are aware of the context
in which they are used and typically must share data with the control to whose template they belong.
Named helper elements are common controls or primitives that a control expects to find within its
template by name. These elements are given a well-known name within the template, making it
possible for a control to find the element and interact with it programmatically. There can only be one
element with a given name in any template.
The following table shows helper elements employed by control styles today (this list is not exhaustive):
Theme Considerations
Theme styles should attempt to have consistent property semantics across all themes, but make
no guarantee. As part of its documentation, your control should have a document describing the control's
property semantics, that is, the "meaning" of a property for a control. For example, the ComboBox control
should define the meaning of the Background property within ComboBox. The default styles for your
control should attempt to follow the semantics defined in that document across all themes. Control users,
on the other hand, should be aware that property semantics can change from theme to theme. In certain
cases, a given property may not be expressible under the visual constraints required by a particular theme.
(The Classic theme, for example, does not have a single border to which Thickness can be applied for many
controls.)
Theme styles do not need to have consistent trigger semantics across all themes. The behavior
exposed by a control style through triggers or animations may vary from theme to theme. Control users
should be aware that a control will not necessarily employ the same mechanism to achieve a particular
behavior across all themes. One theme, for example, may use an animation to express hover behavior where
another theme uses a trigger. This can result in inconsistencies in behavior preservation on customized
controls. (Changing the background property, for example, might not affect the hover state of the control if
that state is expressed using a trigger. However, if the hover state is implemented using an animation,
changing to background could irreparably break the animation and therefore the state transition.)
Theme styles do not need to have consistent "layout" semantics across all themes. For example, the
default style does not need to guarantee that a control will occupy the same amount of size in all themes or
guarantee that a control will have the same content margins / padding across all themes.
See Also
Styling and Templating
Control Authoring Overview
Adorners
5/4/2018 • 2 minutes to read • Edit Online
This section provides information about Adorners and the Windows Presentation Foundation (WPF ) Adorner
framework.
In This Section
Adorners Overview
How -to Topics
Reference
AdornedElementPlaceholder
Adorner
AdornerDecorator
AdornerHitTestResult
AdornerLayer
Related Sections
Adorners Overview
5/4/2018 • 4 minutes to read • Edit Online
Adorners are a special type of FrameworkElement, used to provide visual cues to a user. Among other uses,
Adorners can be used to add functional handles to elements or provide state information about a control.
About Adorners
An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an
AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of
adorned elements. Rendering of an adorner is independent from rendering of the UIElement that the adorner is
bound to. An adorner is typically positioned relative to the element to which it is bound, using the standard 2-D
coordinate origin located at the upper-left of the adorned element.
Common applications for adorners include:
Adding functional handles to a UIElement that enable a user to manipulate the element in some way
(resize, rotate, reposition, etc.).
Provide visual feedback to indicate various states, or in response to various events.
Overlay visual decorations on a UIElement.
Visually mask or override part or all of a UIElement.
Windows Presentation Foundation (WPF ) provides a basic framework for adorning visual elements. The
following table lists the primary types used when adorning objects, and their purpose. Several usage examples
follow.
NOTE
The parent of an Adorner is the AdornerLayer that renders the Adorner, not the element being adorned.
The following example shows a class that implements a simple adorner. The example adorner simply adorns the
corners of a UIElement with circles.
// Adorners must subclass the abstract base class Adorner.
public class SimpleCircleAdorner : Adorner
{
// Be sure to call the base class constructor.
public SimpleCircleAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
NOTE
Anything placed in the adorner layer is rendered on top of the rest of any styles you have set. In other words, adorners are
always visually on top and cannot be overridden using z-order.
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))
NOTE
Using Extensible Application Markup Language (XAML) to bind an adorner to another element is currently not supported.
See Also
AdornerHitTestResult
Shapes and Basic Drawing in WPF Overview
Painting with Images, Drawings, and Visuals
Drawing Objects Overview
How -to Topics
Adorners How-to Topics
5/4/2018 • 2 minutes to read • Edit Online
The following examples demonstrate how to accomplish common tasks using the Windows Presentation
Foundation (WPF ) adorner framework.
In This Section
Implement an Adorner
Bind an Adorner to an Element
Adorn the Children of a Panel
Remove an Adorner from an Element
Remove all Adorners from an Element
Reference
AdornedElementPlaceholder
Adorner
AdornerDecorator
AdornerHitTestResult
AdornerLayer
Related Sections
How to: Implement an Adorner
5/4/2018 • 2 minutes to read • Edit Online
Example
Description
A custom adorner is created by implementing a class that inherits from the abstract Adorner class. The example
adorner simply adorns the corners of a UIElement with circles by overriding the OnRender method.
Code
See Also
Adorners Overview
How to: Bind an Adorner to an Element
5/4/2018 • 2 minutes to read • Edit Online
Example
To bind an adorner to a particular UIElement, follow these steps:
1. Call the static method GetAdornerLayer to get an AdornerLayer object for the UIElement to be adorned.
GetAdornerLayer walks up the visual tree, starting at the specified UIElement, and returns the first adorner
layer it finds. (If no adorner layers are found, the method returns null.)
2. Call the Add method to bind the adorner to the target UIElement.
The following example binds a SimpleCircleAdorner (shown above) to a TextBox named myTextBox.
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))
NOTE
Using Extensible Application Markup Language (XAML) to bind an adorner to another element is currently not supported.
See Also
Adorners Overview
How to: Adorn the Children of a Panel
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to programmatically bind an adorner to the children of a specified Panel.
Example
To bind an adorner to the children of a Panel, follow these steps:
1. Declare a new AdornerLayer object and call the static GetAdornerLayer method to find an adorner layer
for the element whose children are to be adorned.
2. Enumerate through the children of the parent element and call the Add method to bind an adorner to each
child element.
The following example binds a SimpleCircleAdorner (shown above) to the children of a StackPanel named
myStackPanel.
NOTE
Using Extensible Application Markup Language (XAML) to bind an adorner to another element is currently not supported.
See Also
Adorners Overview
How to: Remove an Adorner from an Element
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to programmatically remove a specific adorner from a specified UIElement.
Example
This verbose code example removes the first adorner in the array of adorners returned by GetAdorners. This
example happens to retrieve the adorners on a UIElement named myTextBox. If the element specified in the call to
GetAdorners has no adorners, null is returned. This code explicitly checks for a null array, and is best suited for
applications where a null array is expected to be relatively common.
Example
This condensed code example is functionally equivalent to the verbose example shown above. This code does not
explicitly check for a null array, so it is possible that a NullReferenceException exception may be raised. This code is
best suited for applications where a null array is expected to be rare.
Try
myAdornerLayer.Remove((myAdornerLayer.GetAdorners(myTextBox))(0))
Catch
End Try
See Also
Adorners Overview
How to: Remove all Adorners from an Element
5/4/2018 • 2 minutes to read • Edit Online
This example shows how to programmatically remove all adorners from a specified UIElement.
Example
This verbose code example removes all of the adorners in the array of adorners returned by GetAdorners. This
example happens to retrieve the adorners on a UIElement named myTextBox. If the element specified in the call to
GetAdorners has no adorners, null is returned. This code explicitly checks for a null array, and is best suited for
applications where a null array is expected to be relatively common.
toRemoveArray = myAdornerLayer.GetAdorners(myTextBox)
If toRemoveArray IsNot Nothing Then
For x As Integer = 0 To toRemoveArray.Length - 1
myAdornerLayer.Remove(toRemoveArray(x))
Next x
End If
Example
This condensed code example is functionally equivalent to the verbose example shown above. This code does not
explicitly check for a null array, so it is possible that a NullReferenceException exception may be raised. This code is
best suited for applications where a null array is expected to be rare.
Try
For Each toRemove In myAdornerLayer.GetAdorners(myTextBox)
myAdornerLayer.Remove(toRemove)
Next toRemove
Catch
End Try
See Also
Adorners Overview
Control Styles and Templates
8/31/2018 • 2 minutes to read • Edit Online
Controls in Windows Presentation Foundation (WPF ) have a ControlTemplate that contains the visual tree of
that control. You can change the structure and appearance of a control by modifying the ControlTemplate of
that control. There is no way to replace only part of the visual tree of a control; to change the visual tree of a
control you must set the Template property of the control to its new and complete ControlTemplate.
The desktop themes determine which resource dictionary is used. To get the resource dictionaries for the
desktop themes, see Default WPF Themes.
The following table describes the resource dictionary file names and their corresponding desktop themes.
Classic.xaml Classic Windows look (from Windows 95, Windows 98, and
Windows 2000) on the Windows XP operating system..
In This Section
Button Styles and Templates
Calendar Styles and Templates
CheckBox Styles and Templates
ComboBox Styles and Templates
ContextMenu Styles and Templates
DataGrid Styles and Templates
DatePicker Styles and Templates
DocumentViewer Styles and Templates
Expander Styles and Templates
Frame Styles and Templates
GroupBox Styles and Templates
Label Styles and Templates
ListBox Styles and Templates
ListView Styles and Templates
Menu Styles and Templates
NavigationWindow Styles and Templates
PasswordBox Styles and Templates
ProgressBar Styles and Templates
RadioButton Styles and Templates
RepeatButton Styles and Templates
ScrollBar Styles and Templates
ScrollViewer Styles and Templates
Slider Styles and Templates
StatusBar Styles and Templates
TabControl Styles and Templates
TextBox Styles and Templates
Thumb Styles and Templates
ToggleButton Styles and Templates
ToolBar Styles and Templates
ToolTip Styles and Templates
TreeView Styles and Templates
Window Styles and Templates
Reference
System.Windows.Controls
ControlTemplate
Related Sections
Control Authoring Overview
Styling and Templating
Button Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the Button control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Button Parts
The Button control does not have any named parts.
Button States
The following table lists the visual states for the Button control.
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Border>
<Rectangle Margin="2"
StrokeThickness="1"
Stroke="#60000000"
StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
<VisualTransition GeneratedDuration="0"
To="Pressed" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefault"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource DefaultBorderBrushLightBrush}"
Offset="0.0" />
<GradientStop Color="{DynamicResource DefaultBorderBrushDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Calendar Styles and Templates
5/22/2018 • 9 minutes to read • Edit Online
This topic describes the styles and templates for the Calendar control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Calendar Parts
The following table lists the named parts for the Calendar control.
Calendar States
The following table lists the visual states for the Calendar control.
CalendarItem Parts
The following table lists the named parts for the CalendarItem control.
CalendarItem States
The following table lists the visual states for the CalendarItem control.
CalendarDayButton Parts
The CalendarDayButton control does not have any named parts.
CalendarDayButton States
The following table lists the visual states for the CalendarDayButton control.
CalendarButton Parts
The CalendarButton control does not have any named parts.
CalendarButton States
The following table lists the visual states for the CalendarButton control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
CheckBox Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the CheckBox control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
CheckBox Parts
The CheckBox control does not have any named parts.
CheckBox States
The following table lists the visual states for the CheckBox control.
</Border.Background>
<Grid>
<Path Visibility="Collapsed"
Width="7"
Height="7"
x:Name="CheckMark"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
<Path Visibility="Collapsed"
Width="7"
Height="7"
x:Name="InderminateMark"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path.Stroke>
</Path>
</Grid>
</Border>
</BulletDecorator.Bullet>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CheckMark">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="InderminateMark">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="4,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True" />
</BulletDecorator>
</ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ComboBox Styles and Templates
5/22/2018 • 4 minutes to read • Edit Online
This topic describes the styles and templates for the ComboBox control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
ComboBox Parts
The following table lists the named parts for the ComboBox control.
When you create a ControlTemplate for a ComboBox, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the ComboBox; the ScrollViewer enables scrolling within
the control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
ComboBox States
The following table lists the states for the ComboBox control.
ComboBoxItem Parts
The ComboBoxItem control does not have any named parts.
ComboBoxItem States
The following table lists the states for the ComboBoxItem control.
<ControlTemplate x:Key="ComboBoxToggleButton"
<ControlTemplate x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)"
Storyboard.TargetName="Arrow">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="2"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1" />
Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Grid.Column="0"
CornerRadius="2,0,0,2"
Margin="1" >
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}"/>
</Border.Background>
</Border>
<Path x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z" >
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}"/>
</Path.Fill>
</Path>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox"
TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
Focusable="False"
Background="{TemplateBinding Background}" />
</ControlTemplate>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ContextMenu Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ContextMenu control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
ContextMenu Parts
The ContextMenu control does not have any named parts.
When you create a ControlTemplate for a ContextMenu, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the ContextMenu; the ScrollViewer enables scrolling
within the control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the
ItemsPresenter the name, ItemsPresenter .
ContextMenu States
The following table lists the visual states for the ContextMenu control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
DataGrid Styles and Templates
5/22/2018 • 12 minutes to read • Edit Online
This topic describes the styles and templates for the DataGrid control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
DataGrid Parts
The following table lists the named parts for the DataGrid control.
When you create a ControlTemplate for a DataGrid, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the DataGrid; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
The default template for the DataGrid contains a ScrollViewer control. For more information about the parts
defined by the ScrollViewer, see ScrollViewer Styles and Templates.
DataGrid States
The following table lists the visual states for the DataGrid control.
DataGridCell Parts
The DataGridCell element does not have any named parts.
DataGridCell States
The following table lists the visual states for the DataGridCell element.
VISUALSTATE NAME VISUALSTATEGROUP NAME DESCRIPTION
InvalidUnfocused ValidationStates The cell is not valid and does not have
focus.
DataGridRow Parts
The DataGridRow element does not have any named parts.
DataGridRow States
The following table lists the visual states for the DataGridRow element.
DataGridRowHeader Parts
The following table lists the named parts for the DataGridRowHeader element.
DataGridRowHeader States
The following table lists the visual states for the DataGridRowHeader element.
DataGridColumnHeadersPresenter Parts
The following table lists the named parts for the DataGridColumnHeadersPresenter element.
PART TYPE DESCRIPTION
DataGridColumnHeadersPresenter States
The following table lists the visual states for the DataGridColumnHeadersPresenter element.
InvalidUnfocused ValidationStates The cell is not valid and does not have
focus.
DataGridColumnHeader Parts
The following table lists the named parts for the DataGridColumnHeader element.
DataGridColumnHeader States
The following table lists the visual states for the DataGridColumnHeader element.
<!--Style and template for the button in the upper left corner of the DataGrid.-->
<Style TargetType="{x:Type Button}"
x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle,
TypeInTargetAssembly={x:Type DataGrid}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Arrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="Border"
SnapsToDevicePixels="True">
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="1" />
</LinearGradientBrush>
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Polygon x:Name="Arrow"
HorizontalAlignment="Right"
Margin="8,8,3,3"
Opacity="0.15"
Points="0,10 10,10 10,0"
Stretch="Uniform"
VerticalAlignment="Bottom">
<Polygon.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Polygon.Fill>
</Polygon>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Focusable="false"
Command="{x:Static DataGrid.SelectAllCommand}"
Style="{DynamicResource {ComponentResourceKey
ResourceId=DataGridSelectAllButtonStyle,
TypeInTargetAssembly={x:Type DataGrid}}}"
Visibility="{Binding HeadersVisibility,
ConverterParameter={x:Static DataGridHeadersVisibility.All},
Converter={x:Static DataGrid.HeadersVisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Width="{Binding CellsPanelHorizontalOffset,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="{Binding HeadersVisibility,
ConverterParameter={x:Static DataGridHeadersVisibility.Column},
Converter={x:Static DataGrid.HeadersVisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.ColumnSpan="2"
Grid.Row="1"
CanContentScroll="{TemplateBinding CanContentScroll}" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="2"
Grid.Row="1"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Maximum="{TemplateBinding ScrollableHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}"/>
<Grid Grid.Column="1"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Column="1"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Maximum="{TemplateBinding ScrollableWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</Style.Triggers>
</Style>
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ContentAreaColorDark}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused_Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal_Editing">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver_Editing">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver_Unfocused_Editing">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused_Editing">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMediumColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver_Unfocused_Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
Visibility="{TemplateBinding DetailsVisibility}"
SelectiveScrollingGrid.SelectiveScrollingOrientation=
"{Binding AreRowDetailsFrozen,
ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
Converter={x:Static DataGrid.RowDetailsScrollingConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility,
ConverterParameter={x:Static DataGridHeadersVisibility.Row},
Converter={x:Static DataGrid.HeadersVisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Thumb x:Name="PART_TopHeaderGripper"
<Thumb x:Name="PART_TopHeaderGripper"
Style="{StaticResource RowHeaderGripperStyle}"
VerticalAlignment="Top" />
<Thumb x:Name="PART_BottomHeaderGripper"
Style="{StaticResource RowHeaderGripperStyle}"
VerticalAlignment="Bottom" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Thumb x:Name="PART_LeftHeaderGripper"
HorizontalAlignment="Left"
Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper"
HorizontalAlignment="Right"
Style="{StaticResource ColumnHeaderGripperStyle}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
DatePicker Styles and Templates
5/22/2018 • 5 minutes to read • Edit Online
This topic describes the styles and templates for the DatePicker control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
DatePicker Parts
The following table lists the named parts for the DatePicker control.
DatePicker States
The following table lists the visual states for the DatePicker control.
DatePickerTextBox Parts
The following table lists the named parts for the DatePickerTextBox control.
PART TYPE DESCRIPTION
DatePickerTextBox States
The following table lists the visual states for the DatePickerTextBox control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
DocumentViewer Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the DocumentViewer control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
DocumentViewer Parts
The following table lists the named parts for the DocumentViewer control.
DocumentViewer States
The following table lists the visual states for the DocumentViewer control.
<ScrollViewer Grid.Row="1"
CanContentScroll="true"
HorizontalScrollBarVisibility="Auto"
x:Name="PART_ContentHost"
IsTabStop="true">
<ScrollViewer.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</ScrollViewer.Background>
</ScrollViewer>
<ContentControl Grid.Row="2"
x:Name="PART_FindToolBarHost"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The preceding example uses one or more of the following resources.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Expander Styles and Templates
5/22/2018 • 3 minutes to read • Edit Online
This topic describes the styles and templates for the Expander control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Expander Parts
The Expander control does not have any named parts.
Expander States
The following table lists the visual states for the Expander control.
<ControlTemplate x:Key="ExpanderToggleButton"
TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
CornerRadius="2,0,0,0"
BorderThickness="0,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CollapsedArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ExpandededArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Path x:Name="CollapsedArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
<Path x:Name="ExpandededArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Data="M 0 4 L 4 0 L 8 4 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
</Border>
</ControlTemplate>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton OverridesDefaultStyle="True"
Template="{StaticResource ExpanderToggleButton}"
IsChecked="{Binding IsExpanded, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</ToggleButton.Background>
</ToggleButton>
<ContentPresenter Grid.Column="1"
Margin="4"
ContentSource="Header"
RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content"
Grid.Row="1"
BorderThickness="1,0,1,1"
CornerRadius="0,0,2,2">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
</Border.Background>
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter TargetName="ContentRow"
Property="Height"
Value="{Binding DesiredHeight, ElementName=Content}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Frame Styles and Templates
5/22/2018 • 5 minutes to read • Edit Online
This topic describes the styles and templates for the Frame control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Frame Parts
The following table lists the named parts for the Frame control.
Frame States
The following table lists the visual states for the Frame control.
<Style x:Key="FrameButtonStyle"
TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Command"
Value="NavigationCommands.BrowseBack" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="Ellipse"
StrokeThickness="1"
Width="16"
Height="16">
<Ellipse.Stroke>
<SolidColorBrush Color="{DynamicResource NavButtonFrameColor}" />
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Path x:Name="Arrow"
Margin="0,0,2,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 4 0 L 0 4 L 4 8 Z" >
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}"/>
</Path.Fill>
</Path>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Command"
Value="{x:Static NavigationCommands.BrowseForward}">
<Setter TargetName="Arrow"
Property="Data"
Value="M 0 0 L 4 4 L 0 8 z" />
<Setter TargetName="Arrow"
Property="Margin"
Value="2,0,0,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FrameMenu"
TargetType="{x:Type Menu}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="KeyboardNavigation.TabNavigation"
Value="None" />
<Setter Property="IsMainMenu"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Menu}">
<DockPanel IsItemsHost="true" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FrameHeaderMenuItem"
TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid>
<Popup x:Name="PART_Popup"
Placement="Bottom"
VerticalOffset="2"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border x:Name="SubMenuBorder"
BorderThickness="1"
Background="{DynamicResource MenuPopupBrush}">
<Border.BorderBrush>
<SolidColorBrush Color="{StaticResource BorderMediumColor}" />
</Border.BorderBrush>
<StackPanel IsItemsHost="true"
Margin="2"
KeyboardNavigation.TabNavigation="Cycle"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
<Grid x:Name="Panel"
Width="24"
Background="Transparent"
HorizontalAlignment="Right">
HorizontalAlignment="Right">
<Border Visibility="Hidden"
x:Name="HighlightBorder"
BorderThickness="1"
CornerRadius="2">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMouseOverColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Path x:Name="Arrow"
SnapsToDevicePixels="false"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0,2,4,0"
StrokeLineJoin="Round"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted"
Value="true">
<Setter TargetName="HighlightBorder"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="IsSubmenuOpen"
Value="true">
<Setter TargetName="HighlightBorder"
Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Background"
TargetName="HighlightBorder">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlPressedColor}"
Offset="0.984" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Arrow"
Property="Fill">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FrameSubmenuItem"
TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Header"
Value="{Binding (JournalEntry.Name)}" />
<Setter Property="Command"
Value="NavigationCommands.NavigateJournal" />
<Setter Property="CommandTarget"
Value="{Binding TemplatedParent,
RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" />
<Setter Property="CommandParameter"
Value="{Binding RelativeSource={RelativeSource Self}}" />
<Setter Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
Value="{Binding (JournalEntryUnifiedViewConverter.JournalEntryPosition)}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border BorderThickness="1"
Name="Border">
<Grid x:Name="Panel"
Background="Transparent"
SnapsToDevicePixels="true"
Height="35"
Width="250">
<Path x:Name="Glyph"
SnapsToDevicePixels="false"
Margin="7,5"
Width="10"
Height="10"
HorizontalAlignment="Left"
StrokeStartLineCap="Triangle"
StrokeEndLineCap="Triangle"
StrokeThickness="2">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
<ContentPresenter ContentSource="Header"
Margin="24,5,50,5" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
Value="Current">
<Setter TargetName="Glyph"
Property="Data"
Value="M 0,5 L 2.5,8 L 7,3 " />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter Property="Background"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Transparent"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMouseOverColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="0" />
<GradientStop Color="Transparent"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted"
Value="true" />
<Condition Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
Value="Forward" />
</MultiTrigger.Conditions>
<Setter TargetName="Glyph"
Property="Data"
Value="M 3 1 L 7 5 L 3 9 z" />
<Setter TargetName="Glyph"
Property="Stroke"
Value="{x:Null}" />
<Setter TargetName="Glyph"
Property="Fill">
<Setter.Value>
<SolidColorBrush Color="{StaticResource GlyphColor}" />
</Setter.Value>
</Setter>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted"
Value="true" />
<Condition Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
Value="Back" />
</MultiTrigger.Conditions>
</MultiTrigger.Conditions>
<Setter TargetName="Glyph"
Property="Data"
Value="M 7 1 L 3 5 L 7 9 z" />
<Setter TargetName="Glyph"
Property="Stroke"
Value="{x:Null}" />
<Setter TargetName="Glyph"
Property="Fill">
<Setter.Value>
<SolidColorBrush Color="{StaticResource GlyphColor}" />
</Setter.Value>
</Setter>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Menu x:Name="NavMenu"
<Menu x:Name="NavMenu"
Grid.ColumnSpan="3"
Height="16"
Margin="1,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource FrameMenu}">
<MenuItem Style="{StaticResource FrameHeaderMenuItem}"
ItemContainerStyle="{StaticResource FrameSubmenuItem}"
IsSubmenuOpen="{Binding (MenuItem.IsSubmenuOpen),
Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<MenuItem.ItemsSource>
<MultiBinding Converter="{StaticResource JournalEntryUnifiedViewConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="BackStack" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ForwardStack" />
</MultiBinding>
</MenuItem.ItemsSource>
</MenuItem>
</Menu>
<Path Grid.Column="0"
SnapsToDevicePixels="false"
IsHitTestVisible="false"
Margin="2,1.5,0,1.5"
Grid.ColumnSpan="3"
StrokeThickness="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Data="M15,14 Q18,12.9 20.9,14 A8.3,8.3,0,0,0,35.7,8.7 A8.3,8.3,0,0,0,
25.2,0.6 Q18, 3.3 10.8,0.6 A8.3,8.3,0,0,0,0.3,8.7 A8.3,8.3,0,0,0,15,14 z"
Stroke="{x:Null}">
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Path.Fill>
</Path>
<Button Style="{StaticResource FrameButtonStyle}"
Command="NavigationCommands.BrowseBack"
Content="M 4 0 L 0 4 L 4 8 Z"
Margin="2.7,1.5,1.3,1.5"
Grid.Column="0" />
<Button Style="{StaticResource FrameButtonStyle}"
Command="NavigationCommands.BrowseForward"
Content="M 4 0 L 0 4 L 4 8 Z"
Margin="1.3,1.5,0,1.5"
Grid.Column="1" />
</Grid>
</Border>
<Border BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<ContentPresenter x:Name="PART_FrameCP"
Height="458"
Width="640" />
</Border>
</DockPanel>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="CanGoForward"
Value="false" />
<Condition Property="CanGoBack"
Value="false" />
Value="false" />
</MultiTrigger.Conditions>
<Setter TargetName="NavMenu"
Property="IsEnabled"
Value="false" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
GroupBox Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the GroupBox control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
GroupBox Parts
The GroupBox control does not have any named parts.
GroupBox States
The following table lists the visual states for the GroupBox control.
<Style TargetType="GroupBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="0"
BorderThickness="1"
CornerRadius="2,2,0,0">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter Margin="4"
ContentSource="Header"
RecognizesAccessKey="True" />
</Border>
<Border Grid.Row="1"
BorderThickness="1,0,1,1"
CornerRadius="0,0,2,2">
<Border.BorderBrush>
<SolidColorBrush Color="{StaticResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
MappingMode="RelativeToBoundingBox"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ContentAreaColorLight}"
Offset="0" />
<GradientStop Color="{DynamicResource ContentAreaColorDark}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter Margin="4" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Label Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the Label control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Label Parts
The Label control does not have any named parts.
Label States
The following table lists the visual states for the Label control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ListBox Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ListBox control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
ListBox Parts
The ListBox control does not have any named parts.
When you create a ControlTemplate for a ListBox, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the ListBox; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
ListBox States
The following table lists the visual states for the ListBox control.
ListBoxItem Parts
The ListBoxItem control does not have any named parts.
ListBoxItem States
The following table lists the visual states for the ListBox control.
</Setter>
</Trigger>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ListView Styles and Templates
5/22/2018 • 4 minutes to read • Edit Online
This topic describes the styles and templates for the ListView control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
ListView Parts
The ListView control does not have any named parts.
When you create a ControlTemplate for a ListView, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the ListView; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
ListView States
The following table lists the visual states for the ListView control.
ListViewItem Parts
The ListViewItem control does not have any named parts.
ListViewItem States
The following table lists the states for the ListViewItem control.
<ScrollContentPresenter Name="PART_ScrollContentPresenter"
KeyboardNavigation.DirectionalNavigation="Local"
CanContentScroll="True"
CanHorizontallyScroll="False"
CanVerticallyScroll="False" />
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GridViewColumnHeaderGripper"
TargetType="Thumb">
<Setter Property="Width"
Value="18" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}"
Background="Transparent">
<Rectangle HorizontalAlignment="Center"
Width="1"
Fill="{TemplateBinding Background}" />
</Border>
</ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Color="White"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter x:Name="HeaderContent"
Margin="0,0,0,1"
RecognizesAccessKey="True"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper"
HorizontalAlignment="Right"
Margin="0,0,-9,0"
Style="{StaticResource GridViewColumnHeaderGripper}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Role"
Value="Floating">
<Setter Property="Opacity"
Value="0.7" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Canvas Name="PART_FloatingHeaderCanvas">
<Rectangle Fill="#60000000"
Width="{TemplateBinding ActualWidth}"
Height="{TemplateBinding ActualHeight}" />
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Role"
Value="Padding">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border Name="HeaderBorder"
BorderThickness="0,1,0,1">
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}" />
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Menu Styles and Templates
5/22/2018 • 6 minutes to read • Edit Online
This topic describes the styles and templates for the Menu control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Menu Parts
The Menu control does not have any named parts.
When you create a ControlTemplate for a Menu, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the Menu; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
Menu States
The following table lists the visual states for the Menu control.
MenuItem Parts
The following table lists the named parts for the Menu control.
When you create a ControlTemplate for a MenuItem, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the MenuItem; the ScrollViewer enables scrolling within
the control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
MenuItem States
The following table lists the visual states for the MenuItem control.
VISUALSTATE NAME VISUALSTATEGROUP NAME DESCRIPTION
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<StackPanel ClipToBounds="True"
Orientation="Horizontal"
IsItemsHost="True" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The following example shows how to define a ControlTemplate for the MenuItem control.
</Setter.Value>
</Setter>
</Trigger>
<Trigger SourceName="Popup"
Property="AllowsTransparency"
Value="True">
<Setter TargetName="SubmenuBorder"
Property="CornerRadius"
Value="0,0,4,4" />
<Setter TargetName="SubmenuBorder"
Property="Padding"
Value="0,0,0,3" />
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{StaticResource DisabledForegroundColor}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{StaticResource DisabledForegroundColor}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ControlTemplate>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Path x:Name="CheckMark"
Width="7"
Height="7"
Visibility="Hidden"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
</Border>
<ContentPresenter x:Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True" />
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,0,2"
DockPanel.Dock="Right" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ButtonBase.Command"
Value="{x:Null}" />
<Trigger Property="Icon"
Value="{x:Null}">
<Setter TargetName="Icon"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsChecked"
Value="true">
<Setter TargetName="CheckMark"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="IsCheckable"
Value="true">
<Setter TargetName="Check"
Property="Visibility"
Value="Visible" />
<Setter TargetName="Icon"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter Property="Background"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Transparent"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMouseOverColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="0" />
<GradientStop Color="Transparent"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{StaticResource DisabledForegroundColor}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
The following example defines the MenuScrollViewer , which is used in the previous example.
<Style x:Key="MenuScrollViewer"
TargetType="{x:Type ScrollViewer}"
BasedOn="{x:Null}">
<Setter Property="HorizontalScrollBarVisibility"
Value="Hidden" />
<Setter Property="VerticalScrollBarVisibility"
Value="Auto" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="1"
Grid.Column="0">
<ScrollContentPresenter Margin="{TemplateBinding Padding}" />
</Border>
<RepeatButton Style="{StaticResource MenuScrollButton}"
Grid.Row="0"
Grid.Column="0"
Command="{x:Static ScrollBar.LineUpCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Focusable="False">
<RepeatButton.Visibility>
<MultiBinding FallbackValue="Visibility.Collapsed"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
ConverterParameter="0">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ComputedVerticalScrollBarVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="VerticalOffset" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ExtentHeight" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ViewportHeight" />
</MultiBinding>
</RepeatButton.Visibility>
<Path Fill="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"
Data="{StaticResource UpArrow}" />
</RepeatButton>
<RepeatButton Style="{StaticResource MenuScrollButton}"
Grid.Row="2"
Grid.Column="0"
Command="{x:Static ScrollBar.LineDownCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Focusable="False">
<RepeatButton.Visibility>
<MultiBinding FallbackValue="Visibility.Collapsed"
Converter="{StaticResource MenuScrollingVisibilityConverter}"
ConverterParameter="100">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ComputedVerticalScrollBarVisibility" />
Path="ComputedVerticalScrollBarVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="VerticalOffset" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ExtentHeight" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ViewportHeight" />
</MultiBinding>
</RepeatButton.Visibility>
<Path Fill="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"
Data="{StaticResource DownArrow}" />
</RepeatButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
NavigationWindow Styles and Templates
5/22/2018 • 6 minutes to read • Edit Online
This topic describes the styles and templates for the NavigationWindow control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
NavigationWindow Parts
The following table lists the named parts for the NavigationWindow control.
NavigationWindow States
The following table lists the visual states for the NavigationWindow control.
<Style x:Key="NavWinButtonStyle"
TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Command"
Value="NavigationCommands.BrowseBack" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="Ellipse"
StrokeThickness="1"
Width="24"
Height="24">
<Ellipse.Stroke>
<SolidColorBrush Color="{DynamicResource NavButtonFrameColor}" />
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Path x:Name="Arrow"
Margin="0,0,3,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 6 0 L 0 6 L 6 12 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Command"
Value="{x:Static NavigationCommands.BrowseForward}">
<Setter TargetName="Arrow"
Property="Data"
Value="M 0 0 L 6 6 L 0 12 z" />
<Setter TargetName="Arrow"
Property="Margin"
Value="3,0,0,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Grid x:Name="Panel"
Width="24"
Background="Transparent"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
d:IsHidden="True">
<Border Visibility="Hidden"
x:Name="HighlightBorder"
BorderThickness="1"
CornerRadius="2">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMouseOverColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Path x:Name="Arrow"
SnapsToDevicePixels="false"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0,2,4,0"
StrokeLineJoin="Round"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted"
Value="true">
<Setter TargetName="HighlightBorder"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="IsSubmenuOpen"
Value="true">
<Setter TargetName="HighlightBorder"
Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Background"
TargetName="HighlightBorder">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlPressedColor}"
Offset="0.984" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavWinSubmenuItem"
TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Header"
Value="{Binding (JournalEntry.Name)}" />
<Setter Property="Command"
Value="NavigationCommands.NavigateJournal" />
<Setter Property="CommandTarget"
Value="{Binding TemplatedParent, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" />
<Setter Property="CommandParameter"
Value="{Binding RelativeSource={RelativeSource Self}}" />
<Setter Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
Value="{Binding (JournalEntryUnifiedViewConverter.JournalEntryPosition)}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border Name="Border"
BorderThickness="1">
<Grid x:Name="Panel"
Background="Transparent"
SnapsToDevicePixels="true"
Height="35"
Width="250">
<Path x:Name="Glyph"
SnapsToDevicePixels="false"
Margin="7,5"
Width="10"
Height="10"
HorizontalAlignment="Left"
StrokeStartLineCap="Triangle"
StrokeEndLineCap="Triangle"
StrokeThickness="2">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
<ContentPresenter ContentSource="Header"
Margin="24,5,50,5" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Value="Current"
Property="JournalEntryUnifiedViewConverter.JournalEntryPosition">
Property="JournalEntryUnifiedViewConverter.JournalEntryPosition">
<Setter TargetName="Glyph"
Property="Data"
Value="M 0,5 L 2.5,8 L 7,3 " />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter Property="Background"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Transparent"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMouseOverColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="0" />
<GradientStop Color="Transparent"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted"
Value="true" />
<Condition Value="Forward"
Property="JournalEntryUnifiedViewConverter.JournalEntryPosition" />
</MultiTrigger.Conditions>
<Setter TargetName="Glyph"
Property="Data"
Value="M 3 1 L 7 5 L 3 9 z" />
<Setter TargetName="Glyph"
Property="Fill">
<Setter.Value>
<SolidColorBrush Color="{StaticResource GlyphColor}" />
</Setter.Value>
</Setter>
<Setter TargetName="Glyph"
Property="Stroke"
Value="{x:Null}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted"
Value="true" />
<Condition Value="Back"
Property="JournalEntryUnifiedViewConverter.JournalEntryPosition" />
</MultiTrigger.Conditions>
<Setter TargetName="Glyph"
Property="Data"
Value="M 7 1 L 3 5 L 7 9 z" />
<Setter TargetName="Glyph"
Property="Fill">
<Setter.Value>
<SolidColorBrush Color="{StaticResource GlyphColor}" />
</Setter.Value>
</Setter>
<Setter TargetName="Glyph"
Property="Stroke"
Property="Stroke"
Value="{x:Null}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Menu x:Name="NavMenu"
Grid.ColumnSpan="3"
Height="20"
Margin="1,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource NavWinMenu}">
<MenuItem Style="{StaticResource NavWinHeaderMenuItem}"
ItemContainerStyle="{StaticResource NavWinSubmenuItem}"
IsSubmenuOpen="{Binding (MenuItem.IsSubmenuOpen),
Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<MenuItem.ItemsSource>
<MultiBinding Converter="{StaticResource JournalEntryUnifiedViewConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="BackStack" />
<Binding RelativeSource="{RelativeSource TemplatedParent}"
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="ForwardStack" />
</MultiBinding>
</MenuItem.ItemsSource>
</MenuItem>
</Menu>
<Path Grid.Column="0"
SnapsToDevicePixels="false"
IsHitTestVisible="false"
Margin="2,1.5,0,1.5"
Grid.ColumnSpan="3"
StrokeThickness="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Data="M22.5767,21.035 Q27,19.37
31.424,21.035 A12.5,12.5,0,0,0,53.5,13
A12.5,12.5,0,0,0,37.765,0.926
Q27,4.93 16.235,0.926
A12.5,12.5,0,0,0,0.5,13
A12.5,12.5,0,0,0,22.5767,21.035 z">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Path.Stroke>
<Path.Fill>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0" />
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
PasswordBox Syles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the PasswordBox control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
PasswordBox Parts
The following table lists the named parts for the PasswordBox control.
PasswordBox States
The following table lists the visual states for the PasswordBox control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ProgressBar Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ProgressBar control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
ProgressBar Parts
The following table lists the named parts for the ProgressBar control.
ProgressBar States
The following table lists the visual states for the ProgressBar control.
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="PART_Track"
CornerRadius="2"
BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
</Border>
<Border x:Name="PART_Indicator"
CornerRadius="2"
BorderThickness="1"
HorizontalAlignment="Left"
Background="{TemplateBinding Foreground}"
Margin="0,-1,0,1">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Grid ClipToBounds="True"
x:Name="Animation">
<Rectangle x:Name="PART_GlowRect"
Width="100"
HorizontalAlignment="Left"
Fill="{StaticResource ProgressBarIndicatorAnimatedFill}"
Margin="-100,0,0,0" />
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
RadioButton Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the RadioButton control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
RadioButton Parts
The RadioButton control does not have any named parts.
RadioButton States
The following table lists the visual states for the RadioButton control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
RepeatButton Syles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the RepeatButton control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
RepeatButton Parts
The RepeatButton control does not have any named parts.
RepeatButton States
The following table lists the visual states for the RepeatButton control.
<Style x:Key="ScrollBarLineButton"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Focusable"
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="Border"
Margin="1"
CornerRadius="2"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"/>
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="Arrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{Binding Content,
RelativeSource={RelativeSource TemplatedParent}}" >
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}"/>
</Path.Fill>
</Path>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ScrollBar Styles and Templates
5/22/2018 • 3 minutes to read • Edit Online
This topic describes the styles and templates for the ScrollBar control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
ScrollBar Parts
The following table lists the named parts for the ScrollBar control.
ScrollBar States
The following table lists the visual states for the ScrollBar control.
<Style x:Key="ScrollBarLineButton"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Focusable"
Value="false" />
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="Border"
Margin="1"
CornerRadius="2"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"/>
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="Arrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{Binding Content,
RelativeSource={RelativeSource TemplatedParent}}" >
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}"/>
</Path.Fill>
</Path>
</Border>
</ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarPageButton"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="IsTabStop"
Value="false" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="Transparent" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarThumb"
TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="IsTabStop"
Value="false" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border CornerRadius="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="VerticalScrollBar"
TargetType="{x:Type ScrollBar}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="18" />
<RowDefinition Height="0.00001*" />
<RowDefinition MaxHeight="18" />
</Grid.RowDefinitions>
<Border Grid.RowSpan="3"
CornerRadius="2"
Background="#F0F0F0" />
<RepeatButton Grid.Row="0"
Style="{StaticResource ScrollBarLineButton}"
Height="18"
Command="ScrollBar.LineUpCommand"
Content="M 0 4 L 8 4 L 4 0 Z" />
<Track x:Name="PART_Track"
Grid.Row="1"
IsDirectionReversed="true">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageUpCommand" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}"
Margin="1,0,1,0">
<Thumb.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Thumb.BorderBrush>
<Thumb.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Thumb.Background>
</Thumb>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageDownCommand" />
</Track.IncreaseRepeatButton>
</Track>
<RepeatButton Grid.Row="3"
Style="{StaticResource ScrollBarLineButton}"
Height="18"
Command="ScrollBar.LineDownCommand"
Content="M 0 0 L 4 4 L 8 0 Z" />
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="HorizontalScrollBar"
TargetType="{x:Type ScrollBar}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="18" />
<ColumnDefinition Width="0.00001*" />
<ColumnDefinition MaxWidth="18" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3"
CornerRadius="2"
Background="#F0F0F0" />
<RepeatButton Grid.Column="0"
Style="{StaticResource ScrollBarLineButton}"
Width="18"
Command="ScrollBar.LineLeftCommand"
Content="M 4 0 L 4 8 L 0 4 Z" />
<Track x:Name="PART_Track"
Grid.Column="1"
IsDirectionReversed="False">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageLeftCommand" />
Command="ScrollBar.PageLeftCommand" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}"
Margin="0,1,0,1">
<Thumb.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Thumb.BorderBrush>
<Thumb.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Thumb.Background>
</Thumb>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageRightCommand" />
</Track.IncreaseRepeatButton>
</Track>
<RepeatButton Grid.Column="3"
Style="{StaticResource ScrollBarLineButton}"
Width="18"
Command="ScrollBar.LineRightCommand"
Content="M 0 0 L 4 4 L 0 8 Z" />
</Grid>
</ControlTemplate>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ScrollViewer Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ScrollViewer control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
ScrollViewer Parts
The following table lists the named parts for the ScrollViewer control.
ScrollViewer States
The following table lists the visual states for the ScrollViewer control.
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Slider Styles and Templates
5/22/2018 • 4 minutes to read • Edit Online
This topic describes the styles and templates for the Slider control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Slider Parts
The following table lists the named parts for the Slider control.
Slider States
The following table lists the visual states for the Slider control.
<Style x:Key="SliderButtonStyle"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="IsTabStop"
Value="false" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="Transparent" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SliderThumbStyle"
TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Height"
Value="14" />
<Setter Property="Width"
Value="14" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Ellipse x:Name="Ellipse"
StrokeThickness="1">
<Ellipse.Stroke>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
<GradientStop Color="{DynamicResource ControlLightColor}" />
</LinearGradientBrush>
</Ellipse.Fill>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Border x:Name="TrackBackground"
Margin="0"
CornerRadius="2"
Width="4"
Grid.Column="1"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="1,0"
StartPoint="0.25,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource SliderTrackDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Track Grid.Column="1"
x:Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderButtonStyle}"
Command="Slider.DecreaseLarge" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumbStyle}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderButtonStyle}"
Command="Slider.IncreaseLarge" />
</Track.IncreaseRepeatButton>
</Track>
<TickBar x:Name="BottomTick"
SnapsToDevicePixels="True"
Grid.Column="2"
Fill="{TemplateBinding Foreground}"
Placement="Right"
Width="4"
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TickPlacement"
Value="TopLeft">
Value="TopLeft">
<Setter TargetName="TopTick"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="TickPlacement"
Value="BottomRight">
<Setter TargetName="BottomTick"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="TickPlacement"
Value="Both">
<Setter TargetName="TopTick"
Property="Visibility"
Value="Visible" />
<Setter TargetName="BottomTick"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
StatusBar Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the StatusBar control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
StatusBar Parts
The StatusBar control does not have any named parts.
StatusBar States
The following table lists the visual states for the StatusBar control.
StatusBarItem Parts
The StatusBarItem control does not have any named parts.
StatusBar States
The following table lists the visual states for the StatusBarItem control.
</Border.Background>
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
TabControl Styles and Templates
5/22/2018 • 3 minutes to read • Edit Online
This topic describes the styles and templates for the TabControl control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
TabControl Parts
The following table lists the named parts for the TabControl control.
When you create a ControlTemplate for a TabControl, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the TabControl; the ScrollViewer enables scrolling within
the control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
TabControl States
The following table lists the visual states for the TabControl control.
TabItem Parts
The TabItem control does not have any named parts.
TabItem States
The following table lists the visual states for the TabItem control.
VISUALSTATE NAME VISUALSTATEGROUP NAME DESCRIPTION
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Panel.ZIndex"
Value="100" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
TextBox Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the TextBox control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
TextBox Parts
The following table lists the named parts for the TextBox control.
TextBox States
The following table lists the visual states for the TextBox control.
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Thumb Syles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the Thumb control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Thumb Parts
The Thumb control does not have any named parts.
Thumb States
The following table lists the visual states for the Thumb control.
<Style x:Key="SliderThumbStyle"
TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Height"
<Setter Property="Height"
Value="14" />
<Setter Property="Width"
Value="14" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Ellipse x:Name="Ellipse"
StrokeThickness="1">
<Ellipse.Stroke>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
<GradientStop Color="{DynamicResource ControlLightColor}" />
</LinearGradientBrush>
</Ellipse.Fill>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Ellipse">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ToggleButton Syles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ToggleButton control. You can modify the default
ControlTemplate to give the control a unique appearance. For more information, see Customizing the Appearance
of an Existing Control by Creating a ControlTemplate.
ToggleButton Parts
The ToggleButton control does not have any named parts.
ToggleButton States
The following table lists the visual states for the ToggleButton control.
<ControlTemplate x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
(SolidColorBrush.Color)"
Storyboard.TargetName="Arrow">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledForegroundColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="2"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Grid.Column="0"
CornerRadius="2,0,0,2"
Margin="1" >
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}"/>
</Border.Background>
</Border>
<Path x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z" >
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}"/>
</Path.Fill>
</Path>
</Grid>
</ControlTemplate>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ToolBar Styles and Templates
5/22/2018 • 4 minutes to read • Edit Online
This topic describes the styles and templates for the ToolBar control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
ToolBar Parts
The following table lists the named parts for the ToolBar control.
When you create a ControlTemplate for a ToolBar, your template might contain an ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the ToolBar; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
ToolBar States
The following table lists the visual states for the ToolBar control.
<Style x:Key="ToolBarButtonBaseStyle"
TargetType="{x:Type ButtonBase}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="Border"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ToolBarThumbStyle"
TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Cursor"
Value="SizeAll" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="Transparent"
SnapsToDevicePixels="True">
<Rectangle Margin="0,2">
<Rectangle.Fill>
<DrawingBrush Viewport="0,0,4,4"
ViewportUnits="Absolute"
Viewbox="0,0,8,8"
ViewboxUnits="Absolute"
TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#AAA"
Geometry="M 4 4 L 4 8 L 8 8 L 8 4 z" />
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ToolBarOverflowButtonStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
CornerRadius="0,3,3,0"
SnapsToDevicePixels="true">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#00000000"
Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Path x:Name="Arrow"
Fill="Black"
VerticalAlignment="Bottom"
Margin="2,3"
Data="M -0.5 3 L 5.5 3 L 2.5 6 Z" />
<ContentPresenter />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Thumb x:Name="ToolBarThumb"
Style="{StaticResource ToolBarThumbStyle}"
Width="10" />
<ToolBarPanel x:Name="PART_ToolBarPanel"
IsItemsHost="true"
Margin="0,1,2,2" />
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsOverflowOpen"
Value="true">
<Setter TargetName="ToolBarThumb"
Property="IsEnabled"
Value="false" />
</Trigger>
<Trigger Property="ToolBarTray.IsLocked"
Value="true">
<Setter TargetName="ToolBarThumb"
Property="Visibility"
Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
ToolTip Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the ToolTip control. You can modify the default ControlTemplate to
give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
ToolTip Parts
The ToolTip control does not have any named parts.
ToolTip States
The following table lists the visual states for the ToolTip control.
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<ContentPresenter Margin="4"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow"
Value="true">
<Setter TargetName="Border"
Property="CornerRadius"
Value="4" />
<Setter TargetName="Border"
Property="SnapsToDevicePixels"
Value="true" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
TreeView Styles and Templates
5/22/2018 • 4 minutes to read • Edit Online
This topic describes the styles and templates for the TreeView control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
TreeView Parts
The TreeView control does not have any named parts.
When you create a ControlTemplate for an TreeView, your template might contain a ItemsPresenter within a
ScrollViewer. (The ItemsPresenter displays each item in the TreeView; the ScrollViewer enables scrolling within the
control). If the ItemsPresenter is not the direct child of the ScrollViewer, you must give the ItemsPresenter the
name, ItemsPresenter .
TreeView States
The following table lists the visual states for the TreeView control.
TreeViewItem Parts
The following table lists the named parts for the TreeViewItem control.
TreeViewItem States
The following table lists the visual states for TreeViewItem control.
<Style x:Key="ExpandCollapseToggleStyle"
TargetType="ToggleButton">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid Width="15"
Height="13"
Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Collapsed">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Expanded">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="Collapsed"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="1,1,1,1"
Data="M 4 0 L 8 4 L 4 8 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
<Path x:Name="Expanded"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="1,1,1,1"
Data="M 0 4 L 8 4 L 4 8 Z"
Visibility="Hidden">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="0,0,0,0"
StrokeThickness="5"
Stroke="Black"
StrokeDashArray="1 2"
Opacity="0" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type TreeViewItem}"
TargetType="{x:Type TreeViewItem}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding Path=HorizontalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding Path=VerticalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Padding"
Value="1,0,0,0" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource TreeViewItemFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19"
Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd"
Storyboard.TargetProperty="(Panel.Background).
(SolidColorBrush.Color)"
>
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource SelectedBackgroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unselected" />
<VisualState x:Name="SelectedInactive">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd"
Storyboard.TargetProperty="(Panel.Background).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource SelectedUnfocusedColor}" />
</ColorAnimationUsingKeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ExpansionStates">
<VisualState x:Name="Expanded">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ItemsHost">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ToggleButton x:Name="Expander"
Style="{StaticResource ExpandCollapseToggleStyle}"
ClickMode="Press"
IsChecked="{Binding IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"/>
<Border x:Name="Bd"
Grid.Column="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems"
Value="false">
<Setter TargetName="Expander"
Property="Visibility"
Value="Hidden" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader"
Value="false" />
<Condition Property="Width"
Value="Auto" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header"
Property="MinWidth"
Value="75" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader"
Value="false" />
<Condition Property="Height"
Value="Auto" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header"
Property="MinHeight"
Value="19" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
Window Styles and Templates
5/22/2018 • 2 minutes to read • Edit Online
This topic describes the styles and templates for the Window control. You can modify the default ControlTemplate
to give the control a unique appearance. For more information, see Customizing the Appearance of an Existing
Control by Creating a ControlTemplate.
Window Parts
The Window control does not have any named parts.
Window States
The following table lists the visual states for the Window control.
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
See Also
Style
ControlTemplate
Control Styles and Templates
Control Customization
Styling and Templating
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
UI Automation of a WPF Custom Control
8/31/2018 • 8 minutes to read • Edit Online
Microsoft UI Automation provides a single, generalized interface that automation clients can use to examine or
operate the user interfaces of a variety of platforms and frameworks. UI Automation enables both quality-
assurance (test) code and accessibility applications such as screen readers to examine user-interface elements and
simulate user interaction with them from other code. For information about UI Automation across all platforms,
see Accessibility.
This topic describes how to implement a server-side UI Automation provider for a custom control that runs in a
WPF application. WPF supports UI Automation through a tree of peer automation objects that parallels the tree of
user interface elements. Test code and applications that provide accessibility features can use automation peer
objects directly (for in-process code) or through the generalized interface provided by UI Automation.
Peer Navigation
After locating an automation peer, in-process code can navigate the peer tree by calling the object's GetChildren
and GetParent methods. Navigation among WPF elements within a control is supported by the peer's
implementation of the GetChildrenCore method. The UI Automation system calls this method to build up a tree of
subelements contained within a control; for example, list items in a list box. The default
UIElementAutomationPeer.GetChildrenCore method traverses the visual tree of elements to build the tree of
automation peers. Custom controls override this method to expose children elements to automation clients,
returning the automation peers of elements that convey information or allow user interaction.
A GetPattern method can also specify a subelement as a pattern provider. The following code shows how
ItemsControl transfers scroll pattern handling to the peer of its internal ScrollViewer control.
public override object GetPattern(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.Scroll)
{
ItemsControl owner = (ItemsControl) base.Owner;
To specify a subelement for pattern handling, this code gets the subelement object, creates a peer by using the
CreatePeerForElement method, sets the EventsSource property of the new peer to the current peer, and returns
the new peer. Setting EventsSource on a subelement prevents the subelement from appearing in the automation
peer tree and designates all events raised by the subelement as originating from the control specified in
EventsSource. The ScrollViewer control does not appear in the automation tree, and scrolling events that it
generates appear to originate from the ItemsControl object.
Override "Core" Methods
Automation code gets information about your control by calling public methods of the peer class. To provide
information about your control, override each method whose name ends with "Core" when your control
implementation differs from that of that provided by the base automation peer class. At a minimum, your control
must implement the GetClassNameCore and GetAutomationControlTypeCore methods, as shown in the following
example.
protected override string GetClassNameCore()
{
return "NumericUpDown";
}
<Button AutomationProperties.Name="Special"
AutomationProperties.HelpText="This is a special button."/>
If the owning control derives from a specific type of control such as RangeBase, the peer can be derived from an
equivalent derived peer class. In this case, the peer would derive from RangeBaseAutomationPeer, which supplies
a base implementation of IRangeValueProvider. The following code shows the declaration of such a peer.
For an example implementation, see NumericUpDown Custom Control with Theme and UI Automation Support
Sample.
Raise Events
Automation clients can subscribe to automation events. Custom controls must report changes to control state by
calling the RaiseAutomationEvent method. Similarly, when a property value changes, call the
RaisePropertyChangedEvent method. The following code shows how to get the peer object from within the control
code and call a method to raise an event. As an optimization, the code determines if there are any listeners for this
event type. Raising the event only when there are listeners avoids unnecessary overhead and helps the control
remain responsive.
if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
NumericUpDownAutomationPeer peer =
UIElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;
if (peer != null)
{
peer.RaisePropertyChangedEvent(
RangeValuePatternIdentifiers.ValueProperty,
(double)oldValue,
(double)newValue);
}
}
If AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged) Then
Dim peer As NumericUpDownAutomationPeer = TryCast(UIElementAutomationPeer.FromElement(nudCtrl),
NumericUpDownAutomationPeer)
See Also
UI Automation Overview
NumericUpDown Custom Control with Theme and UI Automation Support Sample
Server-Side UI Automation Provider Implementation
Walkthroughs: Create a Custom Animated Button
5/4/2018 • 2 minutes to read • Edit Online
As its name suggests, Windows Presentation Foundation (WPF ) is great for making rich presentation experiences
for customers. These walkthroughs show you how to customize the look and behavior of a button (including
animations). This customization is done using a style and template so that you can apply this custom button easily
to any buttons in your application. The following illustration shows the customized button that you will create.
The vector graphics that make up the appearance of the button are created by using Extensible Application Markup
Language (XAML ). XAML is similar to HTML except it is more powerful and extensible. Extensible Application
Markup Language (XAML ) can be typed in manually using Microsoft Visual Studio or Notepad, or you can use a
visual design tool such as Microsoft Expression Blend. Expression Blend works by creating underlying XAML code,
so both methods create the same graphics.
In This Section
Create a Button by Using Microsoft Expression Blend
Demonstrates how to create buttons with custom behavior by using the designer features of Expression Blend.
Create a Button by Using XAML
Demonstrates how to create buttons with custom behavior by using XAML and Visual Studio.
Related Sections
Styling and Templating
Describes how styles and templates can be used to determine the appearance and behavior of controls.
Animation Overview
Describes how objects can be animated by using the WPF animation and timing system.
Painting with Solid Colors and Gradients Overview
Describes how to use brush objects to paint with solid colors, linear gradients, and radial gradients.
Bitmap Effects Overview
Describes the bitmap effects supported by WPF and explains how to apply them.
Walkthrough: Create a Button by Using Microsoft
Expression Blend
5/4/2018 • 10 minutes to read • Edit Online
This walkthrough steps you through the process of creating a WPF customized button using Microsoft Expression
Blend.
IMPORTANT
Microsoft Expression Blend works by generating Extensible Application Markup Language (XAML) that is then compiled to
make the executable program. If you would rather work with Extensible Application Markup Language (XAML) directly, there
is another walkthrough that creates the same application as this one using Extensible Application Markup Language (XAML)
with Visual Studio rather than Blend. See Create a Button by Using XAML for more information.
The following illustration shows the customized button that you will create.
2. Draw a rectangle approximately the size of a button on the Window: Select the rectangle tool on the
left-hand tool panel and drag the rectangle onto the Window.
3. Round out the corners of the rectangle: Either drag the control points of the rectangle or directly set the
RadiusX and RadiusY properties. Set the values of RadiusX and RadiusY to 20.
4. Change the rectangle into a button: Select the rectangle. On the Tools menu, click Make Button.
5. Specify the scope of the style/template: A dialog box like the following appears.
For Resource name (Key), select Apply to all. This will make the resulting style and button template
apply to all objects that are buttons. For Define in, select Application. This will make the resulting style
and button template have scope over the entire application. When you set the values in these two boxes, the
button style and template apply to all buttons within the entire application and any button you create in the
application will, by default, use this template.
In the template editor, notice that the button is now separated into a Rectangle and the ContentPresenter.
The ContentPresenter is used to present content within the button (for example, the string "Button"). Both
the rectangle and ContentPresenter are laid out inside of a Grid.
2. Change the names of the template components: Right-click the rectangle in the template inventory,
change the Rectangle name from "[Rectangle]" to "outerRectangle", and change "[ContentPresenter]" to
"myContentPresenter".
3. Alter the rectangle so that it is empty inside (like a donut): Select outerRectangle and set Fill to
"Transparent" and StrokeThickness to 5.
Then set the Stroke to the color of whatever the template will be. To do this, click the small white box next to
Stroke, select CustomExpression, and type "{TemplateBinding Background}" in the dialog box.
4. Create an inner rectangle: Now, create another rectangle (name it "innerRectangle") and position it
symmetrically on the inside of outerRectangle . For this kind of work, you will probably want to zoom to
make the button larger in the editing area.
NOTE
Your rectangle might look different than the one in the figure (for example, it might have rounded corners).
5. Move ContentPresenter to the top: At this point, it is possible that the text "Button" will not be visible
any longer. If this is so, this is because innerRectangle is on top of the myContentPresenter. To fix this,
drag myContentPresenter below innerRectangle. Reposition rectangles and myContentPresenter to
look similar to below.
NOTE
Alternatively, you can also position myContentPresenter on top by right-clicking it and pressing Send Forward.
6. Change the look of innerRectangle: Set the RadiusX, RadiusY, and StrokeThickness values to 20. In
addition, set the Fill to the background of the template using the custom expression "{TemplateBinding
Background}" ) and set Stroke to "transparent". Notice that the settings for the Fill and Stroke of
innerRectangle are the opposite of those for outerRectangle.
7. Add a glass layer on top: The final piece of customizing the look of the button is to add a glass layer on
top. This glass layer consists of a third rectangle. Because the glass will cover the entire button, the glass
rectangle is similar in dimensions to the outerRectangle. Therefore, create the rectangle by simply making
a copy of the outerRectangle. Highlight outerRectangle and use CTRL+C and CTRL+V to make a copy.
Name this new rectangle "glassCube".
8. Reposition glassCube if necessary: If glassCube is not already positioned so that it covers the entire
button, drag it into position.
9. Give glassCube a slightly different shape than outerRectangle: Change the properties of glassCube.
Start off by changing the RadiusX and RadiusY properties to 10 and the StrokeThickness to 2.
10. Make glassCube look like glass: Set the Fill to a glassy look by using a linear gradient that is 75%
opaque and alternates between the color White and Transparent over 6 approximately evenly spaced
intervals. This is what to set the gradient stops to:
Gradient Stop 1: White with Alpha value of 75%
Gradient Stop 2: Transparent
Gradient Stop 3: White with Alpha value of 75%
Gradient Stop 4: Transparent
Gradient Stop 5: White with Alpha value of 75%
Gradient Stop 6: Transparent
This creates a "wavy" glass look.
11. Hide the glass layer: Now that you see what the glassy layer looks like, go into the Appearance pane of
the Properties panel and set the Opacity to 0% to hide it. In the sections ahead, we'll use property triggers
and events to show and manipulate the glass layer.
You have now created your first property trigger. Notice that the Triggers panel of the editor has recorded
the Opacity being changed to 100%.
Press F5 to run the application, and move the mouse pointer over and off the button. You should see the
glass layer appear when you mouse-over the button and disappear when the pointer leaves.
4. IsMouseOver triggers stroke value change: Let's associate some other actions with the IsMouseOver
trigger. While recording continues, switch your selection from glassCube to outerRectangle. Then set the
Stroke of outerRectangle to the custom expression of "{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}". This sets the Stroke to the typical highlight color used by buttons.
Press F5 to see the effect when you mouse over the button.
5. IsMouseOver triggers blurry text: Let's associate one more action to the IsMouseOver property trigger.
Make the content of the button appear a little blurry when the glass appears over it. To do this, we can apply
a blur BitmapEffect to the ContentPresenter (myContentPresenter).
NOTE
To return the Properties panel back to what it was before you did the search for BitmapEffect, clear the text from
the Search box.
At this point, we have used a property trigger with several associated actions to create highlighting
behavior for when the mouse pointer enters and leaves the button area. Another typical behavior for a
button is to highlight when it has focus (as after it is clicked). We can add such behavior by adding another
property trigger for the IsFocused property.
6. Create property trigger for IsFocused: Using the same procedure as for IsMouseOver (see the first step
of this section), create another property trigger for the IsFocused property. While Trigger recording is on,
add the following actions to the trigger:
glassCube gets an Opacity of 100%.
outerRectangle gets a Stroke custom expression value of "{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}".
As the final step in this walkthrough, we will add animations to the button. These animations will be triggered by
events—specifically, the MouseEnter and Click events.
To use event triggers and animations to add interactivity
1. Create a MouseEnter Event Trigger: Add a new event trigger and select MouseEnter as the event to use
in the trigger.
2. Create an animation timeline: Next, associate an animation timeline to the MouseEnter event.
After you press OK to create a new timeline, a Timeline Panel appears and "Timeline recording is on" is
visible in the design panel. This means we can start recording property changes in the timeline (animate
property changes).
NOTE
You may need to resize your window and/or panels to see the display.
3. Create a keyframe: To create an animation, select the object you want to animate, create two or more
keyframes on the timeline, and for those keyframes, set the property values you want the animation to
interpolate between. The following figure guides you through the creation of a keyframe.
4. Shrink glassCube at this keyframe: With the second keyframe selected, shrink the size of the glassCube
to 90% of its full size using the Size Transform.
Press F5 to run the application. Move the mouse pointer over the button. Notice that the glass layer shrinks
on top of the button.
5. Create another Event Trigger and associate a different animation with it: Let's add one more
animation. Use a similar procedure to what you used to create the previous event trigger animation:
a. Create a new event trigger using the Click event.
b. Associate a new timeline with the Click event.
a. For this timeline, create two keyframes, one at 0.0 seconds and the second one at 0.3 seconds.
b. With the keyframe at 0.3 seconds highlighted, set the Rotate Transform Angle to 360 degrees.
a. Press F5 to run the application. Click the button. Notice that the glass layer spins around.
Conclusion
You have completed a customized button. You did this using a button template that was applied to all buttons in
the application. If you leave the template editing mode (see the following figure) and create more buttons, you will
see that they look and behave like your custom button rather than like the default button.
Press F5 to run the application. Click the buttons and notice how they all behave the same.
Remember that while you were customizing the template, you set the Fill property of innerRectangle and the
Stroke property outerRectangle to the template background ({TemplateBinding Background}). Because of this,
when you set the background color of the individual buttons, the background you set will be used for those
respective properties. Try changing the backgrounds now. In the following figure, different gradients are used.
Therefore, although a template is useful for overall customization of controls like button, controls with templates
can still be modified to look different from each other.
In conclusion, in the process of customizing a button template you have learned how to do the following in
Microsoft Expression Blend:
Customize the look of a control.
Set property triggers. Property triggers are very useful because they can be used on most objects, not just
controls.
Set event triggers. Event triggers are very useful because they can be used on most objects, not just
controls.
Create animations.
Miscellaneous: create gradients, add BitmapEffects, use transforms, and set basic properties of objects.
See Also
Create a Button by Using XAML
Styling and Templating
Animation Overview
Painting with Solid Colors and Gradients Overview
Bitmap Effects Overview
Walkthrough: Create a Button by Using XAML
7/18/2018 • 12 minutes to read • Edit Online
The objective of this walkthrough is to learn how to create an animated button for use in a Windows Presentation
Foundation (WPF ) application. This walkthrough uses styles and a template to create a customized button
resource that allows reuse of code and separation of button logic from the button declaration. This walkthrough is
written entirely in Extensible Application Markup Language (XAML ).
IMPORTANT
This walkthrough guides you through the steps for creating the application by typing or copying and pasting Extensible
Application Markup Language (XAML) into Microsoft Visual Studio. If you would prefer to learn how to use a design tool
(Microsoft Expression Blend) to create the same application, see Create a Button by Using Microsoft Expression Blend.
Press F5 to run the application; you should see a set of buttons that looks like the following figure.
Now that you have created the basic buttons, you are finished working in the Window1.xaml file. The rest
of the walkthrough focuses on the app.xaml file, defining styles and a template for the buttons.
<Application x:Class="AnimatedButton.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
>
<Application.Resources>
<!-- Resources for the entire application can be defined here. -->
</Application.Resources>
</Application>
Resource scope is determined by where you define the resource. Defining resources in
Application.Resources in the app.xaml file enables the resource to be used from anywhere in the
application. To learn more about defining the scope of your resources, see XAML Resources.
2. Create a style and define basic property values with it: Add the following markup to the
Application.Resources block. This markup creates a Style that applies to all buttons in the application,
setting the Width of the buttons to 90 and the Margin to 10:
<Application.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="90" />
<Setter Property="Margin" Value="10" />
</Style>
</Application.Resources>
The TargetType property specifies that the style applies to all objects of type Button. Each Setter sets a
different property value for the Style. Therefore, at this point every button in the application has a width of
90 and a margin of 10. If you press F5 to run the application, you see the following window.
There is much more you can do with styles, including a variety of ways to fine-tune what objects are
targeted, specifying complex property values, and even using styles as input for other styles. For more
information, see Styling and Templating.
3. Set a style property value to a resource: Resources enable a simple way to reuse commonly defined
objects and values. It is especially useful to define complex values using resources to make your code more
modular. Add the following highlighted markup to app.xaml.
<Application.Resources>
<LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0" />
<GradientStop Color="#CCCCFF" Offset="0.5" />
<GradientStop Color="DarkGray" Offset="1" />
</LinearGradientBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />
<Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" />
</Style>
</Application.Resources>
Directly under the Application.Resources block, you created a resource called "GrayBlueGradientBrush".
This resource defines a horizontal gradient. This resource can be used as a property value from anywhere
in the application, including inside the button style setter for the Background property. Now, all the buttons
have a Background property value of this gradient.
Press F5 to run the application. It should look like the following.
Create a Template That Defines the Look of the Button
In this section, you create a template that customizes the appearance (presentation) of the button. The button
presentation is made up of several objects including rectangles and other components to give the button a unique
look.
So far, the control of how buttons look in the application has been confined to changing properties of the button.
What if you want to make more radical changes to the button's appearance? Templates enable powerful control
over the presentation of an object. Because templates can be used within styles, you can apply a template to all
objects that the style applies to (in this walkthrough, the button).
To use the template to define the look of the button
1. Set up the template: Because controls like Button have a Template property, you can define the template
property value just like the other property values we have set in a Style using a Setter. Add the following
highlighted markup to your button style.
<Application.Resources>
<LinearGradientBrush x:Key="GrayBlueGradientBrush"
StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0" />
<GradientStop Color="#CCCCFF" Offset="0.5" />
<GradientStop Color="DarkGray" Offset="1" />
</LinearGradientBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />
<Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" />
<Setter Property="Template">
<Setter.Value>
<!-- The button template is defined here. -->
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
2. Alter button presentation: At this point, you need to define the template. Add the following highlighted
markup. This markup specifies two Rectangle elements with rounded edges, followed by a DockPanel. The
DockPanel is used to host the ContentPresenter of the button. A ContentPresenter displays the content of
the button. In this walkthrough, the content is text ("Button 1", "Button 2", "Button 3"). All of the template
components (the rectangles and the DockPanel) are laid out inside of a Grid.
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<!-- Outer Rectangle with rounded corners. -->
<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent"
/>
<!-- Inner Rectangle with rounded corners. -->
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20"
/>
<!-- Present Content (text) of the button. -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}"
TextBlock.Foreground="Black" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
3. Add a glasseffect to the template: Next you will add the glass. First you create some resources that
create a glass gradient effect. Add these gradient resources anywhere within the Application.Resources
block:
<Application.Resources>
<GradientStopCollection x:Key="MyGlassGradientStopsResource">
<GradientStop Color="WhiteSmoke" Offset="0.2" />
<GradientStop Color="Transparent" Offset="0.4" />
<GradientStop Color="WhiteSmoke" Offset="0.5" />
<GradientStop Color="Transparent" Offset="0.75" />
<GradientStop Color="WhiteSmoke" Offset="0.9" />
<GradientStop Color="Transparent" Offset="1" />
</GradientStopCollection>
<LinearGradientBrush x:Key="MyGlassBrushResource"
StartPoint="0,0" EndPoint="1,1" Opacity="0.75"
GradientStops="{StaticResource MyGlassGradientStopsResource}" />
<!-- Styles and other resources below here. -->
These resources are used as the Fill for a rectangle that we insert into the Grid of the button template. Add
the following highlighted markup to the template.
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
ClipToBounds="True">
Notice that the Opacity of the rectangle with the x:Name property of "glassCube" is 0, so when you run the
sample, you do not see the glass rectangle overlaid on top. This is because we will later add triggers to the
template for when the user interacts with the button. However, you can see what the button looks like now
by changing the Opacity value to 1 and running the application. See the following figure. Before proceeding
to the next step, change the Opacity back to 0.
Create Button Interactivity
In this section, you will create property triggers and event triggers to change property values and run animations
in response to user actions such as moving the mouse pointer over the button and clicking.
An easy way to add interactivity (mouse-over, mouse-leave, click, and so on) is to define triggers within your
template or style. To create a Trigger, you define a property "condition" such as: The button IsMouseOver property
value is equal to true . You then define setters (actions) that take place when the trigger condition is true.
To create button interactivity
1. Add template triggers: Add the highlighted markup to your template.
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}" ClipToBounds="True">
<ControlTemplate.Triggers> <!-- Set action triggers for the buttons and define
what the button does in response to those triggers. --> </ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
2. Add property triggers: Add the highlighted markup to the ControlTemplate.Triggers block:
<ControlTemplate.Triggers>
<!-- Set properties when mouse pointer is over the button. --> <Trigger Property="IsMouseOver"
Value="True"> <!-- Below are three property settings that occur when the condition is met
(user mouses over button). --> <!-- Change the color of the outer rectangle when user
mouses over it. --> <Setter Property ="Rectangle.Stroke" TargetName="outerRectangle" Value="
{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <!-- Sets the glass opacity to 1,
therefore, the glass "appears" when user mouses over it. --> <Setter
Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <!-- Makes the text slightly
blurry as though you were looking at it through blurry glass. --> <Setter
Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter"> <Setter.Value>
<BlurBitmapEffect Radius="1" /> </Setter.Value> </Setter> </Trigger>
<ControlTemplate.Triggers/>
Press F5 to run the application and see the effect as you run the mouse pointer over the buttons.
3. Add a focus trigger: Next, we'll add some similar setters to handle the case when the button has focus (for
example, after the user clicks it).
<ControlTemplate.Triggers>
<!-- Set properties when mouse pointer is over the button. -->
<Trigger Property="IsMouseOver" Value="True">
<!-- Below are three property settings that occur when the
condition is met (user mouses over button). -->
<!-- Change the color of the outer rectangle when user mouses over it. -->
<Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it.
-->
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
<!-- Makes the text slightly blurry as though you were looking at it through blurry glass.
-->
<Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter">
<Setter.Value>
<BlurBitmapEffect Radius="1" />
</Setter.Value>
</Setter>
</Trigger>
<!-- Set properties when button has focus. --> <Trigger Property="IsFocused" Value="true">
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <Setter
Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}" /> <Setter Property="Rectangle.Opacity" Value="1"
TargetName="glassCube" /> </Trigger>
</ControlTemplate.Triggers>
Press F5 to run the application and click on one of the buttons. Notice that the button stays highlighted
after you click it because it still has focus. If you click another button, the new button gains focus while the
last one loses it.
4. Add animations for MouseEnter and MouseLeave : Next we add some animations to the triggers. Add
the following markup anywhere inside of the ControlTemplate.Triggers block.
<!-- Animations that start when mouse enters and leaves button. -->
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="mouseEnterBeginStoryboard">
<Storyboard>
<!-- This animation makes the glass rectangle shrink in the X direction. -->
<DoubleAnimation Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
By="-0.1" Duration="0:0:0.5" />
<!-- This animation makes the glass rectangle shrink in the Y direction. -->
<DoubleAnimation
Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
By="-0.1" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<!-- Stopping the storyboard sets all animated properties back to default. -->
<StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" />
</EventTrigger.Actions>
</EventTrigger>
The glass rectangle shrinks when the mouse pointer moves over the button and returns back to normal size
when the pointer leaves.
There are two animations that are triggered when the pointer goes over the button (MouseEnter event is
raised). These animations shrink the glass rectangle along the X and Y axis. Notice the properties on the
DoubleAnimation elements — Duration and By. The Duration specifies that the animation occurs over half
a second, and By specifies that the glass shrinks by 10%.
The second event trigger (MouseLeave) simply stops the first one. When you stop a Storyboard, all the
animated properties return to their default values. Therefore, when the user moves the pointer off the
button, the button goes back to the way it was before the mouse pointer moved over the button. For more
information about animations, see Animation Overview.
5. Add an animation for when the button is clicked: The final step is to add a trigger for when the user
clicks the button. Add the following markup anywhere inside of the ControlTemplate.Triggers block:
<!-- Animation fires when button is clicked, causing glass to spin. -->
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)"
By="360" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
Press F5 to run the application, and click one of the buttons. When you click a button, the glass rectangle
spins around.
Summary
In this walkthrough, you performed the following exercises:
Targeted a Style to an object type (Button).
Controlled basic properties of the buttons in the entire application using the Style.
Created resources like gradients to use for property values of the Style setters.
Customized the look of buttons in the entire application by applying a template to the buttons.
Customized behavior for the buttons in response to user actions (such as MouseEnter, MouseLeave, and
Click) that included animation effects.
See Also
Create a Button by Using Microsoft Expression Blend
Styling and Templating
Animation Overview
Painting with Solid Colors and Gradients Overview
Bitmap Effects Overview