Control Library 3 프로그래밍/WPF2016. 11. 18. 23:20
https://msdn.microsoft.com/en-us/library/ms752060(v=vs.110).aspx
StackPanel
StackPanel Class
Arranges child elements into a single line that can be oriented horizontally or vertically.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Panel
System.Windows.Controls.StackPanel
System.Windows.Controls.Primitives.ToolBarPanel
System.Windows.Controls.Ribbon.Primitives.RibbonGroupsPanel
Remarks
A StackPanel contains a collection of UIElement objects, which are in the Children property.
The default value is stretch for both HorizontalAlignment and VerticalAlignment of content that is contained in a StackPanel.
Panel elements do not receive focus by default. To compel a panel element to receive focus, set the Focusable property to true.
StackPanel implements the IScrollInfo interface to support logical scrolling. Logical scrolling is used to scroll to the next element in the logical tree. This is in contrast to physical scrolling, which scrolls content by a defined physical increment in a given direction. If you require physical scrolling instead of logical scrolling, wrap the host StackPanel element in a ScrollViewer and set its CanContentScroll property to false.
How to: Choose Between StackPanel and DockPanel
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.
// Create the application's main window mainWindow = new Window (); mainWindow.Title = "StackPanel vs. DockPanel"; // Add root Grid myGrid = new Grid(); myGrid.Width = 175; myGrid.Height = 150; RowDefinition myRowDef1 = new RowDefinition(); RowDefinition myRowDef2 = new RowDefinition(); myGrid.RowDefinitions.Add(myRowDef1); myGrid.RowDefinitions.Add(myRowDef2); // Define the DockPanel myDockPanel = new DockPanel(); Grid.SetRow(myDockPanel, 0); //Define an Image and Source Image myImage = new Image(); BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative); bi.EndInit(); myImage.Source = bi; Image myImage2 = new Image(); BitmapImage bi2 = new BitmapImage(); bi2.BeginInit(); bi2.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative); bi2.EndInit(); myImage2.Source = bi2; Image myImage3 = new Image(); BitmapImage bi3 = new BitmapImage(); bi3.BeginInit(); bi3.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative); bi3.EndInit(); myImage3.Stretch = Stretch.Fill; myImage3.Source = bi3; // Add the images to the parent DockPanel myDockPanel.Children.Add(myImage); myDockPanel.Children.Add(myImage2); myDockPanel.Children.Add(myImage3); //Define a StackPanel myStackPanel = new StackPanel(); myStackPanel.Orientation = Orientation.Horizontal; Grid.SetRow(myStackPanel, 1); Image myImage4 = new Image(); BitmapImage bi4 = new BitmapImage(); bi4.BeginInit(); bi4.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative); bi4.EndInit(); myImage4.Source = bi4; Image myImage5 = new Image(); BitmapImage bi5 = new BitmapImage(); bi5.BeginInit(); bi5.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative); bi5.EndInit(); myImage5.Source = bi5; Image myImage6 = new Image(); BitmapImage bi6 = new BitmapImage(); bi6.BeginInit(); bi6.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative); bi6.EndInit(); myImage6.Stretch = Stretch.Fill; myImage6.Source = bi6; // Add the images to the parent StackPanel myStackPanel.Children.Add(myImage4); myStackPanel.Children.Add(myImage5); myStackPanel.Children.Add(myImage6); // Add the layout panels as children of the Grid myGrid.Children.Add(myDockPanel); myGrid.Children.Add(myStackPanel); // Add the Grid as the Content of the Parent Window Object mainWindow.Content = myGrid; mainWindow.Show ();
<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> <DockPanel Grid.Column="0" Grid.Row="0"> <Image Source="smiley_stackpanel.png" /> <Image Source="smiley_stackpanel.png" /> <Image Source="smiley_stackpanel.png" Stretch="Fill"/> </DockPanel> <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal"> <Image Source="smiley_stackpanel.png" /> <Image Source="smiley_stackpanel.png" /> <Image Source="smiley_stackpanel.png" Stretch="Fill"/> </StackPanel> </Grid> </Page>
How to: Create a StackPanel
This example shows how to create a StackPanel.
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.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="StackPanel Sample"> <StackPanel> <Border Background="SkyBlue" BorderBrush="Black" BorderThickness="1"> <TextBlock Foreground="Black" FontSize="12">Stacked Item #1</TextBlock> </Border> <Border Width="400" Background="CadetBlue" BorderBrush="Black" BorderThickness="1"> <TextBlock Foreground="Black" FontSize="14">Stacked Item #2</TextBlock> </Border> <Border Background="LightGoldenRodYellow" BorderBrush="Black" BorderThickness="1"> <TextBlock Foreground="Black" FontSize="16">Stacked Item #3</TextBlock> </Border> <Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1"> <TextBlock Foreground="Black" FontSize="18">Stacked Item #4</TextBlock> </Border> <Border Background="White" BorderBrush="Black" BorderThickness="1"> <TextBlock Foreground="Black" FontSize="20">Stacked Item #5</TextBlock> </Border> </StackPanel> </Page>
How to: Horizontally or Vertically Align Content in a StackPanel
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.
<ListBox VerticalAlignment="Top" SelectionChanged="changeOrientation" Grid.Row="2" Grid.Column="1" Width="100" Height="50" Margin="0,0,0,10"> <ListBoxItem>Horizontal</ListBoxItem> <ListBoxItem>Vertical</ListBoxItem> </ListBox> <ListBox VerticalAlignment="Top" SelectionChanged="changeHorAlign" Grid.Row="2" Grid.Column="3" Width="100" Height="50" Margin="0,0,0,10"> <ListBoxItem>Left</ListBoxItem> <ListBoxItem>Right</ListBoxItem> <ListBoxItem>Center</ListBoxItem> <ListBoxItem>Stretch</ListBoxItem> </ListBox> <ListBox VerticalAlignment="Top" SelectionChanged="changeVertAlign" Grid.Row="2" Grid.Column="5" Width="100" Height="50" Margin="0,0,0,10"> <ListBoxItem>Top</ListBoxItem> <ListBoxItem>Bottom</ListBoxItem> <ListBoxItem>Center</ListBoxItem> <ListBoxItem>Stretch</ListBoxItem> </ListBox> <StackPanel Grid.ColumnSpan="6" Grid.Row="3" Name="sp1" Background="Yellow"> <Button>Button One</Button> <Button>Button Two</Button> <Button>Button Three</Button> <Button>Button Four</Button> <Button>Button Five</Button> <Button>Button Six</Button> </StackPanel>
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; } } private void changeHorAlign(object sender, SelectionChangedEventArgs args) { ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem); if (li.Content.ToString() == "Left") { sp1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; } else if (li.Content.ToString() == "Right") { sp1.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; } else if (li.Content.ToString() == "Center") { sp1.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; } else if (li.Content.ToString() == "Stretch") { sp1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; } } private void changeVertAlign(object sender, SelectionChangedEventArgs args) { ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem); if (li.Content.ToString() == "Top") { sp1.VerticalAlignment = System.Windows.VerticalAlignment.Top; } else if (li.Content.ToString() == "Bottom") { sp1.VerticalAlignment = System.Windows.VerticalAlignment.Bottom; } else if (li.Content.ToString() == "Center") { sp1.VerticalAlignment = System.Windows.VerticalAlignment.Center; } else if (li.Content.ToString() == "Stretch") { sp1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch; } }
StatusBar
StatusBar Class
Represents a control that displays items and information in a horizontal bar in an application window.
Namespace: System.Windows.Controls.Primitives
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
StatusBar is an ItemsControl, which means it can contain a collection of objects of any type (such as string, image, or panel). For more information, see the ItemsControl class.
A StatusBar is a bar that typically displays a horizontal row of images and status information. You can divide the items in a StatusBar into groups that contain related items, by using Separator controls. The items in a StatusBar can display text, graphics, or other complex content. Items in a StatusBarare defined as StatusBarItem objects.
Events that are defined on a StatusBarItem are raised when the user clicks the item in the StatusBar.
The StatusBar does not receive keyboard focus.
The following illustration shows an example of a StatusBar.
Status Bar

Customizing the StatusBar Control
To apply the same property settings to multiple StatusBar controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the StatusBar, see StatusBar Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in Button control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example creates a StatusBar.
<StatusBar Name="sbar" VerticalAlignment="Bottom" Background="Beige" > <StatusBarItem> <TextBlock>Downloading File</TextBlock> </StatusBarItem> <StatusBarItem> <ProgressBar Width="100" Height="20" Name="progressBar1"> <ProgressBar.Triggers> <EventTrigger RoutedEvent="ProgressBar.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="progressBar1" Storyboard.TargetProperty="Value" From="0" To="100" Duration="0:0:5" /> </Storyboard> </BeginStoryboard> </EventTrigger> </ProgressBar.Triggers> </ProgressBar> </StatusBarItem> <Separator/> <StatusBarItem> <TextBlock>Online</TextBlock> </StatusBarItem> <StatusBarItem HorizontalAlignment="Right"> <Image Source="images\help.bmp" Width="16" Height="16"/> </StatusBarItem> </StatusBar>
StatusBarItem Class
Represents an item of a StatusBar control.
Namespace: System.Windows.Controls.Primitives
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
A StatusBarItem is a ContentControl, which means that it can contain a single object of any type (such as a string, an image, or a panel). For more information, see the ContentControl class.
StatusBarItem objects are used to define items in a StatusBar control. A StatusBar is a horizontal area at the bottom of a parent window in which an application can display status information. A StatusBarItem can contain complex content, such as graphics and text, and can receive events. The StatusBar and StatusBarItem objects cannot receive keyboard focus.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
Examples
The following example creates a StatusBar.
<StatusBar Name="sbar" VerticalAlignment="Bottom" Background="Beige" > <StatusBarItem> <TextBlock>Downloading File</TextBlock> </StatusBarItem> <StatusBarItem> <ProgressBar Width="100" Height="20" Name="progressBar1"> <ProgressBar.Triggers> <EventTrigger RoutedEvent="ProgressBar.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="progressBar1" Storyboard.TargetProperty="Value" From="0" To="100" Duration="0:0:5" /> </Storyboard> </BeginStoryboard> </EventTrigger> </ProgressBar.Triggers> </ProgressBar> </StatusBarItem> <Separator/> <StatusBarItem> <TextBlock>Online</TextBlock> </StatusBarItem> <StatusBarItem HorizontalAlignment="Right"> <Image Source="images\help.bmp" Width="16" Height="16"/> </StatusBarItem> </StatusBar>
TabControl
TabControl Class
Represents a control that contains multiple items that share the same space on the screen.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
System.Windows.Controls.Primitives.Selector
System.Windows.Controls.TabControl
Remarks
The TabControl is useful for minimizing screen space usage while allowing an application to expose a large amount of data. A TabControl consists of multiple TabItem objects that share the same screen space. Only one TabItem in a TabControl is visible at a time. When a user selects the tab of a TabItem, the contents of that TabItem become visible and the contents of the other TabItem objects are hidden.
TabControl is an ItemsControl, which means it can contain a collection of objects of any type (such as string, image, or panel). For more information, see the ItemsControl class.
Customizing the TabControl Control
To apply the same property settings to multiple TabControl controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the TabControl, see TabControl Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in TabControl control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example creates a TabControl and binds the TextBlock in the second TabItem to a TextBox in the first TabItem.
<TabControl> <TabItem> <TabItem.Header> <StackPanel Orientation="Horizontal"> <Ellipse Width="10" Height="10" Fill="DarkGray"/> <TextBlock>Tab 1</TextBlock> </StackPanel> </TabItem.Header> <StackPanel> <TextBlock>Enter some text</TextBlock> <TextBox Name="textBox1" Width="50"/> </StackPanel> </TabItem> <TabItem Header="Tab 2"> <!--Bind TextBlock.Text to the TextBox on the first TabItem.--> <TextBlock Text="{Binding ElementName=textBox1, Path=Text}"/> </TabItem> </TabControl>
TabItem Class
Represents a selectable item inside a TabControl.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ContentControl
System.Windows.Controls.HeaderedContentControl
System.Windows.Controls.TabItem
Remarks
TabItem is a HeaderedContentControl. Its content property is Content and its header property is Header. For more information, see the HeaderedContentControl class.
Customizing the TabControl Control
To apply the same property settings to multiple TabItem controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the TabItem, see TabControl Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in TabItem control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example shows how to create a TabControl with TabItem elements.
<TabControl TabStripPlacement="Top" Margin="0, 0, 0, 10"> <TabItem Name="tabIitemContent" Header="TabItem with Buttons"> <StackPanel> <Button Content="_OK"/> <Button Content="_Cancel"/> </StackPanel> </TabItem> <TabItem Name="backgroundcolor" Header="Background"> <TabItem.Content>Background property information goes here.</TabItem.Content> </TabItem> <TabItem Name="foregroundcolor" Header="Foreground"> <TabItem.Content>Foreground property information goes here.</TabItem.Content> </TabItem> <TabItem Name="bordercolor" Header="BorderColor"> <TabItem.Content>Border color property information goes here.</TabItem.Content> </TabItem> </TabControl>
TextBlock
TextBlock Overview
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.
<TextBlock FontSize="18" FontWeight="Bold" FontStyle="Italic"> Hello, world! </TextBlock>
Similarly, usage of the TextBlock element in code is relatively simple.
TextBlock Class
Provides a lightweight control for displaying small amounts of flow content.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
A TextBlock can contain a string in its Text property or Inline flow content elements, such as Bold, Hyperlink, and InlineUIContainer, in its Inlinesproperty.
TextBlock is designed to be lightweight, and is geared specifically at integrating small portions of flow content into a user interface (UI). TextBlock is optimized for single-line display, and provides good performance for displaying up to a few lines of content.
TextBlock is not optimized for scenarios that need to display more than a few lines of content; for such scenarios, a FlowDocument coupled with an appropriate viewing control is a better choice than TextBlock, in terms of performance. After TextBlock, FlowDocumentScrollViewer is the next lightest-weight control for displaying flow content, and simply provides a scrolling content area with minimal UI. FlowDocumentPageViewer is optimized around "page-at-a-time" viewing mode for flow content. Finally, FlowDocumentReader supports the richest set functionality for viewing flow content, but is correspondingly heavier-weight.
Horizontally aligning text within a TextBlock is done with the TextAlignment property. Aligning the TextBlock within the layout of the page is done with the HorizontalAlignment and VerticalAlignment properties.
Examples
The following example shows how to use the TextBlock element.
<TextBlock Name="textBlock1" TextWrapping="Wrap"> <Bold>TextBlock</Bold> is designed to be <Italic>lightweight</Italic>, and is geared specifically at integrating <Italic>small</Italic> portions of flow content into a UI. </TextBlock> <Button Width="100" Margin="10">Click Me</Button> <TextBlock Name="textBlock2" TextWrapping="Wrap" Background="AntiqueWhite" TextAlignment="Center" > By default, a TextBlock provides no UI beyond simply displaying its contents. </TextBlock> <Button Width="100" Margin="10">Click Me</Button>
The following figure shows how this example renders.

The following example shows how to shows how to achieve similar results programmatically.
TextBlock textBlock1 = new TextBlock(); TextBlock textBlock2 = new TextBlock(); textBlock1.TextWrapping = textBlock2.TextWrapping = TextWrapping.Wrap; textBlock2.Background = Brushes.AntiqueWhite; textBlock2.TextAlignment = TextAlignment.Center; textBlock1.Inlines.Add(new Bold(new Run("TextBlock"))); textBlock1.Inlines.Add(new Run(" is designed to be ")); textBlock1.Inlines.Add(new Italic(new Run("lightweight"))); textBlock1.Inlines.Add(new Run(", and is geared specifically at integrating ")); textBlock1.Inlines.Add(new Italic(new Run("small"))); textBlock1.Inlines.Add(new Run(" portions of flow content into a UI.")); textBlock2.Text = "By default, a TextBlock provides no UI beyond simply displaying its contents.";
TextBox
TextBox Overview
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.
Control | Real-time Spellchecking | Context Menu | Formatting commands like ToggleBold (Ctr+B) | FlowDocument content like images, paragraphs, tables, etc. |
---|---|---|---|---|
Yes | Yes | No | No. | |
Yes | Yes | Yes (see RichTextBox Overview) | Yes (see RichTextBox Overview) |
![]() |
---|
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 How to: 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 How to: 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 TextBoxexpands beyond the size of the frame or window that encloses it.
For more information on different tasks associated with using a TextBox, see TextBox How-to Topics.
Detect When Content Changes
Usually the TextChanged event should be used to detect whenever the text in a TextBox or RichTextBox changes, rather then KeyDown as you might expect. See How to: Detect When Text in a TextBox Has Changed for an example.
TextBox Class
Represents a control that can be used to display or edit unformatted text.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.Primitives.TextBoxBase
System.Windows.Controls.TextBox
System.Windows.Controls.Primitives.DatePickerTextBox
System.Windows.Controls.Ribbon.RibbonTextBox
Remarks
A TextBox control can contain only unformatted text in its Text property. The following graphic shows an example of a TextBox.

Example of a TextBox
TextBox is a composite control that is composed of several encapsulated components. Consequently, some events do not bubble up to the containing control because they are handled by encapsulated child elements. Because of this, application developers should listen for the tunneling version of an event (denoted by the prefix "Preview").
TextBox supports unformatted text only. For applications that require support for richer content, see RichTextBox. For applications that need to accept passwords or other sensitive input, see PasswordBox.
Horizontally and vertically aligning text within a TextBox is done with the HorizontalContentAlignment and VerticalContentAlignment properties. Aligning the TextBox within the layout of the page is done with the HorizontalAlignment and VerticalAlignment properties.
The best way to hide the border around a TextBox is to set the BorderThickness property of the TextBox to 0.
![]() |
---|
TextBox has built-in handling for the bubbling MouseUp and MouseDown events. Consequently, custom event handlers that listen for MouseUpor MouseDown events from a TextBox will not be called. If you need to respond to these events, listen for the tunneling PreviewMouseUp and PreviewMouseDown events instead, or register the handlers with the HandledEventsToo argument (this latter option is only available through code). Do not mark the event handled unless you deliberately want to disable TextBox native handling of these events, and be aware that this has notable effects on the control's UI. |
Scrollbars are not visible on a TextBox by default. To make scrollbars visible, set the VerticalScrollBarVisibility and HorizontalScrollBarVisibilityproperties to Visible or Auto.
Usually the TextChanged event should be used to detect whenever the text in a TextBox or RichTextBox changes rather then KeyDown as you might expect. See How to: Detect When Text in a TextBox Has Changed for an example.
Customizing the TextBox Control
To apply the same property settings to multiple TextBox controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the TextBox, see TextBox Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in TextBox control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
This example shows how to use the Text property to set the initial text contents of a TextBox control.
![]() |
---|
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. |
<TextBox Name="tbSettingText"> Initial text contents of the TextBox. </TextBox>
For additional examples, see the 4.0 version of this document: TextBox Class.
Create a Multiline TextBox Control
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 TextBoxexpands 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>
Detect When Text in a TextBox Has Changed
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.
Note: This event fires when the TextBox control is created and initially populated with text.
Enable Tab Characters in a TextBox Control
his 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>
Get a Collection of Lines from a TextBox
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.
StringCollection GetLinesCollectionFromTextBox(TextBox textBox) { StringCollection lines = new StringCollection(); // lineCount may be -1 if TextBox layout info is not up-to-date. int lineCount = textBox.LineCount; for (int line = 0; line < lineCount; line++) // GetLineText takes a zero-based line index. lines.Add(textBox.GetLineText(line)); return lines; }
Make a TextBox Control Read-Only
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.
Position the Cursor at the Beginning or End of Text in a TextBox Control
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
Retrieve a Text Selection
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 OnClickmethod 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> <Button Click="OnClick">Retrieve Selection</Button>
Set Focus in 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>
Set the Text Content of a TextBox Control
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).
Enable Spell Checking in a Text Editing Control
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; // Enable spellchecking on the TextBox. myTextBox.SpellCheck.IsEnabled = true; // Alternatively, the SetIsEnabled method could be used // to enable or disable spell checking like this: // SpellCheck.SetIsEnabled(myTextBox, true); myStackPanel.Children.Add(myTextBox); this.Content = myStackPanel; } } }
Use a Custom Context Menu with a TextBox
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 Clickattribute 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).
private void MenuChange(Object sender, RoutedEventArgs ags) { RadioButton rb = sender as RadioButton; if (rb == null || cxm == null) return; 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; } } void ClickPaste(Object sender, RoutedEventArgs args) { cxmTextBox.Paste(); } void ClickCopy(Object sender, RoutedEventArgs args) { cxmTextBox.Copy(); } void ClickCut(Object sender, RoutedEventArgs args) { cxmTextBox.Cut(); } void ClickSelectAll(Object sender, RoutedEventArgs args) { cxmTextBox.SelectAll(); } void ClickClear(Object sender, RoutedEventArgs args) { cxmTextBox.Clear(); } void ClickUndo(Object sender, RoutedEventArgs args) { cxmTextBox.Undo(); } void ClickRedo(Object sender, RoutedEventArgs args) { cxmTextBox.Redo(); } void ClickSelectLine(Object sender, RoutedEventArgs args) { int lineIndex = cxmTextBox.GetLineIndexFromCharacterIndex(cxmTextBox.CaretIndex); int lineStartingCharIndex = cxmTextBox.GetCharacterIndexFromLineIndex(lineIndex); int lineLength = cxmTextBox.GetLineLength(lineIndex); cxmTextBox.Select(lineStartingCharIndex, lineLength); } void CxmOpened(Object sender, RoutedEventArgs args) { // Only allow copy/cut if something is selected to copy/cut. if (cxmTextBox.SelectedText == "") cxmItemCopy.IsEnabled = cxmItemCut.IsEnabled = false; else cxmItemCopy.IsEnabled = cxmItemCut.IsEnabled = true; // Only allow paste if there is text on the clipboard to paste. if (Clipboard.ContainsText()) cxmItemPaste.IsEnabled = true; else cxmItemPaste.IsEnabled = false; }
Use Spell Checking with a Context Menu
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 { void OnWindowLoaded(object sender, RoutedEventArgs e) { //This is required for the first time ContextMenu invocation so that TextEditor doesnt handle it. myTextBox.ContextMenu = GetContextMenu(); } void tb_ContextMenuOpening(object sender, RoutedEventArgs e) { int caretIndex, cmdIndex; SpellingError spellingError; 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); } } // Gets a fresh context menu. private ContextMenu GetContextMenu() { ContextMenu cm = new ContextMenu(); //Can create STATIC custom menu items if exists here... MenuItem m1, m2, m3, m4; m1 = new MenuItem(); m1.Header = "File"; m2 = new MenuItem(); m2.Header = "Save"; m3 = new MenuItem(); m3.Header = "SaveAs"; m4 = new MenuItem(); m4.Header = "Recent Files"; //Can add functionality for the custom menu items here... cm.Items.Add(m1); cm.Items.Add(m2); cm.Items.Add(m3); cm.Items.Add(m4); return cm; } } }
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);
Add a Watermark to a TextBox
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.

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 { void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) { 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; } } } }
ToolBar
ToolBar Overview
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.
Specifying the Position of ToolBars in a ToolBarTray
Use the Band and BandIndex properties to position the ToolBar in the ToolBarTray. Band indicates the position in which the ToolBar is placed within its parent ToolBarTray. BandIndex indicates the order in which the ToolBar is placed within its band. The following example shows how use this property to place ToolBar controls inside a ToolBarTray.
<ToolBarTray Background="White"> <ToolBar Band="1" BandIndex="1"> <Button> <Image Source="toolbargraphics\cut.bmp" /> </Button> <Button> <Image Source="toolbargraphics\copy.bmp" /> </Button> <Button> <Image Source="toolbargraphics\paste.bmp" /> </Button> </ToolBar> <ToolBar Band="2" BandIndex="1"> <Button> <Image Source="toolbargraphics\undo.bmp" /> </Button> <Button> <Image Source="toolbargraphics\redo.bmp" /> </Button> </ToolBar> <ToolBar Band="2" BandIndex="2"> <Button> <Image Source="toolbargraphics\paint.bmp" /> </Button> <Button> <Image Source="toolbargraphics\spell.bmp" /> </Button> <Separator/> <Button> <Image Source="toolbargraphics\save.bmp" /> </Button> <Button> <Image Source="toolbargraphics\open.bmp" /> </Button> </ToolBar> </ToolBarTray>
ToolBars with Overflow Items
Often ToolBar controls contain more items than can fit into the toolbar's size. When this happens, the ToolBar displays an overflow button. To see the overflow items, a user clicks the overflow button and the items are shown in a pop-up window below the ToolBar. The following graphic shows a ToolBar with overflow items.

Toolbar with Overflow Items
You can specify when an item on a toolbar is placed on the overflow panel by setting the ToolBar.OverflowMode attached property to OverflowMode.Always, OverflowMode.Never, or OverflowMode.AsNeeded. The following example specifies that the last four buttons on the toolbar should always be on the overflow panel.
<ToolBarTray Background="White"> <ToolBar Band="1" BandIndex="1"> <Button> <Image Source="toolbargraphics\cut.bmp" /> </Button> <Button> <Image Source="toolbargraphics\copy.bmp" /> </Button> <Button> <Image Source="toolbargraphics\paste.bmp" /> </Button> <Button> <Image Source="toolbargraphics\undo.bmp" /> </Button> <Button> <Image Source="toolbargraphics\redo.bmp" /> </Button> <Button> <Image Source="toolbargraphics\paint.bmp" /> </Button> <Button> <Image Source="toolbargraphics\spell.bmp" /> </Button> <Separator/> <Button ToolBar.OverflowMode="Always"> <Image Source="toolbargraphics\save.bmp" /> </Button> <Button ToolBar.OverflowMode="Always"> <Image Source="toolbargraphics\open.bmp" /> </Button> <Button ToolBar.OverflowMode="Always"> <Image Source="toolbargraphics\print.bmp" /> </Button> <Button ToolBar.OverflowMode="Always"> <Image Source="toolbargraphics\preview.bmp" /> </Button> </ToolBar> </ToolBarTray>
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
Style Controls on a ToolBar
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:
Example
The following example defines styles for the controls within a ToolBar.
<Window.Resources> <!--Styles for controls in a toolbar.--> <Style x:Key="{x:Static ToolBar.SeparatorStyleKey}" TargetType="Separator"> <Setter Property="Background" Value="DarkBlue"/> <Setter Property="Width" Value="2"/> </Style> <Style x:Key="{x:Static ToolBar.ButtonStyleKey}" TargetType="Button"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontSize" Value="14"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <Style x:Key="{x:Static ToolBar.CheckBoxStyleKey}" TargetType="CheckBox"> <Setter Property="Foreground" Value="DarkSlateBlue"/> <Setter Property="FontSize" Value="14"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <Style x:Key="{x:Static ToolBar.MenuStyleKey}" TargetType="Menu"> <Setter Property="FontSize" Value="14"/> <Setter Property="FontStyle" Value="Italic"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Background" Value="LightSteelBlue"/> </Style> <Style x:Key="{x:Static ToolBar.RadioButtonStyleKey}" TargetType="RadioButton"> <Setter Property="Background" Value="LightSteelBlue"/> <Setter Property="FontSize" Value="14"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <Style x:Key="{x:Static ToolBar.TextBoxStyleKey}" 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 x:Key="{x:Static ToolBar.ComboBoxStyleKey}" TargetType="ComboBox"> <Setter Property="Background" Value="LightSteelBlue"/> <Setter Property="FontSize" Value="14"/> <Setter Property="MinWidth" Value="60"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <!--*********Styles for controls that are not in a toolbar.*********--> <Style TargetType="Separator"> <Setter Property="Background" Value="DarkBlue"/> <Setter Property="Width" Value="2"/> </Style> <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="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>
ToolBar Class
Provides a container for a group of commands or controls.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
System.Windows.Controls.HeaderedItemsControl
System.Windows.Controls.ToolBar
Remarks
ToolBar controls provide an overflow mechanism that places items that do not fit on the ToolBar into an overflow area. Only toolbar elements within a parent ToolBarTray can be moved or resized by the user.
ToolBar is a HeaderedItemsControl, which means its header and collection of objects can be of any type (such as string, image, or panel). For more information, see the HeaderedItemsControl class.
Customizing the ToolBar Control
To apply the same property settings to multiple ToolBar controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the ToolBar, see ToolBar Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in ToolBar control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example shows how to create a ToolBar inside a ToolBarTray.
<ToolBarTray Background="White"> <ToolBar Band="1" BandIndex="1"> <Button> <Image Source="toolbargraphics\new.bmp" /> </Button> <Button> <Image Source="toolbargraphics\open.bmp" /> </Button> <Button> <Image Source="toolbargraphics\save.bmp" /> </Button> <Separator/> <Button> <Image Source="toolbargraphics\cut.bmp" /> </Button> <Button> <Image Source="toolbargraphics\copy.bmp" /> </Button> <Button> <Image Source="toolbargraphics\paste.bmp" /> </Button> <Separator/> <Button> <Image Source="toolbargraphics\print.bmp" /> </Button> <Button> <Image Source="toolbargraphics\preview.bmp" /> </Button> </ToolBar> </ToolBarTray>
ToolTip
ToolTip Overview
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.
Which property you use depends on whether the control that defines the tooltip inherits from the FrameworkContentElement or FrameworkElementclass.
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.
<Button ToolTip="Click to submit your information" Click="SubmitCode" Height="20" Width="50">Submit</Button>
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.
<TextBox HorizontalAlignment="Left">ToolTip with non-text content <TextBox.ToolTip> <ToolTip> <DockPanel Width="50" Height="70"> <Image Source="data\flower.jpg"/> <TextBlock>Useful information goes here.</TextBlock> </DockPanel> </ToolTip> </TextBox.ToolTip> </TextBox>
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>
Using the Properties of the ToolTip and ToolTipService Classes
You can customize tooltip content by setting visual properties and applying styles. If you define the tooltip content as a ToolTip object, you can set the visual properties of the ToolTip object. Otherwise, you must set equivalent attached properties on the ToolTipService class.
For an example of how to set properties in order to specify the position of tooltip content by using the ToolTip and ToolTipService properties, see How to: Position a 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>
Using the Time Interval Properties of ToolTipService
The ToolTipService class provides the following properties for you to set tooltip display times: InitialShowDelay, BetweenShowDelay, and ShowDuration.
Use the InitialShowDelay and ShowDuration properties to specify a delay, typically brief, before a ToolTip appears and also to specify how long a ToolTip remains visible. For more information, see How to: Delay the Display of a ToolTip.
The BetweenShowDelay property determines if tooltips for different controls appear without an initial delay when you move the mouse pointer quickly between them. For more information about the BetweenShowDelay property, see How to: Use the BetweenShowDelay Property.
The following example shows how to set these properties for a tooltip.
<Ellipse Height="25" Width="50" Fill="Gray" HorizontalAlignment="Left" ToolTipService.InitialShowDelay="1000" ToolTipService.ShowDuration="7000" ToolTipService.BetweenShowDelay="2000"> <Ellipse.ToolTip> <ToolTip Placement="Right" PlacementRectangle="50,0,0,0" HorizontalOffset="10" VerticalOffset="20" HasDropShadow="false" Opened="whenToolTipOpens" Closed="whenToolTipCloses" > <BulletDecorator> <BulletDecorator.Bullet> <Ellipse Height="10" Width="20" Fill="Blue"/> </BulletDecorator.Bullet> <TextBlock>Uses the ToolTip Class</TextBlock> </BulletDecorator> </ToolTip> </Ellipse.ToolTip> </Ellipse>
How-to Topics
Position a ToolTip
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.ToolTip class properties | System.Windows.Controls.ToolTipService class properties |
---|---|
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.

ToolTip placement by using the Placement property

ToolTip placement by using the Placement and PlacementRectangle properties

ToolTip placement by using the Placement, PlacementRectangle, and Offset properties
The following example shows how to use the ToolTip properties to specify the position of a tooltip whose content is a ToolTip object.
<Ellipse Height="25" Width="50" Fill="Gray" HorizontalAlignment="Left" ToolTipService.InitialShowDelay="1000" ToolTipService.ShowDuration="7000" ToolTipService.BetweenShowDelay="2000"> <Ellipse.ToolTip> <ToolTip Placement="Right" PlacementRectangle="50,0,0,0" HorizontalOffset="10" VerticalOffset="20" HasDropShadow="false" Opened="whenToolTipOpens" Closed="whenToolTipCloses" > <BulletDecorator> <BulletDecorator.Bullet> <Ellipse Height="10" Width="20" Fill="Blue"/> </BulletDecorator.Bullet> <TextBlock>Uses the ToolTip Class</TextBlock> </BulletDecorator> </ToolTip> </Ellipse.ToolTip> </Ellipse>
//Create an ellipse that will have a //ToolTip control. Ellipse ellipse1 = new Ellipse(); ellipse1.Height = 25; ellipse1.Width = 50; ellipse1.Fill = Brushes.Gray; ellipse1.HorizontalAlignment = HorizontalAlignment.Left; //Create a tooltip and set its position. ToolTip tooltip = new ToolTip(); tooltip.Placement = PlacementMode.Right; tooltip.PlacementRectangle = new Rect(50, 0, 0, 0); tooltip.HorizontalOffset = 10; tooltip.VerticalOffset = 20; //Create BulletDecorator and set it //as the tooltip content. BulletDecorator bdec = new BulletDecorator(); Ellipse littleEllipse = new Ellipse(); littleEllipse.Height = 10; littleEllipse.Width = 20; littleEllipse.Fill = Brushes.Blue; bdec.Bullet = littleEllipse; TextBlock tipText = new TextBlock(); tipText.Text = "Uses the ToolTip class"; bdec.Child = tipText; tooltip.Content = bdec; //set tooltip on ellipse ellipse1.ToolTip = tooltip;
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; //set tooltip timing ToolTipService.SetInitialShowDelay(ellipse2, 1000); ToolTipService.SetBetweenShowDelay(ellipse2, 2000); ToolTipService.SetShowDuration(ellipse2, 7000); //set tooltip placement 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)); //define tooltip content BulletDecorator bdec2 = new BulletDecorator(); Ellipse littleEllipse2 = new Ellipse(); littleEllipse2.Height = 10; littleEllipse2.Width = 20; littleEllipse2.Fill = Brushes.Blue; bdec2.Bullet = littleEllipse2; TextBlock tipText2 = new TextBlock(); tipText2.Text = "Uses the ToolTipService class"; bdec2.Child = tipText2; ToolTipService.SetToolTip(ellipse2, bdec2); stackPanel_1_2.Children.Add(ellipse2);
Use the BetweenShowDelay Property
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.
<Ellipse Height="25" Width="50" Fill="Gray" HorizontalAlignment="Left" ToolTipService.InitialShowDelay="1000" ToolTipService.ShowDuration="7000" ToolTipService.BetweenShowDelay="2000"> <Ellipse.ToolTip> <ToolTip Placement="Right" PlacementRectangle="50,0,0,0" HorizontalOffset="10" VerticalOffset="20" HasDropShadow="false" Opened="whenToolTipOpens" Closed="whenToolTipCloses" > <BulletDecorator> <BulletDecorator.Bullet> <Ellipse Height="10" Width="20" Fill="Blue"/> </BulletDecorator.Bullet> <TextBlock>Uses the ToolTip Class</TextBlock> </BulletDecorator> </ToolTip> </Ellipse.ToolTip> </Ellipse>
<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>
ToolTip Class
Represents a control that creates a pop-up window that displays information for an element in the interface.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ContentControl
System.Windows.Controls.ToolTip
System.Windows.Controls.Ribbon.RibbonToolTip
Remarks
A ToolTip is a ContentControl, which means that it can contain a single object of any type (such as a string, an image, or a panel). For more information, see the ContentControl class.
You use a ToolTip control to provide information to the user. For example, you can use a ToolTip to provide the name of a Button or a ToolBar in a ToolBarTray. The content of a ToolTip control can vary from a simple text string to more complex content such as a StackPanel that has embedded text and images. The content of a ToolTip cannot receive focus.
A ToolTip control cannot have a parent. For example, you cannot set the Content property of a Button to a ToolTip Instead, assign a ToolTip to the FrameworkContentElement.ToolTip and FrameworkElement.ToolTip properties.
You can use a ToolTip on multiple elements by defining a ToolTip in a ResourceDictionary.
The properties of the ToolTip class are used to define the position and behavior of the tooltip. Many of these properties are also defined in the ToolTipService class. If the value of one of these properties is specified by both the ToolTip property and the ToolTipServiceattached property, the value of the ToolTipService property is used. In addition, the ToolTipService class provides properties to set timing behavior. These attached properties are not included in the ToolTip class but can be used by the control.
Customizing the ToolTip Control
To apply the same property settings to multiple ToolTip controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the ToolTip, see ToolTip Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in ToolTip control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following examples shows how to define a tooltip control for a TextBox element.
The following example shows how to define a tooltip by assigning text to the ToolTip property.
<TextBox HorizontalAlignment="Left">TextBox with ToolTip <TextBox.ToolTip> <TextBlock>Useful information goes here.</TextBlock> </TextBox.ToolTip> </TextBox>
The following example shows how to define a tooltip by assigning a ToolTip object to the ToolTip property.
<TextBox HorizontalAlignment="Left">ToolTip with non-text content <TextBox.ToolTip> <ToolTip> <DockPanel Width="50" Height="70"> <Image Source="data\flower.jpg"/> <TextBlock>Useful information goes here.</TextBlock> </DockPanel> </ToolTip> </TextBox.ToolTip> </TextBox>
The following example uses code to generate a ToolTip object. The example creates a ToolTip (tt) and associates it with a Button.
ToolTipService Class
Represents a service that provides properties and events to control the display and behavior of tooltips.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
You define a tooltip for an element by setting the FrameworkContentElement.ToolTip or FrameworkElement.ToolTip property. The ToolTip property takes one child. The content of the child can vary from a simple text string to more complex content such as a StackPanel that has embedded text and Image elements.
You can define tooltip content as a ToolTip object, but this is not required. When you do not define the tooltip content as a ToolTip object, you can use the ToolTipService properties to position and customize the tooltip content. The ToolTipService class attached properties are used to determine the placement, behavior, and appearance of a tooltip. These properties are set on the element that defines the tooltip.
The ToolTip class and the ToolTipService class share many of the same properties that are used to customize a tooltip. If equivalent ToolTip and ToolTipService properties are both set, the ToolTipService property takes precedence. For example, if both the ToolTip.Placement property and the ToolTipService.Placement property are set for a System.Windows.Controls.ToolTip object, the value of the ToolTipService.Placement property is used.
The following ToolTipService timing properties are only defined for the ToolTipService class and are used by all tooltips:
For information about how to handle the events that occur when the tooltip opens or closes, see the ToolTipOpeningEvent and ToolTipClosingEventfields.
Placement, PlacementRectangle, PlacementTarget, HorizontalOffset, and VerticalOffset behave similarly to the properties of the same name in the Popup class. For more information, see Popup Placement Behavior.
Examples
The following example shows how the use the ToolTipService class to specify the behavior of a tooltip. You set the properties of the ToolTipServiceclass by attaching them directly to the element that exposes the tooltip.
<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>
TreeView
TreeView Overview
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.
<TreeView Name="myTreeViewEvent" > <TreeViewItem Header="Employee1" IsSelected="True"> <TreeViewItem Header="Jesper Aaberg"/> <TreeViewItem Header="Employee Number"> <TreeViewItem Header="12345"/> </TreeViewItem> <TreeViewItem Header="Work Days"> <TreeViewItem Header="Monday"/> <TreeViewItem Header="Tuesday"/> <TreeViewItem Header="Thursday"/> </TreeViewItem> </TreeViewItem> <TreeViewItem Header="Employee2"> <TreeViewItem Header="Dominik Paiha"/> <TreeViewItem Header="Employee Number"> <TreeViewItem Header="98765"/> </TreeViewItem> <TreeViewItem Header="Work Days"> <TreeViewItem Header="Tuesday"/> <TreeViewItem Header="Wednesday"/> <TreeViewItem Header="Friday"/> </TreeViewItem> </TreeViewItem> </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 How to: 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.
Expanding and Collapsing a TreeViewItem
If the user expands a TreeViewItem, the IsExpanded property is set to true. You can also expand or collapse a TreeViewItem without any direct user action by setting the IsExpanded property to true (expand) or false (collapse). When this property changes, an Expanded or Collapsed event occurs.
When the BringIntoView method is called on a TreeViewItem control, the TreeViewItem and its parent TreeViewItem controls expand. If a TreeViewItem is not visible or partially visible, the TreeView scrolls to make it visible.
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 How to: 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 Heightproperties 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.
<Style TargetType="{x:Type TreeViewItem}"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontSize" Value="12"/> </Style>
Adding Images and Other Content to TreeView Items
You can include more than one object in the Header content of a TreeViewItem. To include multiple objects in Header content, enclose the objects inside a layout control, such as a Panel or StackPanel.
The following example shows how to define the Header of a TreeViewItem as a CheckBox and TextBlock that are both enclosed in a DockPanelcontrol.
<TreeViewItem> <TreeViewItem.Header> <DockPanel> <CheckBox/> <TextBlock> TreeViewItem Text </TextBlock> </DockPanel> </TreeViewItem.Header> </TreeViewItem>
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>
TreeView Class
Represents a control that displays hierarchical data in a tree structure that has items that can expand and collapse.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
TreeView is an ItemsControl, which means it can contain a collection of objects of any type (such as string, image, or panel). For more information, see the ItemsControl class.
The following illustration shows a simple TreeView.
The contents of a TreeView are TreeViewItem controls that can contain rich content, such as Button and Image controls. A TreeViewItem can contain one or more TreeViewItem objects as its descendants. A TreeView is defined as a hierarchy of TreeViewItem objects.
A TreeView can populate its tree by binding to a data source and using HierarchicalDataTemplate objects. Examples of data sources include XmlDataProvider and ObservableCollection<T> objects.
Displaying a large number of items may cause performance issues. See Optimizing Performance: Controls for more information. To improve the performance of a TreeView, see How to: Improve the Performance of a TreeView.
For more information about the TreeView control, see the TreeView Overview.
A TreeView has a limited number of levels. For more information, see Visual.
Customizing the TreeView Control
To apply the same property settings to multiple TreeView controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the TreeView, see TreeView Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in TreeView control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example shows how to create a TreeView.
<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>
TreeViewItem Class
Implements a selectable item in a TreeView control.
Namespace: System.Windows.ControlsAssembly: PresentationFramework (in PresentationFramework.dll)
Inheritance Hierarchy
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
System.Windows.Controls.HeaderedItemsControl
System.Windows.Controls.TreeViewItem
Remarks
TreeViewItem is a HeaderedItemsControl, which means its header and collection of objects can be of any type (such as string, image, or panel). For more information, see the HeaderedItemsControl class.
TreeViewItem controls can be embedded inside other TreeViewItem controls to create a hierarchy of nodes inside a TreeView control.
The following illustration shows a hierarchy of TreeViewItem controls inside a TreeView.

To expand or collapse a TreeViewItem, use the IsExpanded property.
For more information about the TreeView control, see the TreeView Overview.
Customizing the TreeViewItem Control
To apply the same property settings to multiple TreeViewItem controls, use the Style property. You can modify the default ControlTemplate to give the control a unique appearance. For more information about creating a ControlTemplate, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. To see the parts and states that are specific to the TreeViewItem, see TreeView Styles and Templates.
Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Default WPF Themes.
![]() |
---|
Setting a visual property will only have an effect if that property is both present in TreeViewItem control's default template and is set by using a . You can find a list of visual properties in the "Changing the Visual Structure of a Control" section in Customizing the Appearance of an Existing Control by Creating a ControlTemplate. |
Examples
The following example shows how to create a hierarchy of TreeViewItem controls in a TreeView control.
<TreeView Name="myTreeViewEvent" > <TreeViewItem Header="Employee1" IsSelected="True"> <TreeViewItem Header="Jesper Aaberg"/> <TreeViewItem Header="Employee Number"> <TreeViewItem Header="12345"/> </TreeViewItem> <TreeViewItem Header="Work Days"> <TreeViewItem Header="Monday"/> <TreeViewItem Header="Tuesday"/> <TreeViewItem Header="Thursday"/> </TreeViewItem> </TreeViewItem> <TreeViewItem Header="Employee2"> <TreeViewItem Header="Dominik Paiha"/> <TreeViewItem Header="Employee Number"> <TreeViewItem Header="98765"/> </TreeViewItem> <TreeViewItem Header="Work Days"> <TreeViewItem Header="Tuesday"/> <TreeViewItem Header="Wednesday"/> <TreeViewItem Header="Friday"/> </TreeViewItem> </TreeViewItem> </TreeView>
How-to Topics
Create Simple or Complex TreeViews
This example shows how to create simple or complex TreeView controls.
A TreeView consists of a hierarchy of TreeViewItem controls, which can contain simple text strings and also more complex content, such as Buttoncontrols or a StackPanel with embedded content. You can explicitly define the TreeView content or a data source can provide the content. This topic provides examples of these concepts.
Example
The Header property of the TreeViewItem contains the content that the TreeView displays for that item. A TreeViewItem can also have TreeViewItemcontrols 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 HierarchicalDataTemplatedefines 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>
<TreeView ItemsSource="{Binding Source={StaticResource myEmployeeData}, XPath=EmployeeInfo}"/>
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>
Use SelectedValue, SelectedValuePath, and SelectedItem
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.
<XmlDataProvider x:Key="myEmployeeData" XPath="/EmployeeData"> <x:XData> <EmployeeData xmlns=""> <EmployeeInfo> <EmployeeName>Jesper Aabergy</EmployeeName> <EmployeeWorkDay>Monday</EmployeeWorkDay> <EmployeeWorkDay>Wednesday</EmployeeWorkDay> <EmployeeWorkDay>Friday</EmployeeWorkDay> <EmployeeStartTime>8:00am</EmployeeStartTime> <EmployeeNumber>12345</EmployeeNumber> </EmployeeInfo> <EmployeeInfo> <EmployeeName>Dominik Paiha</EmployeeName> <EmployeeWorkDay>Monday</EmployeeWorkDay> <EmployeeWorkDay>Tuesday</EmployeeWorkDay> <EmployeeStartTime>6:30am</EmployeeStartTime> <EmployeeNumber>98765</EmployeeNumber> </EmployeeInfo> </EmployeeData> </x:XData> </XmlDataProvider>
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.
<HierarchicalDataTemplate DataType="EmployeeInfo" ItemsSource ="{Binding XPath=EmployeeWorkDay}"> <TextBlock Text="{Binding XPath=EmployeeName}" /> </HierarchicalDataTemplate>
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}, XPath=EmployeeInfo}" Name="myTreeView" SelectedValuePath="EmployeeNumber" /> <TextBlock Margin="10">SelectedValuePath: </TextBlock> <TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, Path=SelectedValuePath}" Foreground="Blue"/> <TextBlock Margin="10">SelectedValue: </TextBlock> <TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, Path=SelectedValue}" Foreground="Blue"/>
Bind a TreeView to Data That Has an Indeterminable Depth
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 Employeeelements 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> <!-- Bind the HierarchicalDataTemplate.ItemsSource property to the employees under each Employee element. --> <HierarchicalDataTemplate x:Key="EmployeeTemplate" ItemsSource="{Binding XPath=Employee}"> <TextBlock Text="{Binding XPath=@Name}" ></TextBlock> </HierarchicalDataTemplate> <Style TargetType="TreeViewItem"> <Setter Property="IsExpanded" Value="True"/> </Style> </Page.Resources> <Grid> <TreeView ItemsSource="{Binding Source={StaticResource myCompany}}" ItemTemplate="{StaticResource EmployeeTemplate}"/> </Grid> </Page>
Improve the Performance of a TreeView
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 Recycling.
Example
Description
The following example creates a TreeView that sets VirtualizingStackPanel.IsVirtualizing to true and VirtualizingStackPanel.VirtualizationMode to Recycling to optimize its performance.
Code
<StackPanel> <StackPanel.Resources> <src:TreeViewData x:Key="dataItems"/> <HierarchicalDataTemplate DataType="{x:Type src:ItemsForTreeView}" ItemsSource="{Binding Path=SecondLevelItems}"> <!--Display the TopLevelName property in the first level.--> <TextBlock Text="{Binding Path=TopLevelName}"/> <!--Display each string in the SecondLevelItems property in the second level.--> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}"/> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> <!--Set the foreground of the items in the second level to Navy.--> <HierarchicalDataTemplate.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="Foreground" Value="Navy"/> </Style> </HierarchicalDataTemplate.ItemContainerStyle> </HierarchicalDataTemplate> </StackPanel.Resources> <TreeView Height="200" ItemsSource="{Binding Source={StaticResource dataItems}}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"> <TreeView.ItemContainerStyle> <!--Expand each TreeViewItem in the first level and set its foreground to Green.--> <Style TargetType="TreeViewItem"> <Setter Property="IsExpanded" Value="True"/> <Setter Property="Foreground" Value="Green"/> </Style> </TreeView.ItemContainerStyle> </TreeView> </StackPanel>
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 class ItemsForTreeView { public string TopLevelName { get; set; } private ObservableCollection<string> level2Items; public ObservableCollection<string> SecondLevelItems { get { if (level2Items == null) { level2Items = new ObservableCollection<string>(); } return level2Items; } } public ItemsForTreeView() { for (int i = 0; i < 10; ++i) { SecondLevelItems.Add("Second Level " + i.ToString()); } } }
Find a TreeViewItem in a TreeView
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.
![]() |
---|
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; } // Expand the current container if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded) { container.SetValue(TreeViewItem.IsExpandedProperty, true); } // Try to generate the ItemsPresenter and the ItemsPanel. // by calling ApplyTemplate. Note that in the // virtualizing case even if the item is marked // expanded we still need to do this step in order to // regenerate the visuals because they may have been virtualized away. 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); } } Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0); // Ensure that the generator for this panel has been created. UIElementCollection children = itemsHostPanel.Children; MyVirtualizingStackPanel virtualizingPanel = itemsHostPanel as MyVirtualizingStackPanel; for (int i = 0, count = container.Items.Count; i < count; i++) { TreeViewItem subContainer; if (virtualizingPanel != null) { // Bring the item into view so // that the container will be generated. virtualizingPanel.BringIntoView(i); subContainer = (TreeViewItem)container.ItemContainerGenerator. ContainerFromIndex(i); } else { subContainer = (TreeViewItem)container.ItemContainerGenerator. ContainerFromIndex(i); // Bring the item into view to maintain the // same behavior as with a virtualizing panel. subContainer.BringIntoView(); } 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; }
The previous code relies on a custom VirtualizingStackPanel that exposes a method named BringIntoView. The following code defines the custom VirtualizingStackPanel.
public class MyVirtualizingStackPanel : VirtualizingStackPanel { /// <summary> /// Publically expose BringIndexIntoView. /// </summary> public void BringIntoView(int index) { this.BringIndexIntoView(index); } }
The following XAML shows how to create a TreeView that uses the custom VirtualizingStackPanel.
<TreeView VirtualizingStackPanel.IsVirtualizing="True"> <!--Use the custom class MyVirtualizingStackPanel as the ItemsPanel for the TreeView and TreeViewItem object.--> <TreeView.ItemsPanel> <ItemsPanelTemplate> <src:MyVirtualizingStackPanel/> </ItemsPanelTemplate> </TreeView.ItemsPanel> <TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <src:MyVirtualizingStackPanel/> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView>
WrapPanel
WrapPanel Class
Positions child elements in sequential position from left to right, breaking content to the next line at the edge of the containing box. Subsequent ordering happens sequentially from top to bottom or from right to left, depending on the value of the Orientation property.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
A WrapPanel contains a collection of UIElement objects, which are in the Children property. All child elements of a WrapPanel receive the layout partition size of ItemWidth multiplied by ItemHeight.
Examples
The following example demonstrates how to create a WrapPanel in code and Extensible Application Markup Language (XAML).
// Create the application's main window mainWindow = new System.Windows.Window(); mainWindow.Title = "WrapPanel Sample"; // Instantiate a new WrapPanel and set properties myWrapPanel = new WrapPanel(); myWrapPanel.Background = System.Windows.Media.Brushes.Azure; myWrapPanel.Orientation = Orientation.Horizontal; myWrapPanel.Width = 200; myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left; myWrapPanel.VerticalAlignment = 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. 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); // Add the WrapPanel to the MainWindow as Content mainWindow.Content = myWrapPanel; mainWindow.Show();
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="WrapPanel Sample"> <Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2"> <WrapPanel Background="LightBlue" Width="200" Height="100"> <Button Width="200">Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> <Button>Button 4</Button> </WrapPanel> </Border> </Page>
Viewbox
Viewbox Class
Defines a content decorator that can stretch and scale a single child to fill the available space.
Namespace: System.Windows.Controls
Assembly: PresentationFramework (in PresentationFramework.dll)
Remarks
A Viewbox can only have one Child. If you add an additional Child, you cause an ArgumentException at run time.
Examples
The following example shows how to create an instance of a Viewbox and set common properties in code.
Apply Stretch Properties to the Contents of a Viewbox
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 StretchDirectionenumerations manipulate the stretching behavior of the nested Image.
<StackPanel Margin="0,0,0,10" HorizontalAlignment="Center" Orientation="Horizontal" DockPanel.Dock="Top"> <Button Name="btn1" Click="stretchNone">Stretch="None"</Button> <Button Name="btn2" Click="stretchFill">Stretch="Fill"</Button> <Button Name="btn3" Click="stretchUni">Stretch="Uniform"</Button> <Button Name="btn4" Click="stretchUniFill">Stretch="UniformToFill"</Button> </StackPanel> <StackPanel Margin="0,0,0,10" HorizontalAlignment="Center" Orientation="Horizontal" DockPanel.Dock="Top"> <Button Name="btn5" Click="sdUpOnly">StretchDirection="UpOnly"</Button> <Button Name="btn6" Click="sdDownOnly">StretchDirection="DownOnly"</Button> <Button Name="btn7" Click="sdBoth">StretchDirection="Both"</Button> </StackPanel> <TextBlock DockPanel.Dock="Top" Name="txt1" /> <TextBlock DockPanel.Dock="Top" Name="txt2" /> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Viewbox MaxWidth="500" MaxHeight="500" Name="vb1"> <Image Source="tulip_farm.jpg"/> </Viewbox> </StackPanel>
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."; } private void stretchFill(object sender, RoutedEventArgs e) { vb1.Stretch = System.Windows.Media.Stretch.Fill; txt1.Text = "Stretch is now set to Fill."; } private void stretchUni(object sender, RoutedEventArgs e) { vb1.Stretch = System.Windows.Media.Stretch.Uniform; txt1.Text = "Stretch is now set to Uniform."; } private void stretchUniFill(object sender, RoutedEventArgs e) { vb1.Stretch = System.Windows.Media.Stretch.UniformToFill; txt1.Text = "Stretch is now set to UniformToFill."; } private void sdUpOnly(object sender, RoutedEventArgs e) { vb1.StretchDirection = System.Windows.Controls.StretchDirection.UpOnly; txt2.Text = "StretchDirection is now UpOnly."; } private void sdDownOnly(object sender, RoutedEventArgs e) { vb1.StretchDirection = System.Windows.Controls.StretchDirection.DownOnly; txt2.Text = "StretchDirection is now DownOnly."; } private void sdBoth(object sender, RoutedEventArgs e) { vb1.StretchDirection = System.Windows.Controls.StretchDirection.Both; txt2.Text = "StretchDirection is now Both."; }
'프로그래밍 > WPF' 카테고리의 다른 글
Graphics and Multimedia (0) | 2016.11.24 |
---|---|
Documents (0) | 2016.11.19 |
Control Library 2 (0) | 2016.11.13 |
Controls (0) | 2016.11.05 |
WPF Unmanaged API Reference (0) | 2016.11.05 |
The event handler is called whenever the contents of the TextBox control are changed, either by a user or programmatically.