달력

1

« 2025/1 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2016. 11. 13. 18:18

Control Library 2 프로그래밍/WPF2016. 11. 13. 18:18

ListView


https://msdn.microsoft.com/en-us/library/ms754239(v=vs.110).aspx


ListView Overview


The ListView control provides the infrastructure to display a set of data items in different layouts or views. For example, a user may want to display data items in a table and also to sort its columns.

What Is a ListView?

The ListView control is an ItemsControl that is derived from ListBox. Typically, its items are members of a data collection and are represented as ListViewItem objects. A ListViewItem is a ContentControl and can contain only a single child element. However, that child element can be any visual element.

Defining a View Mode for a ListView

To specify a view mode for the content of a ListView control, you set the View property. One view mode that Windows Presentation Foundation (WPF) provides is GridView, which displays a collection of data items in a table that has customizable columns.

The following example shows how to define a GridView for a ListView control that displays employee information.

<ListView ItemsSource="{Binding Source=
                       {StaticResource EmployeeInfoDataSource}}">

  <ListView.View>

    <GridView AllowsColumnReorder="true"
              ColumnHeaderToolTip="Employee Information">

      <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=FirstName}" 
                      Header="First Name" Width="100"/>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=LastName}" 
                      Width="100">
                      <GridViewColumnHeader>Last Name
                          <GridViewColumnHeader.ContextMenu>
                          <ContextMenu  MenuItem.Click="LastNameCM_Click"  
                                        Name="LastNameCM">
                              <MenuItem Header="Ascending" />
                              <MenuItem Header="Descending" />
                          </ContextMenu>
                          </GridViewColumnHeader.ContextMenu>
                      </GridViewColumnHeader>
                  </GridViewColumn>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=EmployeeNumber}" 
                      Header="Employee No." Width="100"/>
    </GridView>

  </ListView.View>
</ListView>

The following illustration shows how the data appears for the previous example.

ListView with GridView output

You can create a custom view mode by defining a class that inherits from the ViewBase class. The ViewBase class provides the infrastructure that you need to create a custom view. For more information about how to create a custom view, see How to: Create a Custom View Mode for a ListView.

Binding Data to a ListView

Use the Items and ItemsSource properties to specify items for a ListView control. The following example sets the ItemsSource property to a data collection that is called EmployeeInfoDataSource.

<ListView ItemsSource="{Binding Source=
                       {StaticResource EmployeeInfoDataSource}}">

In a GridViewGridViewColumn objects bind to specified data fields. The following example binds a GridViewColumn object to a data field by specifying a Binding for the DisplayMemberBinding property.

GridViewColumn gvc1 = new GridViewColumn();
gvc1.DisplayMemberBinding = new Binding("FirstName");
gvc1.Header = "FirstName";
gvc1.Width = 100;
<GridViewColumn DisplayMemberBinding=
                    "{Binding Path=FirstName}" 
                Header="First Name" Width="100"/>

You can also specify a Binding as part of a DataTemplate definition that you use to style the cells in a column. In the following example, the DataTemplate that is identified with a ResourceKey sets the Binding for a GridViewColumn. Note that this example does not define the DisplayMemberBinding because doing so overrides the binding that is specified by DataTemplate.

<DataTemplate x:Key="myCellTemplateMonth">
  <DockPanel>
    <TextBlock Foreground="DarkBlue" HorizontalAlignment="Center">
      <TextBlock.Text>
        <Binding Path="Month"/>
      </TextBlock.Text>
    </TextBlock>
  </DockPanel>
</DataTemplate>
<GridViewColumn Header="Month" Width="80"
      CellTemplate="{StaticResource myCellTemplateMonth}"/>

Styling a ListView That Implements a GridView

The ListView control contains ListViewItem objects, which represent the data items that are displayed. You can use the following properties to define the content and style of data items:

To avoid alignment issues between cells in a GridView, do not use the ItemContainerStyle to set properties or add content that affects the width of an item in a ListView. For example, an alignment issue can occur when you set the Margin property in the ItemContainerStyle. To specify properties or define content that affects the width of items in a GridView, use the properties of the GridView class and its related classes, such as GridViewColumn.

For more information about how to use GridView and its supporting classes, see GridView Overview.

If you define an ItemContainerStyle for a ListView control and also define an ItemTemplate, you must include a ContentPresenter in the style in order for the ItemTemplate to work correctly.

Do not use the HorizontalContentAlignment and VerticalContentAlignment properties for ListView content that is displayed by using a GridView. To specify the alignment of content in a column of a GridView, define a CellTemplate.

Sharing the Same View Mode

Two ListView controls cannot share the same view mode at the same time. If you try to use the same view mode with more than one ListView control, an exception occurs.

To specify a view mode that can be simultaneously used by more than one ListView, use templates or styles. For an example of how to define views as Resources, see ListView with Multiple Views Sample.

Creating a Custom View Mode

Customized views like GridView are derived from the ViewBase abstract class, which provides the tools to display data items that are represented as ListViewItem objects.

For an example of a custom view mode, see ListView with Multiple Views Sample.




GridView Overview


GridView view mode is one of the view modes for a ListView control. The GridView class and its supporting classes enable you and your users to view item collections in a table that typically uses buttons as interactive column headers. This topic introduces the GridView class and outlines its use.

What Is a GridView View?

The GridView view mode displays a list of data items by binding data fields to columns and by displaying a column header to identify the field. The default GridView style implements buttons as column headers. By using buttons for column headers, you can implement important user interaction capabilities; for example, users can click the column header to sort GridView data according to the contents of a specific column.

System_CAPS_noteNote

The button controls that GridView uses for column headers are derived from ButtonBase.

The following illustration shows a GridView view of ListView content.

GridView view of ListView content

Styled ListView

GridView columns are represented by GridViewColumn objects, which can automatically size to their content. Optionally, you can explicitly set a GridViewColumn to a specific width. You can resize columns by dragging the gripper between column headers. You can also dynamically add, remove, replace, and reorder columns because this functionality is built into GridView. However, GridView cannot directly update the data that it displays.

The following example shows how to define a GridView that displays employee data. In this example, ListView defines the EmployeeInfoDataSourceas the ItemsSource. The property definitions of DisplayMemberBinding bind GridViewColumn content to EmployeeInfoDataSource data categories.

<ListView ItemsSource="{Binding Source=
                       {StaticResource EmployeeInfoDataSource}}">

  <ListView.View>

    <GridView AllowsColumnReorder="true"
              ColumnHeaderToolTip="Employee Information">

      <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=FirstName}" 
                      Header="First Name" Width="100"/>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=LastName}" 
                      Width="100">
                      <GridViewColumnHeader>Last Name
                          <GridViewColumnHeader.ContextMenu>
                          <ContextMenu  MenuItem.Click="LastNameCM_Click"  
                                        Name="LastNameCM">
                              <MenuItem Header="Ascending" />
                              <MenuItem Header="Descending" />
                          </ContextMenu>
                          </GridViewColumnHeader.ContextMenu>
                      </GridViewColumnHeader>
                  </GridViewColumn>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=EmployeeNumber}" 
                      Header="Employee No." Width="100"/>
    </GridView>

  </ListView.View>
</ListView>

The following illustration shows the table that the previous example creates.

GridView that displays data from an ItemsSource

ListView with GridView output

GridView Layout and Style

The column cells and the column header of a GridViewColumn have the same width. By default, each column sizes its width to fit its content. Optionally, you can set a column to a fixed width.

Related data content displays in horizontal rows. For example, in the previous illustration, each employee's last name, first name, and ID number are displayed as a set because they appear in a horizontal row.

Defining and Styling Columns in a GridView

When defining the data field to display in a GridViewColumn, use the DisplayMemberBindingCellTemplate, or CellTemplateSelector properties. The DisplayMemberBinding property takes precedence over either of the template properties.

To specify the alignment of content in a column of a GridView, define a CellTemplate. Do not use the HorizontalContentAlignment and VerticalContentAlignment properties for ListView content that is displayed by using a GridView.

To specify template and style properties for column headers, use the GridViewGridViewColumn, and GridViewColumnHeader classes. For more information, see GridView Column Header Styles and Templates Overview.

Adding Visual Elements to a GridView

To add visual elements, such as CheckBox and Button controls, to a GridView view mode, use templates or styles.

If you explicitly define a visual element as a data item, it can appear only one time in a GridView. This limitation exists because an element can have only one parent and therefore, can appear only one time in the visual tree.

Styling Rows in a GridView

Use the GridViewRowPresenter and GridViewHeaderRowPresenter classes to format and display the rows of a GridView. For an example of how to style rows in a GridView view mode, see How to: Style a Row in a ListView That Implements a GridView.

Alignment Issues When You Use ItemContainerStyle

To prevent alignment issues between column headers and cells, do not set a property or specify a template that affects the width of an item in an ItemContainerStyle. For example, do not set the Margin property or specify a ControlTemplate that adds a CheckBox to an ItemContainerStyle that is defined on a ListView control. Instead, specify the properties and templates that affect column width directly on classes that define a GridViewview mode.

For example, to add a CheckBox to the rows in GridView view mode, add the CheckBox to a DataTemplate, and then set the CellTemplate property to that DataTemplate.

User Interactions with a GridView

When you use a GridView in your application, users can interact with and modify the formatting of the GridView. For example, users can reorder columns, resize a column, select items in a table, and scroll through content. You can also define an event handler that responds when a user clicks the column header button. The event handler can perform operations like sorting the data that is displayed in the GridView according to the contents of a column.

The following list discusses in more detail the capabilities of using GridView for user interaction:

  • Reorder columns by using the drag-and-drop method.

    Users can reorder columns in a GridView by pressing the left mouse button while it is over a column header and then dragging that column to a new position. While the user drags the column header, a floating version of the header is displayed as well as a solid black line that shows where to insert the column.

    If you want to modify the default style for the floating version of a header, specify a ControlTemplate for a GridViewColumnHeader type that is triggered when the Role property is set to Floating. For more information, see How to: Create a Style for a Dragged GridView Column Header.

  • Resize a column to its content.

    Users can double-click the gripper to the right of a column header in order to resize a column to fit its content.

    System_CAPS_noteNote

    You can set the Width property to Double.NaN to produce the same effect.

  • Select row items.

    Users can select one or more items in a GridView.

    If you want to change the Style of a selected item, see How to: Use Triggers to Style Selected Items in a ListView.

  • Scroll to view content that is not initially visible on the screen.

    If the size of the GridView is not large enough to display all the items, users can scroll horizontally or vertically by using scrollbars, which are provided by a ScrollViewer control. A ScrollBar is hidden if all the content is visible in a specific direction. Column headers do not scroll with a vertical scroll bar, but do scroll horizontally.

  • Interact with columns by clicking the column header buttons.

    When users click a column header button, they can sort the data that is displayed in the column if you have provided a sorting algorithm.

    You can handle the Click event for column header buttons in order to provide functionality like a sorting algorithm. To handle the Click event for a single column header, set an event handler on the GridViewColumnHeader. To set an event handler that handles the Click event for all column headers, set the handler on the ListView control.

Obtaining Other Custom Views

The GridView class, which is derived from the ViewBase abstract class, is just one of the possible view modes for the ListView class. You can create other custom views for ListView by deriving from the ViewBase class. For an example of a custom view mode, see How to: Create a Custom View Mode for a ListView.




GridView Column Header Styles and Templates Overview


This overview discusses the order of precedence for properties that you use to customize a column header in the GridView view mode of a ListViewcontrol.

Customizing a Column Header in a GridView

The properties that define the content, layout, and style of a column header in a GridView are found on many related classes. Some of these properties have functionality that is similar or the same.

The rows in the following table show groups of properties that perform the same function. You can use these properties to customize the column headers in a GridView. The order of precedence for related properties is from right to left where the property in the farthest right column has the highest precedence. For example, if a ContentTemplate is set on the GridViewColumnHeader object and the HeaderTemplateSelector is set on the associated GridViewColumn, the ContentTemplate takes precedence. In this scenario, the HeaderTemplateSelector has no effect.

Related properties for column headers in a GridView

1For Header Template Properties, if you set both the template and template selector properties, the template property takes precedence. For example, if you set both the ContentTemplate and ContentTemplateSelector properties, the ContentTemplate property takes precedence.




ListView Class


Represents a control that displays a list of data items.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.ListBox
                    System.Windows.Controls.ListView



Remarks

ListView 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 presentation of the data items in a ListView is defined by its view mode, which is specified by the View property. Windows Presentation Foundation (WPF) provides a GridView view mode that partitions the ListView data item content into columns. The properties and methods on GridView and its related classes style and specify the content of the columns.

The following illustration shows a ListView with a GridView view.

ListView with GridView output

You can also define custom views by creating a class that derives from ViewBase. For more information, see How to: Create a Custom View Mode for a ListView.

If you define a custom ItemContainerStyle for a ListView control and also define an ItemTemplate, you must include a ContentPresenter in the ItemContainerStyle. The ContentPresenter is required for the ItemTemplate to work correctly.

To avoid alignment issues in a GridView view mode, do not add content or set properties that affect the width of an item in the ItemContainerStyle of a ListView. To prevent alignment issues, use properties and templates that are defined for the GridView view mode. This includes properties and templates that are defined for classes that are used in a GridView view mode, such as GridViewColumn and GridViewColumnHeader.

Two ListView controls cannot share the same view. To specify a view that can be used more than one time, use templates or styles. For an example of a GridView and other custom views that are defined as reusable resources, see ListView with Multiple Views Sample.

Do not use the HorizontalContentAlignment and VerticalContentAlignment properties for ListView content that is displayed by using a GridView. To specify the alignment of content in a column of a GridView, define a CellTemplate.

Displaying a large number of items may cause performance issues. See Optimizing Performance: Controls for more information.

Customizing the ListView Control

To apply the same property settings to multiple ListView 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 ListView, see ListView 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in ListView 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 ListView control that implements a GridView as its View. The illustration in the Remarks section is taken from this example.

<ListView ItemsSource="{Binding Source=
                       {StaticResource EmployeeInfoDataSource}}">

  <ListView.View>

    <GridView AllowsColumnReorder="true"
              ColumnHeaderToolTip="Employee Information">

      <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=FirstName}" 
                      Header="First Name" Width="100"/>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=LastName}" 
                      Width="100">
                      <GridViewColumnHeader>Last Name
                          <GridViewColumnHeader.ContextMenu>
                          <ContextMenu  MenuItem.Click="LastNameCM_Click"  
                                        Name="LastNameCM">
                              <MenuItem Header="Ascending" />
                              <MenuItem Header="Descending" />
                          </ContextMenu>
                          </GridViewColumnHeader.ContextMenu>
                      </GridViewColumnHeader>
                  </GridViewColumn>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=EmployeeNumber}" 
                      Header="Employee No." Width="100"/>
    </GridView>

  </ListView.View>
</ListView>




How to: Sort a GridView Column When a Header Is Clicked


This example shows how to create a ListView control that implements a GridView view mode and sorts the data content when a user clicks a column header.

Example

The following example defines a GridView with three columns that bind to the YearMonth, and Day, properties of the DateTime structure.

<GridView>
  <GridViewColumn DisplayMemberBinding="{Binding Path=Year}" 
                  Header="Year"
                  Width="100"/>
  <GridViewColumn DisplayMemberBinding="{Binding Path=Month}" 
                  Header="Month"
                  Width="100"/>
  <GridViewColumn DisplayMemberBinding="{Binding Path=Day}" 
                  Header="Day"
                  Width="100"/>
</GridView>

The following example shows the data items that are defined as an ArrayList of DateTime objects. The ArrayList is defined as the ItemsSource for the ListView control.

<ListView.ItemsSource>
  <s:ArrayList>
    <p:DateTime>1993/1/1 12:22:02</p:DateTime>
    <p:DateTime>1993/1/2 13:2:01</p:DateTime>
    <p:DateTime>1997/1/3 2:1:6</p:DateTime>
    <p:DateTime>1997/1/4 13:6:55</p:DateTime>
    <p:DateTime>1999/2/1 12:22:02</p:DateTime>
    <p:DateTime>1998/2/2 13:2:01</p:DateTime>
    <p:DateTime>2000/2/3 2:1:6</p:DateTime>
    <p:DateTime>2002/2/4 13:6:55</p:DateTime>
    <p:DateTime>2001/3/1 12:22:02</p:DateTime>
    <p:DateTime>2006/3/2 13:2:01</p:DateTime>
    <p:DateTime>2004/3/3 2:1:6</p:DateTime>
    <p:DateTime>2004/3/4 13:6:55</p:DateTime>
  </s:ArrayList>
</ListView.ItemsSource>

The s and p identifiers in the XAML tags refer to namespace mappings that are defined in the metadata of the XAML page. The following example shows the metadata definition.

<Window      
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="ListViewSort.Window1"    
    xmlns:s="clr-namespace:System.Collections;assembly=mscorlib"
    xmlns:p="clr-namespace:System;assembly=mscorlib">

To sort the data according to the contents of a column, the example defines an event handler to handle the Click event that occurs when you press the column header button. The following example shows how to specify an event handler for the GridViewColumnHeader control.

<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" 
  VerticalAlignment="Center" 
  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
 >

The example defines the event handler so that the sort direction changes between ascending order and descending order each time you press the column header button. The following example shows the event handler.

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    GridViewColumnHeader _lastHeaderClicked = null;
    ListSortDirection _lastDirection = ListSortDirection.Ascending;

    void GridViewColumnHeaderClickedHandler(object sender,
                                            RoutedEventArgs e)
    {
        GridViewColumnHeader headerClicked =
              e.OriginalSource as GridViewColumnHeader;
        ListSortDirection direction;

        if (headerClicked != null)
        {
            if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
            {
                if (headerClicked != _lastHeaderClicked)
                {
                    direction = ListSortDirection.Ascending;
                }
                else
                {
                    if (_lastDirection == ListSortDirection.Ascending)
                    {
                        direction = ListSortDirection.Descending;
                    }
                    else
                    {
                        direction = ListSortDirection.Ascending;
                    }
                }

                string header = headerClicked.Column.Header as string;
                Sort(header, direction);

                if (direction == ListSortDirection.Ascending)
                {
                    headerClicked.Column.HeaderTemplate =
                      Resources["HeaderTemplateArrowUp"] as DataTemplate;
                }
                else
                {
                    headerClicked.Column.HeaderTemplate =
                      Resources["HeaderTemplateArrowDown"] as DataTemplate;
                }

                // Remove arrow from previously sorted header
                if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
                {
                    _lastHeaderClicked.Column.HeaderTemplate = null;
                }


                _lastHeaderClicked = headerClicked;
                _lastDirection = direction;
            }
        }
    }

The following example shows the sorting algorithm that is called by the event handler to sort the data. The sort is performed by creating a new SortDescription structure.

private void Sort(string sortBy, ListSortDirection direction)
{
    ICollectionView dataView =
      CollectionViewSource.GetDefaultView(lv.ItemsSource);

    dataView.SortDescriptions.Clear();
    SortDescription sd = new SortDescription(sortBy, direction);
    dataView.SortDescriptions.Add(sd);
    dataView.Refresh();
}




How to: Create a Custom View Mode for a ListView


This example shows how to create a custom View mode for a ListView control.

Example

You must use the ViewBase class when you create a custom view for the ListView control. The following example shows a view mode that is called PlainView, which is derived from the ViewBase class.

public class PlainView : ViewBase
{    

  public static readonly DependencyProperty 
    ItemContainerStyleProperty =
    ItemsControl.ItemContainerStyleProperty.AddOwner(typeof(PlainView));

  public Style ItemContainerStyle
  {
      get { return (Style)GetValue(ItemContainerStyleProperty); }
      set { SetValue(ItemContainerStyleProperty, value); }
  }

  public static readonly DependencyProperty ItemTemplateProperty =
      ItemsControl.ItemTemplateProperty.AddOwner(typeof(PlainView));

  public DataTemplate ItemTemplate
  {
      get { return (DataTemplate)GetValue(ItemTemplateProperty); }
      set { SetValue(ItemTemplateProperty, value); }
  }

  public static readonly DependencyProperty ItemWidthProperty =
      WrapPanel.ItemWidthProperty.AddOwner(typeof(PlainView));

  public double ItemWidth
  {
      get { return (double)GetValue(ItemWidthProperty); }           
      set { SetValue(ItemWidthProperty, value); }
  }


  public static readonly DependencyProperty ItemHeightProperty =
      WrapPanel.ItemHeightProperty.AddOwner(typeof(PlainView));

  public double ItemHeight
  {
      get { return (double)GetValue(ItemHeightProperty); }
      set { SetValue(ItemHeightProperty, value); }
  }


  protected override object DefaultStyleKey
  {
      get 
      { 
        return new ComponentResourceKey(GetType(), "myPlainViewDSK"); 
      }
  }

}

To apply a style to the custom view, use the Style class. The following example defines a Style for the PlainView view mode. In the previous example, this style is set as the value of the DefaultStyleKey property that is defined for PlainView.

<Style x:Key="{ComponentResourceKey 
      TypeInTargetAssembly={x:Type l:PlainView},
      ResourceId=myPlainViewDSK}" 
       TargetType="{x:Type ListView}" 
       BasedOn="{StaticResource {x:Type ListBox}}"
       >
  <Setter Property="HorizontalContentAlignment"
          Value="Center"/>
  <Setter Property="ItemContainerStyle" 
          Value="{Binding (ListView.View).ItemContainerStyle,
          RelativeSource={RelativeSource Self}}"/>
  <Setter Property="ItemTemplate" 
          Value="{Binding (ListView.View).ItemTemplate,
          RelativeSource={RelativeSource Self}}"/>
  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
                   RelativeSource={RelativeSource 
                                   AncestorType=ScrollContentPresenter}}"
                   ItemWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   MinWidth="{Binding (ListView.View).ItemWidth,
                   RelativeSource={RelativeSource AncestorType=ListView}}"
                   ItemHeight="{Binding (ListView.View).ItemHeight,
                   RelativeSource={RelativeSource AncestorType=ListView}}"/>
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>
</Style>

To define the layout of data in a custom view mode, define a DataTemplate object. The following example defines a DataTemplate that can be used to display data in the PlainView view mode.

<DataTemplate x:Key="centralTile">
  <StackPanel Height="100" Width="90">
    <Grid Width="70" Height="70" HorizontalAlignment="Center">
      <Image Source="{Binding XPath=@Image}" Margin="6,6,6,9"/>
    </Grid>
    <TextBlock Text="{Binding XPath=@Name}" FontSize="13" 
               HorizontalAlignment="Center" Margin="0,0,0,1" />
    <TextBlock Text="{Binding XPath=@Type}" FontSize="9" 
               HorizontalAlignment="Center" Margin="0,0,0,1" />
  </StackPanel>
</DataTemplate>

The following example shows how to define a ResourceKey for the PlainView view mode that uses the DataTemplate that is defined in the previous example.

<l:PlainView x:Key="tileView" 
             ItemTemplate="{StaticResource centralTile}" 
             ItemWidth="100"/>

ListView control can use a custom view if you set the View property to the resource key. The following example shows how to specify PlainView as the view mode for a ListView.

//Set the ListView View property to the tileView custom view
lv.View = lv.FindResource("tileView") as ViewBase;

For the complete sample, see ListView with Multiple Views Sample.




How to: Use Templates to Style a ListView That Uses GridView


This example shows how to use the DataTemplate and Style objects to specify the appearance of a ListView control that uses a GridView view mode.

Example

The following examples show Style and DataTemplate objects that customize the appearance of a column header for a GridViewColumn.

<Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
  <Setter Property="Background" Value="LightBlue"/>
</Style>
<DataTemplate x:Key="myHeaderTemplate">
  <DockPanel>
    <CheckBox/>
    <TextBlock FontSize="16" Foreground="DarkBlue">
      <TextBlock.Text>
        <Binding/>
      </TextBlock.Text>
    </TextBlock>
  </DockPanel>
</DataTemplate>

The following example shows how to use these Style and DataTemplate objects to set the HeaderContainerStyle and HeaderTemplate properties of a GridViewColumn. The DisplayMemberBinding property defines the content of the column cells.

<GridViewColumn Header="Month" Width="80"
      HeaderContainerStyle="{StaticResource myHeaderStyle}"
      HeaderTemplate="{StaticResource myHeaderTemplate}"
      DisplayMemberBinding="{Binding Path=Month}"/>

The HeaderContainerStyle and HeaderTemplate are only two of several properties that you can use to customize column header appearance for a GridView control. For more information, see GridView Column Header Styles and Templates Overview.

The following example shows how to define a DataTemplate that customizes the appearance of the cells in a GridViewColumn.

<DataTemplate x:Key="myCellTemplateMonth">
  <DockPanel>
    <TextBlock Foreground="DarkBlue" HorizontalAlignment="Center">
      <TextBlock.Text>
        <Binding Path="Month"/>
      </TextBlock.Text>
    </TextBlock>
  </DockPanel>
</DataTemplate>

The following example shows how to use this DataTemplate to define the content of a GridViewColumn cell. This template is used instead of the DisplayMemberBinding property that is shown in the previous GridViewColumn example.

<GridViewColumn Header="Month" Width="80"
      CellTemplate="{StaticResource myCellTemplateMonth}"/>




How to: Create a Style for a Dragged GridView Column Header


This example shows how to change the appearance of a dragged GridViewColumnHeader when the user changes the position of a column.

Example

When you drag a column header to another location in a ListView that uses GridView for its view mode, the column moves to the new position. While you are dragging the column header, a floating copy of the header appears in addition to the original header. A column header in a GridView is represented by a GridViewColumnHeader object.

To customize the appearance of both the floating and original headers, you can set Triggers to modify the GridViewColumnHeader Style. These Triggersare applied when the IsPressed property value is true and the Role property value is Floating.

When the user presses the mouse button and holds it down while the mouse pauses on the GridViewColumnHeader, the IsPressed property value changes to true. Likewise, when the user begins the drag operation, the Role property changes to Floating.

The following example shows how to set Triggers to change the Foreground and Background colors of the original and floating headers when the user drags a column to a new position.

<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<ControlTemplate.Triggers>
<Trigger Property="IsPressed"
         Value="true">
  <Setter TargetName="HighlightBorder"
          Property="Visibility"
          Value="Hidden"/>
  <Setter TargetName="PART_HeaderGripper"
          Property="Visibility"
          Value="Hidden"/>
  <Setter Property="Background"
          Value="SkyBlue"/>
  <Setter Property="Foreground"
          Value="Yellow"/>
</Trigger>
<Trigger Property="Role"
         Value="Floating">
  <Setter TargetName="PART_HeaderGripper"
          Property="Visibility"
          Value="Collapsed"/>
  <Setter Property="Background"
          Value="Yellow"/>
  <Setter Property="Foreground"
          Value="SkyBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>




How to: Display ListView Contents by Using a GridView


This example shows how to define a GridView view mode for a ListView control.

Example

You can define the view mode of a GridView by specifying GridViewColumn objects. The following example shows how to define GridViewColumnobjects that bind to the data content that is specified for the ListView control. This GridView example specifies three GridViewColumn objects that map to the FirstNameLastName, and EmployeeNumber fields of the EmployeeInfoDataSource that is set as the ItemsSource of the ListView control.

<ListView ItemsSource="{Binding Source=
                       {StaticResource EmployeeInfoDataSource}}">

  <ListView.View>

    <GridView AllowsColumnReorder="true"
              ColumnHeaderToolTip="Employee Information">

      <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=FirstName}" 
                      Header="First Name" Width="100"/>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=LastName}" 
                      Width="100">
                      <GridViewColumnHeader>Last Name
                          <GridViewColumnHeader.ContextMenu>
                          <ContextMenu  MenuItem.Click="LastNameCM_Click"  
                                        Name="LastNameCM">
                              <MenuItem Header="Ascending" />
                              <MenuItem Header="Descending" />
                          </ContextMenu>
                          </GridViewColumnHeader.ContextMenu>
                      </GridViewColumnHeader>
                  </GridViewColumn>

                  <GridViewColumn DisplayMemberBinding=
                          "{Binding Path=EmployeeNumber}" 
                      Header="Employee No." Width="100"/>
    </GridView>

  </ListView.View>
</ListView>

The following illustration shows how this example appears.

ListView with GridView output




How to: Use Triggers to Style Selected Items in a ListView


This example shows how to define Triggers for a ListViewItem control so that when a property value of a ListViewItem changes, the Style of the ListViewItem changes in response.

Example

If you want the Style of a ListViewItem to change in response to property changes, define Triggers for the Style change.

The following example defines a Trigger that sets the Foreground property to Blue and changes the Cursor to display a Hand when the IsMouseOverproperty changes to true.

<Style x:Key="MyContainer" TargetType="{x:Type ListViewItem}">

  <Setter Property="Margin" Value="0,1,0,0"/>
  <Setter Property="Height" Value="21"/>

  <Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
  <Setter Property="Foreground" Value="Blue" />
  <Setter Property="Cursor" Value="Hand"/>
</Trigger>
  </Style.Triggers>
</Style>

The following example defines a MultiTrigger that sets the Foreground property of a ListViewItem to Yellow when the ListViewItem is the selected item and has keyboard focus.

<Style x:Key="MyContainer" TargetType="{x:Type ListViewItem}">

  <Setter Property="Margin" Value="0,1,0,0"/>
  <Setter Property="Height" Value="21"/>

  <Style.Triggers>
<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="IsSelected" Value="true" />
    <Condition Property="Selector.IsSelectionActive" Value="true" />
  </MultiTrigger.Conditions>
  <Setter Property="Foreground" Value="Yellow" />
</MultiTrigger>
  </Style.Triggers>
</Style>




How to: Create ListViewItems with a CheckBox


This example shows how to display a column of CheckBox controls in a ListView control that uses a GridView.

Example

To create a column that contains CheckBox controls in a ListView, create a DataTemplate that contains a CheckBox. Then set the CellTemplate of a GridViewColumn to the DataTemplate.

The following example shows a DataTemplate that contains a CheckBox. The example binds the IsChecked property of the CheckBox to the IsSelectedproperty value of the ListViewItem that contains it. Therefore, when the ListViewItem that contains the CheckBox is selected, the CheckBox is checked.

<DataTemplate x:Key="FirstCell">
  <StackPanel Orientation="Horizontal">
    <CheckBox IsChecked="{Binding Path=IsSelected, 
      RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"/>
  </StackPanel>
</DataTemplate>

The following example shows how to create a column of CheckBox controls. To make the column, the example sets the CellTemplate property of the GridViewColumn to the DataTemplate.

<GridViewColumn CellTemplate="{StaticResource FirstCell}" 
                Width="30"/>




How to: Display Data by Using GridViewRowPresenter


This example shows how to use the GridViewRowPresenter and GridViewHeaderRowPresenter objects to display data in columns.

Example

The following example shows how to specify a GridViewColumnCollection that displays the DayOfWeek and Year of a DateTime object by using GridViewRowPresenter and GridViewHeaderRowPresenter objects. The example also defines a Style for the Header of a GridViewColumn.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
        xmlns:sys="clr-namespace:System;assembly=mscorlib">

  <Window.Resources>

    <Style x:Key="MyHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
     <Setter Property="Background" Value="BurlyWood"/>
    </Style>

    <GridViewColumnCollection x:Key="gvcc">
      <GridViewColumn Header="Year" 
                      DisplayMemberBinding="{Binding Year}" 
                      Width="80"/>
      <GridViewColumn Header="Day"  
                      DisplayMemberBinding="{Binding DayOfWeek}" 
                      Width="80" />

    </GridViewColumnCollection>

  </Window.Resources>

  <StackPanel>
    <GridViewHeaderRowPresenter Name="hrp" Columns="{StaticResource gvcc}"  
                                ColumnHeaderContainerStyle=
                                 "{StaticResource MyHeaderStyle}" />

    <GridViewRowPresenter Columns="{StaticResource gvcc}" >
      <GridViewRowPresenter.Content>
        <sys:DateTime>2005/2/1</sys:DateTime>
      </GridViewRowPresenter.Content>
     </GridViewRowPresenter>
    <GridViewRowPresenter Columns="{StaticResource gvcc}" >
      <GridViewRowPresenter.Content>
        <sys:DateTime>2006/10/12</sys:DateTime>
      </GridViewRowPresenter.Content>
    </GridViewRowPresenter>
  </StackPanel>

</Window>




How to: Group Items in a ListView That Implements a GridView


This example shows how to display groups of items in the GridView view mode of a ListView control.

Example

To display groups of items in a ListView, define a CollectionViewSource. The following example shows a CollectionViewSource that groups data items according to the value of the Catalog data field.

<CollectionViewSource x:Key='src' 
                      Source="{Binding Source={StaticResource MyData}, 
                               XPath=Item}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="@Catalog" />
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

The following example sets the ItemsSource for the ListView to the CollectionViewSource that the previous example defines. The example also defines a GroupStyle that implements an Expander control.

<ListView ItemsSource='{Binding Source={StaticResource src}}' 
          BorderThickness="0">
  <ListView.GroupStyle>
    <GroupStyle>
      <GroupStyle.ContainerStyle>
        <Style TargetType="{x:Type GroupItem}">
          <Setter Property="Margin" Value="0,0,0,5"/>
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type GroupItem}">
                <Expander IsExpanded="True" BorderBrush="#FFA4B97F" 
                          BorderThickness="0,0,0,1">
                  <Expander.Header>
                    <DockPanel>
                      <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" 
                                 Margin="5,0,0,0" Width="100"/>
                      <TextBlock FontWeight="Bold" 
                                 Text="{Binding Path=ItemCount}"/>
                    </DockPanel>
                  </Expander.Header>
                  <Expander.Content>
                    <ItemsPresenter />
                  </Expander.Content>
                </Expander>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </GroupStyle.ContainerStyle>
    </GroupStyle>
  </ListView.GroupStyle>
</ListView>




How to: Style a Row in a ListView That Implements a GridView


This example shows how to style a row in a ListView control that implements a GridView View mode.

Example

You can style a row in a ListView control by setting an ItemContainerStyle on the ListView control. Set the style for its items that are represented as ListViewItem objects. The ItemContainerStyle references the ControlTemplate objects that are used to display the row content.

The complete sample, which the following examples are extracted from, displays a collection of song information that is stored in an XML database. Each song in the database has a rating field and the value of this field specifies how to display a row of song information.

The following example shows how to define ItemContainerStyle for the ListViewItem objects that represent the songs in the song collection. The ItemContainerStyle references ControlTemplate objects that specify how to display a row of song information.

  <ListView.ItemContainerStyle>
   <Style TargetType="{x:Type ListViewItem}"  >
     <Setter Property="Template"
           Value="{StaticResource Default}"/>
     <Style.Triggers>
       <DataTrigger Binding="{Binding XPath=@Rating}" Value="5">
			<Setter Property="Template" 
               Value="{StaticResource StronglyRecommended}"/>
       </DataTrigger>
       <DataTrigger Binding="{Binding XPath=@Rating}" Value="4">
         <Setter Property="Template" 
               Value="{StaticResource Recommended}"/>
       </DataTrigger>
     </Style.Triggers>
</Style>
 </ListView.ItemContainerStyle>

The following example shows a ControlTemplate that adds the text string "Strongly Recommended" to the row. This template is referenced in the ItemContainerStyle and displays when the song's rating has a value of 5 (five). The ControlTemplate includes a GridViewRowPresenter object that lays out the contents of the row in columns as defined by the GridView view mode.

<ControlTemplate x:Key="StronglyRecommended" 
                 TargetType='{x:Type ListViewItem}'>
  <StackPanel Background="Beige">
    <GridViewRowPresenter Content="{TemplateBinding Content}"
       Columns="{TemplateBinding GridView.ColumnCollection}"/>
    <TextBlock Background="LightBlue" Text="Strongly Recommended" />
  </StackPanel>
</ControlTemplate>

The following example defines GridView.

<ListView.View>
  <GridView ColumnHeaderContainerStyle="{StaticResource MyHeaderStyle}">
    <GridViewColumn Header="Name" 
                    DisplayMemberBinding="{Binding XPath=@Name}" 
                    Width="100"/>
    <GridViewColumn Header="Time" 
                    DisplayMemberBinding="{Binding XPath=@Time}" 
                    Width="80"/>
    <GridViewColumn Header="Artist"  
                    DisplayMemberBinding="{Binding XPath=@Artist}" 
                    Width="80" />
    <GridViewColumn Header="Disk" 
                    DisplayMemberBinding="{Binding XPath=@Disk}"  
                    Width="100"/>
  </GridView>
</ListView.View>




How to: Change the Horizontal Alignment of a Column in a ListView


By default, the content of each column in a ListViewItem is left-aligned. You can change the alignment of each column by providing a DataTemplate and setting the HorizontalAlignment property on the element within the DataTemplate. This topic shows how a ListView aligns its content by default and how to change the alignment of one column in a ListView.

Example

In the following example, the data in the Title and ISBN columns is left-aligned.

<!--XmlDataProvider is defined in a ResourceDictionary, 
    such as Window.Resources-->
<XmlDataProvider x:Key="InventoryData" XPath="Books">
    <x:XData>
        <Books xmlns="">
            <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
                <Title>XML in Action</Title>
                <Summary>XML Web Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
                <Title>Programming Microsoft Windows With C#</Title>
                <Summary>C# Programming using the .NET Framework</Summary>
            </Book>
            <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
                <Title>Inside C#</Title>
                <Summary>C# Language Programming</Summary>
            </Book>
            <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
                <Title>Introducing Microsoft .NET</Title>
                <Summary>Overview of .NET Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
                <Title>Microsoft C# Language Specifications</Title>
                <Summary>The C# language definition</Summary>
            </Book>
        </Books>
    </x:XData>
</XmlDataProvider>
<ListView ItemsSource="{Binding Source={StaticResource InventoryData}, XPath=Book}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="300" Header="Title" 
                            DisplayMemberBinding="{Binding XPath=Title}"/>
            <GridViewColumn Width="150" Header="ISBN" 
                            DisplayMemberBinding="{Binding XPath=@ISBN}"/>
        </GridView>
    </ListView.View>
</ListView>

To change the alignment of the ISBN column, you need to specify that the HorizontalContentAlignment property of each ListViewItem is Stretch, so that the elements in each ListViewItem can span or be positioned along the entire width of each column. Because the ListView is bound to a data source, you need to create a style that sets the HorizontalContentAlignment. Next, you need to use a DataTemplate to display the content instead of using the DisplayMemberBinding property. To display the ISBN of each template, the DataTemplate can just contain a TextBlock that has its HorizontalAlignmentproperty set to Right.

The following example defines the style and DataTemplate necessary to make the ISBN column right-aligned, and changes the GridViewColumn to reference the DataTemplate.

<!--The Style and DataTemplate are defined in a ResourceDictionary, 
    such as Window.Resources-->
<Style TargetType="ListViewItem">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>

<DataTemplate x:Key="ISBNTemplate">
    <TextBlock HorizontalAlignment="Right" 
               Text="{Binding XPath=@ISBN}"/>
</DataTemplate>
<ListView ItemsSource="{Binding Source={StaticResource InventoryData}, XPath=Book}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="300" Header="Title" 
                            DisplayMemberBinding="{Binding XPath=Title}"/>
            <GridViewColumn Width="150" Header="ISBN" 
                            CellTemplate="{StaticResource ISBNTemplate}"/>
        </GridView>
    </ListView.View>
</ListView>




How to: Handle the MouseDoubleClick Event for Each Item in a ListView


To handle an event for an item in a ListView, you need to add an event handler to each ListViewItem. When a ListView is bound to a data source, you don't explicitly create a ListViewItem, but you can handle the event for each item by adding an EventSetter to a style of a ListViewItem.

Example

The following example creates a data-bound ListView and creates a Style to add an event handler to each ListViewItem.

<!--XmlDataProvider is defined in a ResourceDictionary, 
    such as Window.Resources-->
<XmlDataProvider x:Key="InventoryData" XPath="Books">
    <x:XData>
        <Books xmlns="">
            <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
                <Title>XML in Action</Title>
                <Summary>XML Web Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
                <Title>Programming Microsoft Windows With C#</Title>
                <Summary>C# Programming using the .NET Framework</Summary>
            </Book>
            <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
                <Title>Inside C#</Title>
                <Summary>C# Language Programming</Summary>
            </Book>
            <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
                <Title>Introducing Microsoft .NET</Title>
                <Summary>Overview of .NET Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
                <Title>Microsoft C# Language Specifications</Title>
                <Summary>The C# language definition</Summary>
            </Book>
        </Books>
    </x:XData>
</XmlDataProvider>
<!--The Style is defined in a ResourceDictionary, 
    such as Window.Resources-->
<Style TargetType="ListViewItem">
    <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
</Style>
<ListView ItemsSource="{Binding Source={StaticResource InventoryData}, XPath=Book}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="300" Header="Title" 
                            DisplayMemberBinding="{Binding XPath=Title}"/>
            <GridViewColumn Width="150" Header="ISBN" 
                            DisplayMemberBinding="{Binding XPath=@ISBN}"/>
        </GridView>
    </ListView.View>
</ListView>

The following example handles the MouseDoubleClick event.

void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{

    XmlElement book = ((ListViewItem) sender).Content as XmlElement;

    if (book == null)
    {
        return;
    }

    if (book.GetAttribute("Stock") == "out")
    {
        MessageBox.Show("Time to order more copies of " + book["Title"].InnerText);
    }
    else
    {
        MessageBox.Show(book["Title"].InnerText + " is available.");
    }
}




ListViewItem Class


Represents an item in a ListView control.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.ListBoxItem
                  System.Windows.Controls.ListViewItem


Remarks

ListViewItem 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.

ListView typically specifies the content for its ListViewItem controls by setting the ItemsSource property or the Items property. For an example, see .

Templates and styles that are defined for the ListViewItem type are used to specify the display of the content in a ListView.

Customizing the ListViewItem Control

To apply the same property settings to multiple ListViewItem 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 ListViewItem, see ListView 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in ListViewItem 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.






Menu




Menu Overview


The Menu class enables you to organize elements associated with commands and event handlers in a hierarchical order. Each Menu element contains a collection of MenuItem elements.

Menu Control

The Menu control presents a list of items that specify commands or options for an application. Typically, clicking a MenuItem opens a submenu or causes an application to carry out a command.

Creating Menus

The following example creates a Menu to manipulate text in a TextBox. The Menu contains MenuItem objects that use the CommandIsCheckable, and Header properties and the CheckedUnchecked, and Click events.

<Menu>
  <MenuItem Header="_Edit">
    <MenuItem Command="ApplicationCommands.Copy"/>
    <MenuItem Command="ApplicationCommands.Cut"/>
    <MenuItem Command="ApplicationCommands.Paste"/>
  </MenuItem>
  <MenuItem Header="_Font">
    <MenuItem Header="_Bold" IsCheckable="True"
              Checked="Bold_Checked"
              Unchecked="Bold_Unchecked"/>
    <MenuItem Header="_Italic" IsCheckable="True"
              Checked="Italic_Checked"
              Unchecked="Italic_Unchecked"/>
    <Separator/>
    <MenuItem Header="I_ncrease Font Size"
              Click="IncreaseFont_Click"/>
    <MenuItem Header="_Decrease Font Size"
              Click="DecreaseFont_Click"/>
  </MenuItem>
</Menu>
<TextBox Name="textBox1" TextWrapping="Wrap"
         Margin="2">
  The quick brown fox jumps over the lazy dog.
</TextBox>
private void Bold_Checked(object sender, RoutedEventArgs e)
{
    textBox1.FontWeight = FontWeights.Bold;
}

private void Bold_Unchecked(object sender, RoutedEventArgs e)
{
    textBox1.FontWeight = FontWeights.Normal;
}

private void Italic_Checked(object sender, RoutedEventArgs e)
{
    textBox1.FontStyle = FontStyles.Italic;
}

private void Italic_Unchecked(object sender, RoutedEventArgs e)
{
    textBox1.FontStyle = FontStyles.Normal;
}

private void IncreaseFont_Click(object sender, RoutedEventArgs e)
{
    if (textBox1.FontSize < 18)
    {
        textBox1.FontSize += 2;
    }
}

private void DecreaseFont_Click(object sender, RoutedEventArgs e)
{
    if (textBox1.FontSize > 10)
    {
        textBox1.FontSize -= 2;
    }
}

MenuItems with Keyboard Shortcuts

Keyboard shortcuts are character combinations that can be entered with the keyboard to invoke Menu commands. For example, the shortcut for Copy is CTRL+C. There are two properties to use with keyboard shortcuts and menu items —InputGestureText or Command.

InputGestureText

The following example shows how to use the InputGestureText property to assign keyboard shortcut text to MenuItem controls. This only places the keyboard shortcut in the menu item. It does not associate the command with the MenuItem. The application must handle the user's input to carry out the action.

<MenuItem Header="_Cut" InputGestureText="Ctrl+X"/>
<MenuItem Header="_Find" InputGestureText="Ctrl+F"/>

Command

The following example shows how to use the Command property to associate the Open and Save commands with MenuItem controls. Not only does the command property associate a command with a MenuItem, but it also supplies the input gesture text to use as a shortcut.

<MenuItem Header="_Open" Command="ApplicationCommands.Open"/>
<MenuItem Header="_Save" Command="ApplicationCommands.Save"/>

The MenuItem class also has a CommandTarget property, which specifies the element where the command occurs. If CommandTarget is not set, the element that has keyboard focus receives the command. For more information about commands, see Commanding Overview.

Menu Styling

With control styling, you can dramatically change the appearance and behavior of Menu controls without having to write a custom control. In addition to setting visual properties, you can also apply a Style to individual parts of a control, change the behavior of parts of the control through properties, or add additional parts or change the layout of a control. The following examples demonstrate several ways to add a Style to a Menucontrol.

The first code example defines a Style called Simple that shows how to use the current system settings in your style. The code assigns the color of the MenuHighlightBrush as the menu's background color and the MenuTextBrush as the menu's foreground color. Notice that you use resource keys to assign the brushes.

<Style x:Key="Simple" TargetType="{x:Type MenuItem}">
  <Setter Property = "Background" Value= "{DynamicResource {x:Static SystemColors.MenuHighlightBrushKey}}"/>
  <Setter Property = "Foreground" Value= "{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/>
  <Setter Property = "Height" Value= "{DynamicResource {x:Static SystemParameters.CaptionHeightKey}}"/>
</Style>

The following sample uses Trigger elements that enable you to change the appearance of a MenuItem in response to events that occur on the Menu. When you move the mouse over the Menu, the foreground color and the font characteristics of the menu items change.

<Style x:Key="Triggers" TargetType="{x:Type MenuItem}">
  <Style.Triggers>
    <Trigger Property="MenuItem.IsMouseOver" Value="true">
      <Setter Property = "Foreground" Value="Red"/>
      <Setter Property = "FontSize" Value="16"/>
      <Setter Property = "FontStyle" Value="Italic"/>
    </Trigger>
  </Style.Triggers>
</Style>




MenuItem Class


Represents a selectable item inside a Menu.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.MenuItem
                    System.Windows.Controls.Ribbon.RibbonMenuItem


Remarks

MenuItem 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.

MenuItem can have submenus. The submenu of the MenuItem is made up of the objects within the ItemCollection of a MenuItem. It is common for a MenuItem to contain other MenuItem objects to create nested submenus.

MenuItem can have one of several functions:

  • It can be selected to invoke a command.

  • It can be a separator for other menu items.

  • It can be a header for a submenu.

  • It can be checked or unchecked.

System_CAPS_noteNote

   By default, the HorizontalAlignment of a MenuItem is set to HorizontalAlignment.Stretch. The default horizontal position of a StackPanel is HorizontalAlignment.Center. If you set the Width property of a MenuItem through a StackPanel, the stack panel's default is applied and the item is centered.

TheMenuItem handles the MouseDown event, so if you attach an event handler to MouseDown, your handler will never be called. To add your own handler, subscribe to the PreviewMouseDown event or subscribe to MouseDown by calling AddHandler(RoutedEvent, Delegate, Boolean) with handledEventsToo set to true.

Customizing the MenuItem Control

To apply the same property settings to multiple MenuItem 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 MenuItem, see Menu 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in MenuItem 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 Menu to manipulate text in a TextBox. The Menu contains MenuItem objects that use the CommandIsCheckable, and Header properties and the CheckedUnchecked, and Click events.

<Menu>
  <MenuItem Header="_Edit">
    <MenuItem Command="ApplicationCommands.Copy"/>
    <MenuItem Command="ApplicationCommands.Cut"/>
    <MenuItem Command="ApplicationCommands.Paste"/>
  </MenuItem>
  <MenuItem Header="_Font">
    <MenuItem Header="_Bold" IsCheckable="True"
              Checked="Bold_Checked"
              Unchecked="Bold_Unchecked"/>
    <MenuItem Header="_Italic" IsCheckable="True"
              Checked="Italic_Checked"
              Unchecked="Italic_Unchecked"/>
    <Separator/>
    <MenuItem Header="I_ncrease Font Size"
              Click="IncreaseFont_Click"/>
    <MenuItem Header="_Decrease Font Size"
              Click="DecreaseFont_Click"/>
  </MenuItem>
</Menu>
<TextBox Name="textBox1" TextWrapping="Wrap"
         Margin="2">
  The quick brown fox jumps over the lazy dog.
</TextBox>
private void Bold_Checked(object sender, RoutedEventArgs e)
{
    textBox1.FontWeight = FontWeights.Bold;
}

private void Bold_Unchecked(object sender, RoutedEventArgs e)
{
    textBox1.FontWeight = FontWeights.Normal;
}

private void Italic_Checked(object sender, RoutedEventArgs e)
{
    textBox1.FontStyle = FontStyles.Italic;
}

private void Italic_Unchecked(object sender, RoutedEventArgs e)
{
    textBox1.FontStyle = FontStyles.Normal;
}

private void IncreaseFont_Click(object sender, RoutedEventArgs e)
{
    if (textBox1.FontSize < 18)
    {
        textBox1.FontSize += 2;
    }
}

private void DecreaseFont_Click(object sender, RoutedEventArgs e)
{
    if (textBox1.FontSize > 10)
    {
        textBox1.FontSize -= 2;
    }
}




MenuBase Class


Represents a control that defines choices for users to select.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.MenuBase
                  System.Windows.Controls.ContextMenu
                  System.Windows.Controls.Menu


Remarks

The MenuBase is the base class for controls that define choices for users to select. The Menu and ContextMenu inherit from MenuBase and allow the user to select an item to invoke some action.

MenuBase 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.





Panel




Panels Overview


Panel elements are components that control the rendering of elements—their size and dimensions, their position, and the arrangement of their child content. The Windows Presentation Foundation (WPF) provides a number of predefined Panel elements as well as the ability to construct custom Panelelements.

The Panel Class

Panel is the base class for all elements that provide layout support in Windows Presentation Foundation (WPF). Derived Panel elements are used to position and arrange elements in Extensible Application Markup Language (XAML) and code.

The WPF includes a comprehensive suite of derived panel implementations that enable many complex layouts. These derived classes expose properties and methods that enable most standard user interface (UI) scenarios. Developers who are unable to find a child arrangement behavior that meets their needs can create new layouts by overriding the ArrangeOverride and MeasureOverride methods. For more information on custom layout behaviors, see Custom Panel Elements.

Panel Common Members

All Panel elements support the base sizing and positioning properties defined by FrameworkElement, including HeightWidthHorizontalAlignmentVerticalAlignmentMargin, and LayoutTransform. For additional information on positioning properties defined by FrameworkElement, see Alignment, Margins, and Padding Overview.

Panel exposes additional properties that are of critical importance in understanding and using layout. The Background property is used to fill the area between the boundaries of a derived panel element with a BrushChildren represents the child collection of elements that the Panel is comprised of. InternalChildren represents the content of the Children collection plus those members generated by data binding. Both consist of a UIElementCollection of child elements hosted within the parent Panel.

Panel also exposes a Panel.ZIndex attached property that can be used to achieve layered order in a derived Panel. Members of a panel's Childrencollection with a higher Panel.ZIndex value appear in front of those with a lower Panel.ZIndex value. This is particularly useful for panels such as Canvas and Grid which allow children to share the same coordinate space.

Panel also defines the OnRender method, which can be used to override the default presentation behavior of a Panel.

Attached Properties

Derived panel elements make extensive use of attached properties. An attached property is a specialized form of dependency property that does not have the conventional common language runtime (CLR) property "wrapper". Attached properties have a specialized syntax in Extensible Application Markup Language (XAML), which can be seen in several of the examples that follow.

One purpose of an attached property is to allow child elements to store unique values of a property that is actually defined by a parent element. An application of this functionality is having child elements inform the parent how they wish to be presented in the user interface (UI), which is extremely useful for application layout. For more information, see Attached Properties Overview.

Derived Panel Elements

Many objects derive from Panel, but not all of them are intended for use as root layout providers. There are six defined panel classes (CanvasDockPanelGridStackPanelVirtualizingStackPanel, and WrapPanel) that are designed specifically for creating application UI.

Each panel element encapsulates its own special functionality, as seen in the following table.

Element Name

UI Panel?

Description

Canvas

Yes

Defines an area within which you can explicitly position child elements by coordinates relative to the Canvasarea.

DockPanel

Yes

Defines an area within which you can arrange child elements either horizontally or vertically, relative to each other.

Grid

Yes

Defines a flexible grid area consisting of columns and rows. Child elements of a Grid can be positioned precisely using the Margin property.

StackPanel

Yes

Arranges child elements into a single line that can be oriented horizontally or vertically.

TabPanel

No

Handles the layout of tab buttons in a TabControl.

ToolBarOverflowPanel

No

Arranges content within a ToolBar control.

UniformGrid

No

UniformGrid is used to arrange children in a grid with all equal cell sizes.

VirtualizingPanel

No

Provides a base class for panels that can "virtualize" their children collection.

VirtualizingStackPanel

Yes

Arranges and virtualizes content on a single line oriented horizontally or vertically.

WrapPanel

Yes

WrapPanel 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 right to left, depending on the value of the Orientation property.

User Interface Panels

There are six panel classes available in WPF that are optimized to support UI scenarios: CanvasDockPanelGridStackPanelVirtualizingStackPanel, and WrapPanel. These panel elements are easy to use, versatile, and extensible enough for most applications.

Each derived Panel element treats sizing constraints differently. Understanding how a Panel handles constraints in either the horizontal or vertical direction can make layout more predictable.

Panel Name

x-Dimension

y-Dimension

Canvas

Constrained to content

Constrained to content

DockPanel

Constrained

Constrained

StackPanel (Vertical Orientation)

Constrained

Constrained to content

StackPanel (Horizontal Orientation)

Constrained to content

Constrained

Grid

Constrained

Constrained, except in cases where Auto apply to rows and columns

WrapPanel

Constrained to content

Constrained to content

More detailed descriptions and usage examples of each of these elements can be found below.

Canvas

The Canvas element enables positioning of content according to absolute x- and y-coordinates. Elements can be drawn in a unique location; or, if elements occupy the same coordinates, the order in which they appear in markup determines the order in which the elements are drawn.

Canvas provides the most flexible layout support of any Panel. Height and Width properties are used to define the area of the canvas, and elements inside are assigned absolute coordinates relative to the area of the parent Canvas. Four attached properties, Canvas.LeftCanvas.TopCanvas.Right and Canvas.Bottom, allow fine control of object placement within a Canvas, allowing the developer to position and arrange elements precisely on the screen.

ClipToBounds Within a Canvas

Canvas can position child elements at any position on the screen, even at coordinates that are outside of its own defined Height and Width. Furthermore, Canvas is not affected by the size of its children. As a result, it is possible for a child element to overdraw other elements outside the bounding rectangle of the parent Canvas. The default behavior of a Canvas is to allow children to be drawn outside the bounds of the parent Canvas. If this behavior is undesirable, the ClipToBounds property can be set to true. This causes Canvas to clip to its own size. Canvas is the only layout element that allows children to be drawn outside its bounds.

This behavior is graphically illustrated in the Width Properties Comparison Sample.

Defining and Using a Canvas

Canvas can be instantiated simply by using Extensible Application Markup Language (XAML) or code. The following example demonstrates how to use Canvas to absolutely position content. This code produces three 100-pixel squares. The first square is red, and its top-left (x, y) position is specified as (0, 0). The second square is green, and its top-left position is (100, 100), just below and to the right of the first square. The third square is blue, and its top-left position is (50, 50), thus encompassing the lower-right quadrant of the first square and the upper-left quadrant of the second. Because the third square is laid out last, it appears to be on top of the other two squares—that is, the overlapping portions assume the color of the third box.

// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "Canvas Sample";

// Create the Canvas
myParentCanvas = new Canvas();
myParentCanvas.Width = 400;
myParentCanvas.Height = 400;

// Define child Canvas elements
myCanvas1 = new Canvas();
myCanvas1.Background = Brushes.Red;
myCanvas1.Height = 100;
myCanvas1.Width = 100;
Canvas.SetTop(myCanvas1, 0);
Canvas.SetLeft(myCanvas1, 0);

myCanvas2 = new Canvas();
myCanvas2.Background = Brushes.Green;
myCanvas2.Height = 100;
myCanvas2.Width = 100;
Canvas.SetTop(myCanvas2, 100);
Canvas.SetLeft(myCanvas2, 100);

myCanvas3 = new Canvas();
myCanvas3.Background = Brushes.Blue;
myCanvas3.Height = 100;
myCanvas3.Width = 100;
Canvas.SetTop(myCanvas3, 50);
Canvas.SetLeft(myCanvas3, 50);

// Add child elements to the Canvas' Children collection
myParentCanvas.Children.Add(myCanvas1);
myParentCanvas.Children.Add(myCanvas2);
myParentCanvas.Children.Add(myCanvas3);

// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myParentCanvas;
mainWindow.Show ();

<Page WindowTitle="Canvas Sample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Canvas Height="400" Width="400">
    <Canvas Height="100" Width="100" Top="0" Left="0" Background="Red"/>
    <Canvas Height="100" Width="100" Top="100" Left="100" Background="Green"/>
    <Canvas Height="100" Width="100" Top="50" Left="50" Background="Blue"/>
  </Canvas>
</Page>

The compiled application yields a new UI that looks like this.

A typical Canvas Element.

DockPanel

The DockPanel element uses the DockPanel.Dock attached property as set in child content elements to position content along the edges of a container. When DockPanel.Dock is set to Top or Bottom, it positions child elements above or below each other. When DockPanel.Dock is set to Left or Right, it positions child elements to the left or right of each other. The LastChildFill property determines the position of the final element added as a child of a DockPanel.

You can use DockPanel to position a group of related controls, such as a set of buttons. Alternately, you can use it to create a "paned" UI, similar to that found in Microsoft Outlook.

Sizing to Content

If its Height and Width properties are not specified, DockPanel sizes to its content. The size can increase or decrease to accommodate the size of its child elements. However, when these properties are specified and there is no longer room for the next specified child element, DockPaneldoes not display that child element or subsequent child elements and does not measure subsequent child elements.

LastChildFill

By default, the last child of a DockPanel element will "fill" the remaining, unallocated space. If this behavior is not desired, set the LastChildFillproperty to false.

Defining and Using a DockPanel

The following example demonstrates how to partition space using a DockPanel. Five Border elements are added as children of a parent DockPanel. Each uses a different positioning property of a DockPanel to partition space. The final element "fills" the remaining, unallocated space.

// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "DockPanel Sample";

// Create the DockPanel
DockPanel myDockPanel = new DockPanel();
myDockPanel.LastChildFill = true;

// Define the child content
Border myBorder1 = new Border();
myBorder1.Height = 25;
myBorder1.Background = Brushes.SkyBlue;
myBorder1.BorderBrush = Brushes.Black;
myBorder1.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder1, Dock.Top);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.Foreground = Brushes.Black;
myTextBlock1.Text = "Dock = Top";
myBorder1.Child = myTextBlock1;

Border myBorder2 = new Border();
myBorder2.Height = 25;
myBorder2.Background = Brushes.SkyBlue;
myBorder2.BorderBrush = Brushes.Black;
myBorder2.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder2, Dock.Top);
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Foreground = Brushes.Black;
myTextBlock2.Text = "Dock = Top";
myBorder2.Child = myTextBlock2;

Border myBorder3 = new Border();
myBorder3.Height = 25;
myBorder3.Background = Brushes.LemonChiffon;
myBorder3.BorderBrush = Brushes.Black;
myBorder3.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder3, Dock.Bottom);
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Foreground = Brushes.Black;
myTextBlock3.Text = "Dock = Bottom";
myBorder3.Child = myTextBlock3;

Border myBorder4 = new Border();
myBorder4.Width = 200;
myBorder4.Background = Brushes.PaleGreen;
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Left);
TextBlock myTextBlock4 = new TextBlock();
myTextBlock4.Foreground = Brushes.Black;
myTextBlock4.Text = "Dock = Left";
myBorder4.Child = myTextBlock4;

Border myBorder5 = new Border();
myBorder5.Background = Brushes.White;
myBorder5.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
TextBlock myTextBlock5 = new TextBlock();
myTextBlock5.Foreground = Brushes.Black;
myTextBlock5.Text = "This content will Fill the remaining space";
myBorder5.Child = myTextBlock5;


// Add child elements to the DockPanel Children collection
myDockPanel.Children.Add(myBorder1);
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);

// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myDockPanel;
mainWindow.Show ();

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="DockPanel Sample">
  <DockPanel LastChildFill="True">
    <Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
      <TextBlock Foreground="Black">Dock = "Top"</TextBlock>
    </Border>
    <Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
      <TextBlock Foreground="Black">Dock = "Top"</TextBlock>
    </Border>
    <Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
      <TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
    </Border>
    <Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
      <TextBlock Foreground="Black">Dock = "Left"</TextBlock>
    </Border>
    <Border Background="White" BorderBrush="Black" BorderThickness="1">
      <TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
    </Border>
  </DockPanel>
</Page>

The compiled application yields a new UI that looks like this.

A typical DockPanel scenario.

Grid

The Grid element merges the functionality of an absolute positioning and tabular data control. A Grid enables you to easily position and style elements. Grid allows you to define flexible row and column groupings, and even provides a mechanism to share sizing information between multiple Grid elements.

How is Grid Different from Table?

Table and Grid share some common functionality, but each is best suited for different scenarios. A Table is designed for use within flow content (see Flow Document Overview for more information on flow content). Grids are best used inside of forms (basically anywhere outside of flow content). Within a FlowDocumentTable supports flow content behaviors like pagination, column reflow, and content selection while a Grid does not. A Grid on the other hand is best used outside of a FlowDocument for many reasons including Grid adds elements based on a row and column index, Table does not. The Grid element allows layering of child content, allowing more than one element to exist within a single "cell." Table does not support layering. Child elements of a Grid can be absolutely positioned relative to the area of their "cell" boundaries. Table does not support this feature. Finally, a Grid is lighter weight than a Table.

Sizing Behavior of Columns and Rows

Columns and rows defined within a Grid can take advantage of Star sizing in order to distribute remaining space proportionally. When Star is selected as the Height or Width of a row or column, that column or row receives a weighted proportion of remaining available space. This is in contrast to Auto, which will distribute space evenly based on the size of the content within a column or row. This value is expressed as * or 2*when using Extensible Application Markup Language (XAML). In the first case, the row or column would receive one times the available space, in the second case, two times, and so on. By combining this technique to proportionally distribute space with a HorizontalAlignment and VerticalAlignment value of Stretch it is possible to partition layout space by percentage of screen space. Grid is the only layout panel that can distribute space in this manner.

Defining and Using a Grid

The following example demonstrates how to build a UI similar to that found on the Run dialog available on the Windows Start menu.

// Create the Grid.
grid1 = new Grid ();
grid1.Background = Brushes.Gainsboro;
grid1.HorizontalAlignment = HorizontalAlignment.Left;
grid1.VerticalAlignment = VerticalAlignment.Top;
grid1.ShowGridLines = true;
grid1.Width = 425;
grid1.Height = 165;

// Define the Columns.
colDef1 = new ColumnDefinition();
colDef1.Width = new GridLength(1, GridUnitType.Auto);
colDef2 = new ColumnDefinition();
colDef2.Width = new GridLength(1, GridUnitType.Star);
colDef3 = new ColumnDefinition();
colDef3.Width = new GridLength(1, GridUnitType.Star);
colDef4 = new ColumnDefinition();
colDef4.Width = new GridLength(1, GridUnitType.Star);
colDef5 = new ColumnDefinition();
colDef5.Width = new GridLength(1, GridUnitType.Star);
grid1.ColumnDefinitions.Add(colDef1);
grid1.ColumnDefinitions.Add(colDef2);
grid1.ColumnDefinitions.Add(colDef3);
grid1.ColumnDefinitions.Add(colDef4);
grid1.ColumnDefinitions.Add(colDef5);

// Define the Rows.
rowDef1 = new RowDefinition();
rowDef1.Height = new GridLength(1, GridUnitType.Auto);
rowDef2 = new RowDefinition();
rowDef2.Height = new GridLength(1, GridUnitType.Auto);
rowDef3 = new RowDefinition();
rowDef3.Height = new GridLength(1, GridUnitType.Star);
rowDef4 = new RowDefinition();
rowDef4.Height = new GridLength(1, GridUnitType.Auto);
grid1.RowDefinitions.Add(rowDef1);
grid1.RowDefinitions.Add(rowDef2);
grid1.RowDefinitions.Add(rowDef3);
grid1.RowDefinitions.Add(rowDef4);

// Add the Image.
img1 = new Image();
img1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("runicon.png", UriKind.Relative));
Grid.SetRow(img1, 0);
Grid.SetColumn(img1, 0);

// Add the main application dialog.
txt1 = new TextBlock();
txt1.Text = "Type the name of a program, folder, document, or Internet resource, and Windows will open it for you.";
txt1.TextWrapping = TextWrapping.Wrap;
Grid.SetColumnSpan(txt1, 4);
Grid.SetRow(txt1, 0);
Grid.SetColumn(txt1, 1);

// Add the second text cell to the Grid.
txt2 = new TextBlock();
txt2.Text = "Open:";
Grid.SetRow(txt2, 1);
Grid.SetColumn(txt2, 0);

// Add the TextBox control.
tb1 = new TextBox();
Grid.SetRow(tb1, 1);
Grid.SetColumn(tb1, 1);
Grid.SetColumnSpan(tb1, 5);

// Add the buttons.
button1 = new Button();
button2 = new Button();
button3 = new Button();
button1.Content = "OK";
button2.Content = "Cancel";
button3.Content = "Browse ...";
Grid.SetRow(button1, 3);
Grid.SetColumn(button1, 2);
button1.Margin = new Thickness(10, 0, 10, 15);
button2.Margin = new Thickness(10, 0, 10, 15);
button3.Margin = new Thickness(10, 0, 10, 15);
Grid.SetRow(button2, 3);
Grid.SetColumn(button2, 3);
Grid.SetRow(button3, 3);
Grid.SetColumn(button3, 4);

grid1.Children.Add(img1);
grid1.Children.Add(txt1);
grid1.Children.Add(txt2);
grid1.Children.Add(tb1);
grid1.Children.Add(button1);
grid1.Children.Add(button2);
grid1.Children.Add(button3);

mainWindow.Content = grid1;

The compiled application yields a new UI that looks like this.

A typical Grid Element.

StackPanel

StackPanel enables you to "stack" elements in an assigned direction. The default stack direction is vertical. The Orientation property can be used to control content flow.

StackPanel vs. DockPanel

Although DockPanel can also "stack" child elements, DockPanel and StackPanel do not produce analogous results in some usage scenarios. For example, the order of child elements can affect their size in a DockPanel but not in a StackPanel. This is because StackPanel measures in the direction of stacking at PositiveInfinity, whereas DockPanel measures only the available size.

The following example demonstrates this key difference.

// 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>

The difference in rendering behavior can be seen in this image.

Screenshot: StackPanel vs. DockPanel screenshot

Defining and Using a StackPanel

The following example demonstrates how to use a StackPanel to create a set of vertically-positioned buttons. For horizontal positioning, set the Orientation property to Horizontal.

// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "StackPanel Sample";

// Define the StackPanel
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;

// Define child content
Button myButton1 = new Button();
myButton1.Content = "Button 1";
Button myButton2 = new Button();
myButton2.Content = "Button 2";
Button myButton3 = new Button();
myButton3.Content = "Button 3";

// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myStackPanel.Children.Add(myButton3);           

// Add the StackPanel as the Content of the Parent Window Object
mainWindow.Content = myStackPanel;
mainWindow.Show ();

The compiled application yields a new UI that looks like this.

A typical StackPanel element.

VirtualizingStackPanel

WPF also provides a variation of the StackPanel element that automatically "virtualizes" data-bound child content. In this context, the word virtualize refers to a technique by which a subset of elements are generated from a larger number of data items based upon which items are visible on-screen. It is intensive, both in terms of memory and processor, to generate a large number of UI elements when only a few may be on the screen at a given time. VirtualizingStackPanel (through functionality provided by VirtualizingPanel) calculates visible items and works with the ItemContainerGenerator from an ItemsControl (such as ListBox or ListView) to only create elements for visible items.

The VirtualizingStackPanel element is automatically set as the items host for controls such as the ListBox. When hosting a data bound collection, content is automatically virtualized, as long as the content is within the bounds of a ScrollViewer. This greatly improves performance when hosting many child items.

The following markup demonstrates how to use a VirtualizingStackPanel as an items host. The VirtualizingStackPanel.IsVirtualizing attached property must be set to true (default) for virtualization to occur.

<StackPanel DataContext="{Binding Source={StaticResource Leagues}}">
    <TextBlock Text="{Binding XPath=@name}" FontFamily="Arial" FontSize="18" Foreground="Black"/>
        <ListBox VirtualizingStackPanel.IsVirtualizing="True" 
                 ItemsSource="{Binding XPath=Team}" 
                 ItemTemplate="{DynamicResource NameDataStyle}"/>      
</StackPanel>

WrapPanel

WrapPanel is used to position child elements in sequential position from left to right, breaking content to the next line when it reaches the edge of its parent container. Content can be oriented horizontally or vertically. WrapPanel is useful for simple flowing user interface (UI) scenarios. It can also be used to apply uniform sizing to all of its child elements.

The following example demonstrates how to create a WrapPanel to display Button controls that wrap when they reach the edge of their container.

// Create the application's main window
mainWindow = 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>

The compiled application yields a new UI that looks like this.

A typical WrapPanel Element.

Nested Panel Elements

Panel elements can be nested within each other in order to produce complex layouts. This can prove very useful in situations where one Panel is ideal for a portion of a UI, but may not meet the needs of a different portion of the UI.

There is no practical limit to the amount of nesting that your application can support, however, it is generally best to limit your application to only use those panels that are actually necessary for your desired layout. In many cases, a Grid element can be used instead of nested panels due to its flexibility as a layout container. This can increase performance in your application by keeping unnecessary elements out of the tree.

The following example demonstrates how to create a UI that takes advantage of nested Panel elements in order to achieve a specific layout. In this particular case, a DockPanel element is used to provide UI structure, and nested StackPanel elements, a Grid, and a Canvas are used to position child elements precisely within the parent DockPanel.

// Define the DockPanel.
myDockPanel = new DockPanel();

// Add the Left Docked StackPanel
Border myBorder2 = new Border();
myBorder2.BorderThickness = new Thickness(1);
myBorder2.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder2, Dock.Left);
StackPanel myStackPanel = new StackPanel();
Button myButton1 = new Button();
myButton1.Content = "Left Docked";
myButton1.Margin = new Thickness(5);
Button myButton2 = new Button();
myButton2.Content = "StackPanel";
myButton2.Margin = new Thickness(5);
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myBorder2.Child = myStackPanel;

// Add the Top Docked Grid.
Border myBorder3 = new Border();
myBorder3.BorderThickness = new Thickness(1);
myBorder3.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder3, Dock.Top);
Grid myGrid = new Grid();
myGrid.ShowGridLines = true;
RowDefinition myRowDef1 = new RowDefinition();
RowDefinition myRowDef2 = new RowDefinition();
ColumnDefinition myColDef1 = new ColumnDefinition();
ColumnDefinition myColDef2 = new ColumnDefinition();
ColumnDefinition myColDef3 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(myColDef1);
myGrid.ColumnDefinitions.Add(myColDef2);
myGrid.ColumnDefinitions.Add(myColDef3);
myGrid.RowDefinitions.Add(myRowDef1);
myGrid.RowDefinitions.Add(myRowDef2);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.FontSize = 20;
myTextBlock1.Margin = new Thickness(10);
myTextBlock1.Text = "Grid Element Docked at the Top";
Grid.SetRow(myTextBlock1, 0);
Grid.SetColumnSpan(myTextBlock1, 3);
Button myButton3 = new Button();
myButton3.Margin = new Thickness(5);
myButton3.Content = "A Row";
Grid.SetColumn(myButton3, 0);
Grid.SetRow(myButton3, 1);
Button myButton4 = new Button();
myButton4.Margin = new Thickness(5);
myButton4.Content = "of Button";
Grid.SetColumn(myButton4, 1);
Grid.SetRow(myButton4, 1);
Button myButton5 = new Button();
myButton5.Margin = new Thickness(5);
myButton5.Content = "Elements";
Grid.SetColumn(myButton5, 2);
Grid.SetRow(myButton5, 1);
myGrid.Children.Add(myTextBlock1);
myGrid.Children.Add(myButton3);
myGrid.Children.Add(myButton4);
myGrid.Children.Add(myButton5);
myBorder3.Child = myGrid;

// Add the Bottom Docked StackPanel.
Border myBorder4 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Bottom);
StackPanel myStackPanel2 = new StackPanel();
myStackPanel2.Orientation = Orientation.Horizontal;
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Text = "This StackPanel is Docked to the Bottom";
myTextBlock2.Margin = new Thickness(5);
myStackPanel2.Children.Add(myTextBlock2);
myBorder4.Child = myStackPanel2;

// Add the Canvas, that fills remaining space.
Border myBorder5 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
Canvas myCanvas = new Canvas();
myCanvas.ClipToBounds = true;
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Text = "Content in the Canvas will Fill the remaining space.";
Canvas.SetTop(myTextBlock3, 50);
Canvas.SetLeft(myTextBlock3, 50);
Ellipse myEllipse = new Ellipse();
myEllipse.Height = 100;
myEllipse.Width = 125;
myEllipse.Fill = Brushes.CornflowerBlue;
myEllipse.Stroke = Brushes.Aqua;
Canvas.SetTop(myEllipse, 100);
Canvas.SetLeft(myEllipse, 150);
myCanvas.Children.Add(myTextBlock3);
myCanvas.Children.Add(myEllipse);
myBorder5.Child = myCanvas;

// Add child elements to the parent DockPanel.
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);

The compiled application yields a new UI that looks like this.

A UI that takes advantage of nested panels.

Custom Panel Elements

While WPF provides an array of flexible layout controls, custom layout behaviors can also be achieved by overriding the ArrangeOverride and MeasureOverride methods. Custom sizing and positioning can be accomplished by defining new positioning behaviors within these override methods.

Similarly, custom layout behaviors based on derived classes (such as Canvas or Grid) can be defined by overriding their ArrangeOverride and MeasureOverride methods.

The following markup demonstrates how to create a custom Panel element. This new Panel, defined as PlotPanel, supports the positioning of child elements through the use of hard-coded x- and y-coordinates. In this example, a Rectangle element (not shown) is positioned at plot point 50 (x), and 50 (y).

public class PlotPanel : Panel
{
    // Default public constructor
    public PlotPanel()
        : base()
    {
    }

    // Override the default Measure method of Panel
    protected override Size MeasureOverride(Size availableSize)
    {
        Size panelDesiredSize = new Size();

        // In our example, we just have one child. 
        // Report that our panel requires just the size of its only child.
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            panelDesiredSize = child.DesiredSize;
        }

        return panelDesiredSize ;
    }
    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (UIElement child in InternalChildren)
        {
            double x = 50;
            double y = 50;

            child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
        }
        return finalSize; // Returns the final Arranged size
    }
}

To view a more complex custom panel implementation, see Create a Custom Content-Wrapping Panel Sample.

Localization/Globalization Support

WPF supports a number of features that assist in the creation of localizable UI.

All panel elements natively support the FlowDirection property, which can be used to dynamically re-flow content based on a user's locale or language settings. For more information, see FlowDirection.

The SizeToContent property provides a mechanism that enables application developers to anticipate the needs of localized UI. Using the WidthAndHeight value of this property, a parent Window always sizes dynamically to fit content and is not constrained by artificial height or width restrictions.

DockPanelGrid, and StackPanel are all good choices for localizable UI. Canvas is not a good choice, however, because it positions content absolutely, making it difficult to localize.

For additional information on creating WPF applications with localizable user interfaces (UIs)s, see the Use Automatic Layout Overview.





Panel Class


Provides a base class for all Panel elements. Use Panel elements to position and arrange child objects in Windows Presentation Foundation (WPF) applications.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Panel
              System.Windows.Controls.Canvas
              System.Windows.Controls.DockPanel
              System.Windows.Controls.Grid
              System.Windows.Controls.Primitives.TabPanel
              System.Windows.Controls.Primitives.ToolBarOverflowPanel
              System.Windows.Controls.Primitives.UniformGrid
              System.Windows.Controls.Ribbon.Primitives.RibbonContextualTabGroupsPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonGalleryCategoriesPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonGalleryItemsPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonGroupItemsPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonQuickAccessToolBarOverflowPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonTabHeadersPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonTabsPanel
              System.Windows.Controls.Ribbon.Primitives.RibbonTitlePanel
              System.Windows.Controls.StackPanel
              System.Windows.Controls.VirtualizingPanel
              System.Windows.Controls.WrapPanel


Remarks

Panel contains a collection of UIElement objects, which are in the Children property. Adding a UIElement child to a Panel implicitly adds it to the UIElementCollection for the Panel element.

WPF provides a comprehensive suite of derived Panel implementations, enabling many complex layouts. If you want to implement new layout containers, use the MeasureOverride and ArrangeOverride methods. For a demonstration of how to use these methods, see Create a Custom Content-Wrapping Panel Sample.

Panel elements do not receive mouse or stylus events if a Background is not defined. If you need to handle mouse or stylus events but do not want a background for your Panel, use Transparent.

Panel elements do not receive focus by default. To compel a panel element to receive focus, set the Focusable property to true.

Examples

The following example shows how to use the Children property to add two Button objects to a StackPanel.

<Page  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
  </StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;

namespace SDKSample
{
    public partial class StackpanelExample : Page
    {
        public StackpanelExample()
        {
            // Create two buttons
            Button myButton1 = new Button();
            myButton1.Content = "Button 1";
            Button myButton2 = new Button();
            myButton2.Content = "Button 2";

            // Create a StackPanel
            StackPanel myStackPanel = new StackPanel();

            // Add the buttons to the StackPanel
            myStackPanel.Children.Add(myButton1);
            myStackPanel.Children.Add(myButton2);

            this.Content = myStackPanel;
        }
    }
}




How to: Create a Custom Panel Element


Example

This example shows how to override the default layout behavior of the Panel element and create custom layout elements that are derived from Panel.

The example defines a simple custom Panel element called PlotPanel, which positions child elements according to two hard-coded x- and y-coordinates. In this example, x and y are both set to 50; therefore, all child elements are positioned at that location on the x and y axes.

To implement custom Panel behaviors, the example uses the MeasureOverride and ArrangeOverride methods. Each method returns the Size data that is necessary to position and render child elements.

public class PlotPanel : Panel
{
    // Default public constructor
    public PlotPanel()
        : base()
    {
    }

    // Override the default Measure method of Panel
    protected override Size MeasureOverride(Size availableSize)
    {
        Size panelDesiredSize = new Size();

        // In our example, we just have one child. 
        // Report that our panel requires just the size of its only child.
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            panelDesiredSize = child.DesiredSize;
        }

        return panelDesiredSize ;
    }
    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (UIElement child in InternalChildren)
        {
            double x = 50;
            double y = 50;

            child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
        }
        return finalSize; // Returns the final Arranged size
    }
}




How to: Override the Panel OnRender Method


This example shows how to override the OnRender method of Panel in order to add custom graphical effects to a layout element.

Example

Use the OnRender method in order to add graphical effects to a rendered panel element. For example, you can use this method to add custom border or background effects. A DrawingContext object is passed as an argument, which provides methods for drawing shapes, text, images, or videos. As a result, this method is useful for customization of a panel object.

// Override the OnRender call to add a Background and Border to the OffSetPanel
protected override void OnRender(DrawingContext dc)
{
    SolidColorBrush mySolidColorBrush  = new SolidColorBrush();
    mySolidColorBrush.Color = Colors.LimeGreen;
    Pen myPen = new Pen(Brushes.Blue, 10);
    Rect myRect = new Rect(0, 0, 500, 500);
    dc.DrawRectangle(mySolidColorBrush, myPen, myRect);
}




How to: Set the Height Properties of an Element


Example

This example visually shows the differences in rendering behavior among the four height-related properties in Windows Presentation Foundation (WPF).

The FrameworkElement class exposes four properties that describe the height characteristics of an element. These four properties can conflict, and when they do, the value that takes precedence is determined as follows: the MinHeight value takes precedence over the MaxHeight value, which in turn takes precedence over the Height value. A fourth property, ActualHeight, is read-only, and reports the actual height as determined by interactions with the layout process.

The following Extensible Application Markup Language (XAML) examples draw a Rectangle element (rect1) as a child of Canvas. You can change the height properties of a Rectangle by using a series of ListBox elements that represent the property values of MinHeightMaxHeight, and Height. In this manner, the precedence of each property is visually displayed.

<Canvas Height="200" MinWidth="200" Background="#b0c4de" VerticalAlignment="Top"  HorizontalAlignment="Center" Name="myCanvas" Margin="0,0,0,50">
    <Rectangle HorizontalAlignment="Center" Canvas.Top="50" Canvas.Left="50"  Name="rect1" Fill="#4682b4" Height="100" Width="100"/>
</Canvas>
   <TextBlock Grid.Row="1" Grid.Column="0" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle Height:</TextBlock>
   <ListBox Grid.Column="1" Grid.Row="1" Margin="10,0,0,0" Height="50" Width="50" SelectionChanged="changeHeight">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem>
   </ListBox>

<TextBlock Grid.Row="1" Grid.Column="2" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle MinHeight:</TextBlock>
   <ListBox Grid.Column="3" Grid.Row="1" Margin="10,0,0,0" Height="50" Width="50" SelectionChanged="changeMinHeight">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem>
 </ListBox>      

   <TextBlock Grid.Row="1" Grid.Column="4" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle MaxHeight:</TextBlock>
   <ListBox Grid.Column="5" Grid.Row="1" Margin="10,0,0,0" Height="50" Width="50" SelectionChanged="changeMaxHeight">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem> 
   </ListBox>

The following code-behind examples handle the events that the SelectionChanged event raises. Each handler takes the input from the ListBox, parses the value as a Double, and applies the value to the specified height-related property. The height values are also converted to a string and written to various TextBlock elements (definition of those elements is not shown in the selected XAML).

private void changeHeight(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.Height = sz1;
    rect1.UpdateLayout();
    txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
    txt2.Text= "Height is set to " + rect1.Height;
    txt3.Text= "MinHeight is set to " + rect1.MinHeight;
    txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}
private void changeMinHeight(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.MinHeight = sz1;
    rect1.UpdateLayout();
    txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
    txt2.Text= "Height is set to " + rect1.Height;
    txt3.Text= "MinHeight is set to " + rect1.MinHeight;
    txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}
private void changeMaxHeight(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.MaxHeight = sz1;
    rect1.UpdateLayout();
    txt1.Text= "ActualHeight is set to " + rect1.ActualHeight;
    txt2.Text= "Height is set to " + rect1.Height;
    txt3.Text= "MinHeight is set to " + rect1.MinHeight;
    txt4.Text= "MaxHeight is set to " + rect1.MaxHeight;
}

For the complete sample, see Height Properties Sample.




How to: Set the Width Properties of an Element


Example

This example visually shows the differences in rendering behavior among the four width-related properties in Windows Presentation Foundation (WPF).

The FrameworkElement class exposes four properties that describe the width characteristics of an element. These four properties can conflict, and when they do, the value that takes precedence is determined as follows: the MinWidth value takes precedence over the MaxWidth value, which in turn takes precedence over the Width value. A fourth property, ActualWidth, is read-only, and reports the actual width as determined by interactions with the layout process.

The following Extensible Application Markup Language (XAML) examples draw a Rectangle element (rect1) as a child of Canvas. You can change the width properties of a Rectangle by using a series of ListBox elements that represent the property values of MinWidthMaxWidth, and Width. In this manner, the precedence of each property is visually displayed.

<Canvas Height="200" MinWidth="200" Background="#b0c4de" VerticalAlignment="Top"  HorizontalAlignment="Center" Name="myCanvas">
    <Rectangle HorizontalAlignment="Center" Canvas.Top="50" Canvas.Left="50"  Name="rect1" Fill="#4682b4" Width="100" Height="100"/>
</Canvas>
   <TextBlock Grid.Row="1" Grid.Column="0" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle Width:</TextBlock>
   <ListBox Grid.Column="1" Grid.Row="1" Margin="10,0,0,0" Width="50" Height="50" SelectionChanged="changeWidth">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem>
     <ListBoxItem>225</ListBoxItem>
     <ListBoxItem>250</ListBoxItem>
   </ListBox>

<TextBlock Grid.Row="1" Grid.Column="2" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle MinWidth:</TextBlock>
   <ListBox Grid.Column="3" Grid.Row="1" Margin="10,0,0,0" Width="50" Height="50" SelectionChanged="changeMinWidth">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem>
     <ListBoxItem>225</ListBoxItem>
     <ListBoxItem>250</ListBoxItem>
 </ListBox>      

   <TextBlock Grid.Row="1" Grid.Column="4" Margin="10,0,0,0" TextWrapping="Wrap">Set the Rectangle MaxWidth:</TextBlock>
   <ListBox Grid.Column="5" Grid.Row="1" Margin="10,0,0,0" Width="50" Height="50" SelectionChanged="changeMaxWidth">
     <ListBoxItem>25</ListBoxItem>
     <ListBoxItem>50</ListBoxItem>
     <ListBoxItem>75</ListBoxItem>
     <ListBoxItem>100</ListBoxItem>
     <ListBoxItem>125</ListBoxItem>
     <ListBoxItem>150</ListBoxItem>
     <ListBoxItem>175</ListBoxItem>
     <ListBoxItem>200</ListBoxItem>
     <ListBoxItem>225</ListBoxItem>
     <ListBoxItem>250</ListBoxItem>  
   </ListBox>

The following code-behind examples handle the events that the SelectionChanged event raises. Each custom method takes the input from the ListBox, parses the value as a Double, and applies the value to the specified width-related property. The width values are also converted to a string and written to various TextBlock elements (definition of those elements is not shown in the selected XAML).

private void changeWidth(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.Width = sz1;
    rect1.UpdateLayout();
    txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
    txt2.Text = "Width is set to " + rect1.Width;
    txt3.Text = "MinWidth is set to " + rect1.MinWidth;
    txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}
private void changeMinWidth(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.MinWidth = sz1;
    rect1.UpdateLayout();
    txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
    txt2.Text = "Width is set to " + rect1.Width;
    txt3.Text = "MinWidth is set to " + rect1.MinWidth;
    txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}
private void changeMaxWidth(object sender, SelectionChangedEventArgs args)
{
    ListBoxItem li = ((sender as ListBox).SelectedItem as ListBoxItem);
    Double sz1 = Double.Parse(li.Content.ToString());
    rect1.MaxWidth = sz1;
    rect1.UpdateLayout();
    txt1.Text = "ActualWidth is set to " + rect1.ActualWidth;
    txt2.Text = "Width is set to " + rect1.Width;
    txt3.Text = "MinWidth is set to " + rect1.MinWidth;
    txt4.Text = "MaxWidth is set to " + rect1.MaxWidth;
}

For the complete sample, see Width Properties Comparison Sample.





PasswordBox




PasswordBox Class


Represents a control designed for entering and handling passwords.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.PasswordBox


Remarks

System_CAPS_importantImportant

PasswordBox has built-in handling for the bubbling  MouseUp and MouseDown events. Consequently, custom event handlers that listen for MouseUp or MouseDown events from a PasswordBox will never 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 PasswordBox native handling of these events, and be aware that this has notable effects on the control's UI.

Customizing the PasswordBox Control

To apply the same property settings to multiple PasswordBox 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 PasswordBox, see PasswordBox Syles 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.

System_CAPS_noteNote

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 shows how to specify the handler method for the PasswordChanged event.

<PasswordBox
  Name="pwdBox" 
  MaxLength="64"
  PasswordChar="#"
  PasswordChanged="PasswordChangedHandler"  
/>

The following example shows the corresponding event handler. In this case, the event handler simply increments a counter.

private int pwChanges = 0;

void PasswordChangedHandler(Object sender, RoutedEventArgs args)
{
    // Increment a counter each time the event fires.
    ++pwChanges;
}





Popup




Popup Overview


The Popup control provides a way to display content in a separate window that floats over the current application window relative to a designated element or screen coordinate. This topic introduces the Popup control and provides information about its use.

What Is a Popup?

Popup control displays content in a separate window relative to an element or point on the screen. When the Popup is visible, the IsOpen property is set to true.

System_CAPS_noteNote

Popup does not automatically open when the mouse pointer moves over its parent object. If you want a Popup to automatically open, use the ToolTip or ToolTipService class. For more information, see ToolTip Overview.

Creating a Popup

The following example shows how to define a Popup control that is the child element of a Button control. Because a Button can have only one child element, this example places the text for the Button and the Popup controls in a StackPanel. The content of the Popup appears in a TextBlock control, which displays its text in a separate window that floats over the application window near the related Button control.

<Button HorizontalAlignment="Left" Click="DisplayPopup" 
        Width="150" Margin="20,10,0,0">
  <StackPanel>
    <TextBlock>Display Your Popup Text</TextBlock>
    <Popup Name="myPopup">
      <TextBlock Name="myPopupText" 
                 Background="LightBlue" 
                 Foreground="Blue">
        Popup Text
      </TextBlock>
    </Popup>
  </StackPanel>
</Button>
<Button Name="ButtonForPopup" HorizontalAlignment="Left" 
        Click="CreatePopup"  
        Width="150" Margin="20,10,0,0">
  <StackPanel Name="aStackPanel">
    <TextBlock>Create Popup</TextBlock>
  </StackPanel>
</Button>

Controls That Implement a Popup

You can build Popup controls into other controls. The following controls implement the Popup control for specific uses:

Popup Behavior and Appearance

The Popup control provides functionality that enables you to customize its behavior and appearance. For example, you can set open and close behavior, animation, opacity and bitmap effects, and Popup size and position.

Open and Close Behavior

Popup control displays its content when the IsOpen property is set to true. By default, Popup stays open until the IsOpen property is set to false. However, you can change the default behavior by setting the StaysOpen property to false. When you set this property to false, the Popupcontent window has mouse capture. The Popup loses mouse capture and the window closes when a mouse event occurs outside the Popupwindow.

The Opened and Closed events are raised when the Popup content window is open or closed.

Animation

The Popup control has built-in support for the animations that are typically associated with behaviors like fade-in and slide-in. You can turn on these animations by setting the PopupAnimation property to a PopupAnimation enumeration value. For Popup animations to work correctly, you must set the AllowsTransparency property to true.

You can also apply animations like Storyboard to the Popup control.

Opacity and Bitmap Effects

The Opacity property for a Popup control has no effect on its content. By default, the Popup content window is opaque. To create a transparent Popup, set the AllowsTransparency property to true.

The content of a Popup does not inherit bitmap effects, such as DropShadowBitmapEffect, that you directly set on the Popup control or on any other element in the parent window. For bitmap effects to appear on the content of a Popup, you must set the bitmap effect directly on its content. For example, if the child of a Popup is a StackPanel, set the bitmap effect on the StackPanel.

Popup Size

By default, a Popup is automatically sized to its content. When auto-sizing occurs, some bitmap effects may be hidden because the default size of the screen area that is defined for the Popup content does not provide enough space for the bitmap effects to display.

Popup content can also be obscured when you set a RenderTransform on the content. In this scenario, some content might be hidden if the content of the transformed Popup extends beyond the area of the original Popup. If a bitmap effect or transform requires more space, you can define a margin around the Popup content in order to provide more area for the control.

Defining the Popup Position

You can position a popup by setting the PlacementTargetPlacementRectanglePlacementHorizontalOffset, and VerticalOffsetProperty properties. For more information, see Popup Placement Behavior. When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned.

Customizing Popup Placement

You can customize the placement of a Popup control by specifying a set of coordinates that are relative to the PlacementTarget where you want the Popup to appear.

To customize placement, set the Placement property to Custom. Then define a CustomPopupPlacementCallback delegate that returns a set of possible placement points and primary axes (in order of preference) for the Popup. The point that shows the largest part of the Popup is automatically selected. For an example, see How to: Specify a Custom Popup Position.

Popup and the Visual Tree

Popup control does not have its own visual tree; it instead returns a size of 0 (zero) when the MeasureOverride method for Popup is called. However, when you set the IsOpen property of Popup to true, a new window with its own visual tree is created. The new window contains the Childcontent of Popup. The width and height of the new window cannot be larger than 75 percent of the width or height of the screen.

The Popup control maintains a reference to its Child content as a logical child. When the new window is created, the content of Popup becomes a visual child of the window and remains the logical child of Popup. Conversely, Popup remains the logical parent of its Child content.




Popup Class


Represents a pop-up window that has content.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Primitives.Popup

Remarks

Content Model:  Popup has one content property: Child. A Popup can have a maximum of one child, which can be any UIElement.

The following illustration shows a Popup control that has a Button as its parent.

Popup illustration

You can position a popup by setting the PlacementTargetPlacementRectanglePlacementHorizontalOffset, and VerticalOffsetProperty properties. For more information, see Popup Placement Behavior. When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned.

Popup displays its content in its own window on the screen. A Popup control supports animation when the AllowsTransparency property is set to true and the application is running with full trust. An application that is running with full trust has complete access to system resources and is typically installed on the user's system. For more information, seeSecurity (WPF).

For bitmap and opacity effects to appear on the content of a Popup, you must set the effects directly on the Popup content. The content of a Popupdoes not inherit effects that are set on the Popup control or on any other element that is in the parent window.

Popup is sized to its content by default. When this occurs, applying a RenderTransform or bitmap effects may cause the Popup to be obscured. This occurs because the default size of the content does not provide enough area for the effects to display. If more space is required, you can define a margin around the Popup content to increase the area that is available to the control.

The Parent property must be set on the Popup when used in a XAML browser application (XBAP).

To create a tooltip, use the ToolTip and ToolTipService classes. For more information, see ToolTip Overview.

Examples

The following example shows how to create a Popup control.

<Popup Name="myPopup">
  <TextBlock Name="myPopupText" 
             Background="LightBlue" 
             Foreground="Blue">
    Popup Text
  </TextBlock>
</Popup>
Popup codePopup = new Popup();
TextBlock popupText = new TextBlock();
popupText.Text = "Popup Text";
popupText.Background = Brushes.LightBlue;
popupText.Foreground = Brushes.Blue;
codePopup.Child = popupText;




Popup Placement Behavior


Popup control displays content in a separate window that floats over an application. You can specify the position of a Popup relative to a control, the mouse, or the screen by using the PlacementTargetPlacementPlacementRectangleHorizontalOffset, and VerticalOffset properties. These properties work together to give you flexibility in specifying the position of the Popup.

System_CAPS_noteNote

The ToolTip and ContextMenu classes also define these five properties and behave similarly.

Positioning the Popup

The placement of a Popup can be relative to a UIElement or to the entire screen. The following example creates four Popup controls that are relative to a UIElement—in this case, an image. All of the Popup controls have the PlacementTarget property set to image1, but each Popup has a different value for the placement property.

<Canvas Width="200" Height="150">
  <Image Name="image1"
         Canvas.Left="75" 
         Source="Water_lilies.jpg" Height="200" Width="200"/>
  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
         Placement="Bottom">
    <TextBlock FontSize="14" Background="LightGreen">Placement=Bottom</TextBlock>

  </Popup>
  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
         Placement="Top">
    <TextBlock FontSize="14" Background="LightGreen">Placement=Top</TextBlock>

  </Popup>
  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
         Placement="Left">
    <TextBlock FontSize="14" Background="LightGreen">Placement=Left</TextBlock>

  </Popup>
  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=image1}"
         Placement="Right">
    <TextBlock FontSize="14" Background="LightGreen">Placement=Right</TextBlock>

  </Popup>
</Canvas>

The following illustration shows the image and the Popup controls

Image with four popup controls

Image with four Popups

This simple example demonstrates how to set the PlacementTarget and Placement properties, but by using the PlacementRectangleHorizontalOffset, and VerticalOffset properties, you have even more control over where the Popup is positioned.

Definitions of Terms: The Anatomy of a Popup

The following terms are useful in understanding how the PlacementTargetPlacementPlacementRectangleHorizontalOffset, and VerticalOffsetproperties relate to each other and the Popup:

  • Target object

  • Target area

  • Target origin

  • Popup alignment point

These terms provide a convenient way to refer to various aspects of the Popup and the control that it is associated with.

Target Object

The target object is the element that the Popup is associated with. If the PlacementTarget property is set, it specifies the target object. If PlacementTarget is not set, and the Popup has a parent, the parent is the target object. If there is no PlacementTarget value and no parent, there is no target object, and the Popup is positioned relative to the screen.

The following example creates a Popup that is the child of a Canvas. The example does not set the PlacementTarget property on the Popup. The default value for Placement is PlacementMode.Bottom, so the Popup appears below the Canvas.

<Canvas Margin="5" Background="Red" Width="200" Height="150" >

  <Ellipse Canvas.Top="60" Canvas.Left="50"
           Height="85" Width="60" 
           Fill="Black"/>

  <Popup IsOpen="True" >
    <TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
  </Popup>
</Canvas>

The following illustration shows that the Popup is positioned relative to the Canvas.

Popup control with no PlacementTarget

Popup with no PlacementTarget

The following example creates a Popup that is the child of a Canvas, but this time the PlacementTarget is set to ellipse1, so the popup appears below the Ellipse.

<Canvas Margin="5" Background="Red" Width="200" Height="150" >

  <Ellipse Name="ellipse1"
           Canvas.Top="60" Canvas.Left="50"
           Height="85" Width="60" 
           Fill="Black"/>

  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=ellipse1}">
    <TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
  </Popup>
</Canvas>

The following illustration shows that the Popup is positioned relative to the Ellipse.

Popup positioned relative to an ellipse

Popup with PlacementTarget

System_CAPS_noteNote

For ToolTip, the default value of Placement is Mouse. For ContextMenu, the default value of Placement is MousePoint. These values are explained later, in "How the Properties Work Together."

Target Area

The target area is the area on the screen that the Popup is relative to. In the previous examples, the Popup is aligned with the bounds of the target object, but in some cases, the Popup is aligned to other bounds, even if the Popup has a target object. If the PlacementRectangle property is set, the target area is different than the bounds of the target object.

The following example creates two Canvas objects, each one containing a Rectangle and a Popup. In both cases, the target object for the Popup is the Canvas. The Popup in the first Canvas has the PlacementRectangle set, with its XYWidth, and Height properties set to 50, 50, 50, and 100, respectively. The Popup in the second Canvas does not have the PlacementRectangle set. As a result, the first Popup is positioned below the PlacementRectangle and the second Popup is positioned below the Canvas. Each Canvas also contains a Rectangle that has the same bounds as the PlacementRectangle for the first Popup. Note that the PlacementRectangle does not create a visible element in the application; the example creates a Rectangle to represent the PlacementRectangle.

<StackPanel Orientation="Horizontal" Margin="50,50,0,0">

  <Canvas Width="200" Height="200" Background="Red">
    <Rectangle Canvas.Top="50" Canvas.Left="50" 
               Width="50" Height="100"
               Stroke="White" StrokeThickness="3"/>
    <Popup IsOpen="True" PlacementRectangle="50,50,50,100">
      <TextBlock FontSize="14" Background="Yellow"
                 Width="140" TextWrapping="Wrap">
        This is a popup with a PlacementRectangle.
      </TextBlock>
    </Popup>
  </Canvas>

  <Canvas Width="200" Height="200" Background="Red" Margin="30,0,0,0">
    <Rectangle Canvas.Top="50" Canvas.Left="50" 
               Width="50" Height="100"
               Stroke="White" StrokeThickness="3"/>
    <Popup IsOpen="True">
      <TextBlock FontSize="14" Background="Yellow"
                 Width="140" TextWrapping="Wrap">
        This is a popup without a PlacementRectangle.
      </TextBlock>
    </Popup>
  </Canvas>

</StackPanel>

The following illustration shows the result of the preceding example.

Popup with and without PlacementRectangle

Popup with and without PlacementRectangle

Target Origin and Popup Alignment Point

The target origin and popup alignment point are reference points on the target area and popup, respectively, that are used for positioning. You can use the HorizontalOffset and VerticalOffset properties to offset the popup from the target area. The HorizontalOffset and VerticalOffset are relative to the target origin and the popup alignment point. The value of the Placement property determines where the target origin and popup alignment point are located.

The following example creates a Popup and sets the HorizontalOffset and VerticalOffset properties to 20. The Placement property is set to Bottom(the default), so the target origin is the bottom-left corner of the target area and the popup alignment point is the top-left corner of the Popup.

<Canvas Width="200" Height="200" Background="Yellow" Margin="20">
  <Popup IsOpen="True" Placement="Bottom"
         HorizontalOffset="20" VerticalOffset="20">
    <TextBlock FontSize="14" Background="#42F3FD">
      This is a popup.
    </TextBlock>
  </Popup>
</Canvas>

The following illustration shows the result of the preceding example.

Popup placement with target origin alignment point

Popup with HorizontalOffset and VerticalOffset

How the Properties Work Together

The values of PlacementTargetPlacementRectangle, and Placement need to be considered together to figure out the correct target area, target origin, and popup alignment point. For example, if the value of Placement is Mouse, there is no target object, the PlacementRectangle is ignored, and the target area is the bounds of the mouse pointer. On the other hand, if Placement is Bottom, the PlacementTarget or parent determines the target object and PlacementRectangle determines the target area.

The following table describes the target object, target area, target origin, and popup alignment point and indicates whether PlacementTarget and PlacementRectangle are used for each PlacementMode enumeration value.

PlacementMode

Target object

Target area

Target origin

Popup alignment point

Absolute

Not applicable. PlacementTarget is ignored.

The screen, or PlacementRectangle if it is set. The PlacementRectangle is relative to the screen.

The top-left corner of the target area.

The top-left corner of the Popup.

AbsolutePoint

Not applicable. PlacementTarget is ignored.

The screen, or PlacementRectangle if it is set. The PlacementRectangle is relative to the screen.

The top-left corner of the target area.

The top-left corner of the Popup.

Bottom

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The bottom-left corner of the target area.

The top-left corner of the Popup.

Center

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The center of the target area.

The center of the Popup.

Custom

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

Defined by the CustomPopupPlacementCallback.

Defined by the CustomPopupPlacementCallback.

Left

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The top-left corner of the target area.

The top-right corner of the Popup.

Mouse

Not applicable. PlacementTarget is ignored.

The bounds of the mouse pointer. PlacementRectangle is ignored.

The bottom-left corner of the target area.

The top-left corner of the Popup.

MousePoint

Not applicable. PlacementTarget is ignored.

The bounds of the mouse pointer. PlacementRectangle is ignored.

The top-left corner of the target area.

The top-left corner of the Popup.

Relative

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The top-left corner of the target area.

The top-left corner of the Popup.

RelativePoint

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The top-left corner of the target area.

The top-left corner of the Popup.

Right

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The top-right corner of the target area.

The top-left corner of the Popup.

Top

PlacementTarget or parent.

The target object, or PlacementRectangle if it is set. The PlacementRectangle is relative to the target object.

The top-left corner of the target area.

The bottom-left corner of the Popup.

The following illustrations show the Popup, target area, target origin, and popup alignment point for each PlacementMode value. In each figure, the target area is yellow, and the Popup is blue.

Popup with Absolute or AbsolutePoint placement

Placement is Absolute or AbsolutePoint

Popup with Bottom placement

Placement is Bottom

Popup with Center placement

Placement is Center

Popup with Left placement

Placement is Left

Popup with Mouse placement

Placement is Mouse

Popup with MousePoint placement

Placement is MousePoint

Popup with Relative or RelativePoint placement

Placement is Relative or RelativePoint

Popup with Right placement

Placement is Right

Popup with Top placement

Placement is Top

When the Popup Encounters the Edge of the Screen

For security reasons, a Popup cannot be hidden by the edge of a screen. One of the following three things happens when the Popup encounters a screen edge:

  • The popup realigns itself along the screen edge that would obscure the Popup.

  • The popup uses a different popup alignment point.

  • The popup uses a different target origin and popup alignment point.

These options are described further later in this section.

The behavior of the Popup when it encounters a screen edge depends on the value of the Placement property and which screen edge the popup encounters. The following table summarizes the behavior when the Popup encounters a screen edge for each PlacementMode value.

PlacementMode

Top edge

Bottom edge

Left edge

Right edge

Absolute

Aligns to the top edge.

Aligns to the bottom edge.

Aligns to the left edge.

Aligns to the right edge.

AbsolutePoint

Aligns to the top edge.

The popup alignment point changes to the bottom-left corner of the Popup.

Aligns to the left edge.

The popup alignment point changes to the top-right corner of the Popup.

Bottom

Aligns to the top edge.

The target origin changes to the top-left corner of the target area and the popup alignment point changes to the bottom-left corner of the Popup.

Aligns to the left edge.

Aligns to the right edge.

Center

Aligns to the top edge.

Aligns to the bottom edge.

Aligns to the left edge.

Aligns to the right edge.

Left

Aligns to the top edge.

Aligns to the bottom edge.

The target origin changes to the top-right corner of the target area and the popup alignment point changes to the top-left corner of the Popup.

Aligns to the right edge.

Mouse

Aligns to the top edge.

The target origin changes to the top-left corner of the target area (the bounds of the mouse pointer) and the popup alignment point changes to the bottom-left corner of the Popup.

Aligns to the left edge.

Aligns to the right edge.

MousePoint

Aligns to the top edge.

The popup alignment point changes to the bottom-left corner of the Popup.

Aligns to the left edge.

The popup alignment point changes to the top-right corner of the popup.

Relative

Aligns to the top edge.

Aligns to the bottom edge.

Aligns to the left edge.

Aligns to the right edge.

RelativePoint

Aligns to the top edge.

The popup alignment point changes to the bottom-left corner of the Popup.

Aligns to the left edge.

The popup alignment point changes to the top-right corner of the popup.

Right

Aligns to the top edge.

Aligns to the bottom edge.

Aligns to the left edge.

The target origin changes to the top-left corner of the target area and the popup alignment point changes to the top-right corner of the Popup.

Top

The target origin changes to the bottom-left corner of the target area and the popup alignment point changes to the top-left corner of the Popup. In effect, this is the same as when Placement is Bottom.

Aligns to the bottom edge.

Aligns to the left edge.

Aligns to the right edge.

Aligning to the Screen Edge

Popup can align to the edge of the screen by repositioning itself so the entire Popup is visible on the screen. When this occurs, the distance between the target origin and popup alignment point might differ from the values of HorizontalOffset and VerticalOffset. When Placement is AbsoluteCenter, or Relative, the Popup aligns itself to every screen edge. For example, assume that a Popup has Placement set to Relative and VerticalOffset set to 100. If the bottom edge of the screen hides all or part of the Popup, the Popup repositions itself along the bottom edge of the screen and the vertical distance between the target origin and popup alignment point is less than 100. The following illustration demonstrates this.

Popup that aligns to edge of screen

Popup aligns to the edge of the screen

Changing the Popup Alignment Point

If Placement is AbsolutePointRelativePoint, or MousePoint, the popup alignment point changes when the popup encounters the bottom or right screen edge.

The following illustration demonstrates that when the bottom screen edge hides all or part of the Popup, the popup alignment point is the bottom-left corner of the Popup.

New alignment point due to bottom screen edge

Popup encounters bottom edge of the screen and changes the popup alignment point

The following illustration demonstrates that when the Popup is hidden by the right screen edge, the popup alignment point is the top-right corner of the Popup.

New popup alignment point due to screen edge

Popup encounters right edge of the screen and changes the popup alignment point

If the Popup encounters the bottom and right screen edges, the popup alignment point is the bottom-right corner of the Popup.

Changing the Target Origin and Popup Alignment Point

When Placement is BottomLeftMouseRight, or Top, the target origin and popup alignment point change if a certain screen edge is encountered. The screen edge that causes the position to change depends on the PlacementMode value.

The following illustration demonstrates that when Placement is Bottom and the Popup encounters the bottom screen edge, the target origin is the top-left corner of the target area and the popup alignment point is the bottom-left corner of the Popup.

New alignment point due to bottom screen edge

Placement is Bottom and the popup encounters the bottom edge of the screen

The following illustration demonstrates that when Placement is Left and the Popup encounters the left screen edge, the target origin is the top-right corner of the target area and the popup alignment point is the top-left corner of the Popup.

New alignment point due to left screen edge

Placement is Left and the popup encounters the left edge of the screen

The following illustration demonstrates that when Placement is Right and the Popup encounters the right screen edge, the target origin is the top-left corner of the target area and the popup alignment point is the top-right corner of the Popup.

New alignment point due to right screen edge

Placement is Right and the popup encounters the right edge of the screen

The following illustration demonstrates that when Placement is Top and the Popup encounters the top screen edge, the target origin is the bottom-left corner of the target area and the popup alignment point is the top-left corner of the Popup.

New alignment point due to top screen edge

Placement is Top and the popup encounters the top edge of the screen

The following illustration demonstrates that when Placement is Mouse and the Popup encounters the bottom screen edge, the target origin is the top-left corner of the target area (the bounds of the mouse pointer) and the popup alignment point is the bottom-left corner of the Popup.

new alignment point due to mouse near screen edge

Placement is Mouse and the popup encounters the bottom edge of the screen

You can customize the target origin and popup alignment point by setting the Placement property to Custom. Then define a CustomPopupPlacementCallback delegate that returns a set of possible placement points and primary axes (in order of preference) for the Popup. The point that shows the largest portion of the Popup is selected. The position of the Popup is automatically adjusted if the Popup is hidden by the edge of the screen. For an example, see How to: Specify a Custom Popup Position.




How to: Animate a Popup


This example shows two ways to animate a Popup control.

Example

The following example sets the PopupAnimation property to a value of Slide, which causes the Popup to "slide-in" when it appears.

In order to rotate the Popup, this example assigns a RotateTransform to the RenderTransform property on the Canvas, which is the child element of the Popup.

For the transform to work correctly, the example must set the AllowsTransparency property to true. In addition, the Margin on the Canvas content must specify enough space for the Popup to rotate.

<Popup IsOpen="{Binding ElementName=myCheckBox,Path=IsChecked}" 
       PlacementTarget="{Binding ElementName=myCheckBox}"            
       AllowsTransparency="True"
       PopupAnimation="Slide"
       HorizontalOffset="50"
       VerticalOffset="50"
       >
  <!--The Margin set on the Canvas provides the additional 
      area around the Popup so that the Popup is visible when 
      it rotates.-->
  <Canvas Width="100" Height="100" Background="DarkBlue"
          Margin="150">
    <Canvas.RenderTransform>
      <RotateTransform x:Name="theTransform" />
    </Canvas.RenderTransform>
    <TextBlock TextWrapping="Wrap" Foreground="White">
      Rotating Popup
    </TextBlock>
  </Canvas>
</Popup>

The following example shows how a Click event, which occurs when a Button is clicked, triggers the Storyboard that starts the animation.

<Button HorizontalAlignment="Left" Width="200" Margin="20,10,0,0">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation 
            Storyboard.TargetName="theTransform"
            Storyboard.TargetProperty="(RotateTransform.Angle)" 
            From="0" To="360" Duration="0:0:5" AutoReverse="True"/>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
  Click to see the Popup animate
</Button>




How to: Specify a Custom Popup Position


This example shows how to specify a custom position for a Popup control when the Placement property is set to Custom.

Example

When the Placement property is set to Custom, the Popup calls a defined instance of the CustomPopupPlacementCallback delegate. This delegate returns a set of possible points that are relative to the top left corner of the target area and the top left corner of the Popup. The Popup placement occurs at the point that provides the best visibility.

The following example shows how to define the position of a Popup by setting the Placement property to Custom. It also shows how to create and assign a CustomPopupPlacementCallback delegate in order to position the Popup. The callback delegate returns two CustomPopupPlacement objects. If the Popup is hidden by a screen edge at the first position, the Popup is placed at the second position.

 <Popup Name="popup1"  
        PlacementTarget ="{Binding ElementName=myButton}" 
        Placement="Custom">
  <TextBlock Height="60" Width="200" 
             Background="LightGray"
             TextWrapping="Wrap">Popup positioned by using
  CustomPopupPlacement callback delegate</TextBlock>
</Popup>
public CustomPopupPlacement[] placePopup(Size popupSize,
                                           Size targetSize,
                                           Point offset)
{
    CustomPopupPlacement placement1 =
       new CustomPopupPlacement(new Point(-50, 100), PopupPrimaryAxis.Vertical);

    CustomPopupPlacement placement2 =
        new CustomPopupPlacement(new Point(10, 20), PopupPrimaryAxis.Horizontal);

    CustomPopupPlacement[] ttplaces =
            new CustomPopupPlacement[] { placement1, placement2 };
    return ttplaces;
}
popup1.CustomPopupPlacementCallback =
    new CustomPopupPlacementCallback(placePopup); 

For the complete sample, see Popup Placement Sample.





ProgressBar




ProgressBar Class


Indicates the progress of an operation.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.RangeBase
                System.Windows.Controls.ProgressBar


Remarks

ProgressBar control consists of a window that is filled, by default from left to right, as an operation progresses. The control has a range and a current position.

ProgressBar overrides the metadata of the Maximum property and sets its default to 100. ProgressBar overrides the metadata of the Focusableproperty and sets its default to false. For more information, see Dependency Properties Overview.

Customizing the ProgressBar Control

To apply the same property settings to multiple ProgressBar 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 ProgressBar, see ProgressBar 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in ProgressBar 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 creates a ProgressBar and uses an animation to simulate the progress of an operation.

<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>
ProgressBar progbar = new ProgressBar();
progbar.IsIndeterminate = false;
progbar.Orientation = Orientation.Horizontal;
progbar.Width = 150;
progbar.Height = 15;
Duration duration = new Duration(TimeSpan.FromSeconds(10));
DoubleAnimation doubleanimation = new DoubleAnimation(100.0, duration);
progbar.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);






PrintDialog




PrintDialog Class


Invokes a standard Microsoft Windows print dialog box that configures a PrintTicket and PrintQueue according to user input and then prints a document.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Controls.PrintDialog


Remarks

A user can use the Print dialog box to select a printer, configure it, and perform a print job.

Strictly speaking, you can use the PrintDocument method without ever opening the dialog. In that sense, the control can be used as an unseen printing component. But for performance reasons, it would be better to use either the AddJob method or one of the many Write and WriteAsyncmethods of the XpsDocumentWriter. For more about this, see How to: Programmatically Print XPS Files.

Do not confuse this class, System.Windows.Controls.PrintDialog, with System.Windows.Forms.PrintDialog. The latter is used with Windows Forms applications. System.Windows.Controls.PrintDialog is used with Windows Presentation Foundation (WPF) applications. 

Examples

The following example shows how to create an instance of and display a simple PrintDialog by using Extensible Application Markup Language (XAML) markup and code.

<Button Width="200" Click="InvokePrint">Invoke PrintDialog</Button>

...

private void InvokePrint(object sender, RoutedEventArgs e)
    {
        // Create the print dialog object and set options
        PrintDialog pDialog = new PrintDialog();
        pDialog.PageRangeSelection = PageRangeSelection.AllPages;
        pDialog.UserPageRangeEnabled = true;

        // Display the dialog. This returns true if the user presses the Print button.
        Nullable<Boolean> print = pDialog.ShowDialog();
        if (print == true)
        {
            XpsDocument xpsDocument = new XpsDocument("C:\\FixedDocumentSequence.xps", FileAccess.ReadWrite);
            FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
            pDialog.PrintDocument(fixedDocSeq.DocumentPaginator, "Test print job");
        }
    }




PrintTicket Class


Defines the settings of a print job.

Namespace:   System.Printing
Assembly:  ReachFramework (in ReachFramework.dll)

Inheritance Hierarchy

System.Object
  System.Printing.PrintTicket


Remarks

PrintTicket object is an easy-to-work-with representation of a certain type of XML document called a PrintTicket document. The latter is a set of instructions telling a printer how to set its various features (such as duplexing, collating, and stapling). For example, to instruct the printer to turn on its stapler and staple print jobs in the upper left corner, the document would have a <JobStapleAllDocuments … > element that specifies StapleTopLeft. The element is, in turn, represented by the Stapling property of the PrintTicket object. The PrintTicket document must conform to the Print Schema.

The PrintTicket class enables your application to configure the printer's features without having to engage in any direct writing of XML Streamobjects.

All of the most popular features of home and business file and photo printers are represented by properties of PrintTicket the class. But the Print Schema defines many more, less common, features and it can be extended to handle features of specialty printing devices. So, although the PrintTicket and PrintCapabilities classes cannot be inherited, you can extend the Print Schema to recognize print device features that are not accounted for in the PrintTicket or PrintCapabilities classes. For more information see NOTINBUILD: How to: Extend the Print Schema and Create New Print System Classes.

Note   When the PrintTicket object is created with the constructor that takes a PrintTicket document (as a Stream) parameter, that entire document is stored in a non-public field in the object, including the XML elements within it that express less common features that are not represented by any of the public properties of the PrintTicket class. In fact, if the driver that produced the PrintTicket document is using a private extension of the Print Schema, that privately defined markup is also stored as part of the non-public PrintTicket document.

System_CAPS_cautionCaution

Classes within the System.Printing namespace are not supported for use within a Windows service or ASP.NET application or service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.

If you want to print from a Windows Forms application, see the System.Drawing.Printing namespace.

Examples

The following example shows how to determine the capabilities of a specific printer and how to configure a print job to take advantage of them.

// ---------------------- GetPrintTicketFromPrinter ----------------------- /// <summary> /// Returns a PrintTicket based on the current default printer.</summary> /// <returns> /// A PrintTicket for the current local default printer.</returns> private PrintTicket GetPrintTicketFromPrinter() { PrintQueue printQueue = null; LocalPrintServer localPrintServer = new LocalPrintServer(); // Retrieving collection of local printer on user machine PrintQueueCollection localPrinterCollection = localPrintServer.GetPrintQueues(); System.Collections.IEnumerator localPrinterEnumerator = localPrinterCollection.GetEnumerator(); if (localPrinterEnumerator.MoveNext()) { // Get PrintQueue from first available printer printQueue = (PrintQueue)localPrinterEnumerator.Current; } else { // No printer exist, return null PrintTicket return null; } // Get default PrintTicket from printer PrintTicket printTicket = printQueue.DefaultPrintTicket; PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities(); // Modify PrintTicket if (printCapabilites.CollationCapability.Contains(Collation.Collated)) { printTicket.Collation = Collation.Collated; } if ( printCapabilites.DuplexingCapability.Contains( Duplexing.TwoSidedLongEdge) ) { printTicket.Duplexing = Duplexing.TwoSidedLongEdge; } if (printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft)) { printTicket.Stapling = Stapling.StapleDualLeft; } return printTicket; }// end:GetPrintTicketFromPrinter()




PrintQueue Class

Manages printers and print jobs.

Namespace:   System.Printing
Assembly:  System.Printing (in System.Printing.dll)


Remarks

Some properties of the PrintQueue object represent characteristics of the print queue utility that runs on the computer, but others represent features or states of the printer itself. For example, NumberOfJobs is a characteristic of the print queue, but Location is a property of the printer. Many of the properties of the printer, such as whether it needs user attention, need to be passed, by means of the Refresh method, from the printer itself to the PrintQueue object. This should be done before the corresponding property (NeedUserIntervention) is read by your program. Similarly, when your program changes the values of one or more properties of a PrintQueue object, the change must be written to the actual print queue utility on the computer. Do this with the Commit method.

System_CAPS_cautionCaution

Classes within the System.Printing namespace are not supported for use within a Windows service or ASP.NET application or service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.

If you want to print from a Windows Forms application, see the System.Drawing.Printing namespace.





Printing Overview


https://msdn.microsoft.com/en-us/library/ms742418(v=vs.110).aspx


With Microsoft .NET Framework, application developers using Windows Presentation Foundation (WPF) have a rich new set of printing and print system management APIs. With Windows Vista, some of these print system enhancements are also available to developers creating Windows Forms applications and developers using unmanaged code. At the core of this new functionality is the new XML Paper Specification (XPS) file format and the XPS print path.

This topic contains the following sections.

About XPS

XPS is an electronic document format, a spool file format and a page description language. It is an open document format that uses XML, Open Packaging Conventions (OPC), and other industry standards to create cross-platform documents. XPS simplifies the process by which digital documents are created, shared, printed, viewed, and archived. For additional information on XPS, see the XPS Web Site.

Several techniques for printing XPS based content using WPF are demonstrated in How to: Programmatically Print XPS Files. You may find it useful to reference these samples during review of content contained in this topic. (Unmanaged code developers should see the help for the Microsoft XPS Document Converter printer escape. Windows Forms developers must use the API in the System.Drawing.Printing namespace which does not support the full XPS print path, but does support a hybrid GDI-to-XPS print path. See Print Path Architecture below.)

XPS Print Path

The XML Paper Specification (XPS) print path is a new Windows feature that redefines how printing is handled in Windows applications. Because XPS can replace a document presentation language (such as RTF), a print spooler format (such as WMF), and a page description language (such as PCL or Postscript); the new print path maintains the XPS format from application publication to the final processing in the print driver or device.

The XPS print path is built upon the XPS printer driver model (XPSDrv), which provides several benefits for developers such as "what you see is what you get" (WYSIWYG) printing, improved color support, and significantly improved print performance. (For more on XPSDrv, see the Windows Driver Development Kit.)

The operation of the print spooler for XPS documents is essentially the same as in previous versions of Windows. However, it has been enhanced to support the XPS print path in addition to the existing GDI print path. The new print path natively consumes an XPS spool file. While user-mode printer drivers written for previous versions of Windows will continue to work, an XPS printer driver (XPSDrv) is required in order to use the XPS print path.

The benefits of the XPS print path are significant, and include:

  • WYSIWYG print support

  • Native support of advanced color profiles, which include 32 bits per channel (bpc), CMYK, named-colors, n-inks, and native support of transparency and gradients.

  • Improved print performance for both .NET Framework and Win32 based applications.

  • Industry standard XPS format.

For basic print scenarios, a simple and intuitive API is available with a single entry point for user interface, configuration and job submission. For advanced scenarios, an additional support is added for user interface (UI) customization (or no UI at all), synchronous or asynchronous printing, and batch printing capabilities. Both options provide print support in full or partial trust mode.

XPS was designed with extensibility in mind. By using the extensibility framework, features and capabilities can be added to XPS in a modular manner. Extensibility features include:

  • Print Schema. The public schema is updated regularly and enables rapid extension of device capabilities. (See PrintTicket and PrintCapabilities below.)

  • Extensible Filter Pipeline. The XPS printer driver (XPSDrv) filter pipeline was designed to enable both direct and scalable printing of XPS documents. (Lookup "XPSDrv" in the Windows Driver Development Kit.)

Print Path Architecture

While both Win32 and .NET Framework applications support XPS, Win32 and Windows Forms applications use a GDI to XPS conversion in order to create XPS formatted content for the XPS printer driver (XPSDrv). These applications are not required to use the XPS print path, and can continue to use Enhanced Metafile (EMF) based printing. However, most XPS features and enhancements are only available to applications that target the XPS print path. 

To enable the use of XPSDrv-based printers by Win32 and Windows Forms applications, the XPS printer driver (XPSDrv) supports conversion of GDI to XPS format. The XPSDrv model also provides a converter for XPS to GDI format so that Win32 applications can print XPS Documents. For WPF applications, conversion of XPS to GDI format is done automatically by the Write and WriteAsync methods of the XpsDocumentWriter class whenever the target print queue of the write operation does not have an XPSDrv driver. (Windows Forms applications cannot print XPS Documents.)

The following illustration depicts the print subsystem and defines the portions provided by Microsoft, and the portions defined by software and hardware vendors.

The XPS Print System

Basic XPS Printing

WPF defines both a basic and advanced API. For those applications that do not require extensive print customization or access to the complete XPS feature set, basic print support is available. Basic print support is exposed through a print dialog control that requires minimal configuration and features a familiar UI. Many XPS features are available using this simplified print model.

PrintDialog

The System.Windows.Controls.PrintDialog control provides a single entry point for UI, configuration, and XPS job submission. For information about how to instantiate and use the control, see How to: Invoke a Print Dialog.

Advanced XPS Printing

To access the complete set of XPS features, the advanced print API must be used. Several relevant API are described in greater detail below. For a complete list of XPS print path APIs, see the System.Windows.Xps and System.Printing namespace references.

PrintTicket and PrintCapabilities

The PrintTicket and PrintCapabilities classes are the foundation of the advanced XPS features. Both types of objects are XML formatted structures of print-oriented features such as collation, two-sided printing, stapling, etc. These structures are defined by the print schema. A PrintTicket instructs a printer how to process a print job. The PrintCapabilities class defines the capabilities of a printer. By querying the capabilities of a printer, a PrintTicket can be created that takes full advantage of a printer's supported features. Similarly, unsupported features can be avoided.

The following example demonstrates how to query the PrintCapabilities of a printer and create a PrintTicket using code.

// ---------------------- GetPrintTicketFromPrinter -----------------------
/// <summary>
///   Returns a PrintTicket based on the current default printer.</summary>
/// <returns>
///   A PrintTicket for the current local default printer.</returns>
private PrintTicket GetPrintTicketFromPrinter()
{
    PrintQueue printQueue = null;

    LocalPrintServer localPrintServer = new LocalPrintServer();

    // Retrieving collection of local printer on user machine
    PrintQueueCollection localPrinterCollection =
        localPrintServer.GetPrintQueues();

    System.Collections.IEnumerator localPrinterEnumerator =
        localPrinterCollection.GetEnumerator();

    if (localPrinterEnumerator.MoveNext())
    {
        // Get PrintQueue from first available printer
        printQueue = (PrintQueue)localPrinterEnumerator.Current;
    }
    else
    {
        // No printer exist, return null PrintTicket
        return null;
    }

    // Get default PrintTicket from printer
    PrintTicket printTicket = printQueue.DefaultPrintTicket;

    PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();

    // Modify PrintTicket
    if (printCapabilites.CollationCapability.Contains(Collation.Collated))
    {
        printTicket.Collation = Collation.Collated;
    }

    if ( printCapabilites.DuplexingCapability.Contains(
            Duplexing.TwoSidedLongEdge) )
    {
        printTicket.Duplexing = Duplexing.TwoSidedLongEdge;
    }

    if (printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft))
    {
        printTicket.Stapling = Stapling.StapleDualLeft;
    }

    return printTicket;
}// end:GetPrintTicketFromPrinter()

PrintServer and PrintQueue

The PrintServer class represents a network print server and the PrintQueue class represents a printer and the output job queue associated with it. Together, these APIs allow advanced management of a server's print jobs. A PrintServer, or one of its derived classes, is used to manage a PrintQueue. The AddJob method is used to insert a new print job into the queue.

The following example demonstrates how to create a LocalPrintServer and access its default PrintQueue by using code.

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()

XpsDocumentWriter

An XpsDocumentWriter, with its many the Write and WriteAsync methods, is used to write XPS documents to a PrintQueue. For example, the Write(FixedPage, PrintTicket) method is used to output an XPS document and PrintTicket synchronously. The WriteAsync(FixedDocument, PrintTicket) method is used to output an XPS document and PrintTicket asynchronously.

The following example demonstrates how to create an XpsDocumentWriter using code.

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()

The AddJob methods also provide ways to print. See How to: Programmatically Print XPS Files. for details.

GDI Print Path

While WPF applications natively support the XPS print path, Win32 and Windows Forms applications can also take advantage of some XPS features. The XPS printer driver (XPSDrv) can convert GDI based output to XPS format. For advanced scenarios, custom conversion of content is supported using the Microsoft XPS Document Converter printer escape. Similarly, WPF applications can also output to the GDI print path by calling one of the Write or WriteAsync methods of the XpsDocumentWriter class and designating a non-XpsDrv printer as the target print queue.

For applications that do not require XPS functionality or support, the current GDI print path remains unchanged.

XPSDrv Driver Model

The XPS print path improves spooler efficiency by using XPS as the native print spool format when printing to an XPS -enabled printer or driver. The simplified spooling process eliminates the need to generate an intermediate spool file, such as an EMF data file, before the document is spooled. Through smaller spool file sizes, the XPS print path can reduce network traffic and improve print performance.

EMF is a closed format that represents application output as a series of calls into GDI for rendering services. Unlike EMF, the XPS spool format represents the actual document without requiring further interpretation when output to an XPS-based printer driver (XPSDrv). The drivers can operate directly on the data in the format. This capability eliminates the data and color space conversions required when you use EMF files and GDI-based print drivers.

Spool file sizes are usually reduced when you use XPS Documents that target an XPS printer driver (XPSDrv) compared with their EMF equivalents; however, there are exceptions:

  • A vector graphic that is very complex, multi-layered, or inefficiently written can be larger than a bitmapped version of the same graphic.

  • For screen display purposes, XPS files embed device fonts as well as computer-based fonts; whereas GDI spool files do not embed device fonts. But both kinds of fonts are subsetted (see below) and printer drivers can remove the device fonts before transmitting the file to the printer.

Spool size reduction is performed through several mechanisms:

  • Font subsetting. Only characters used within the actual document are stored in the XPS file.

  • Advanced Graphics Support. Native support for transparency and gradient primitives avoids rasterization of content in the XPS Document.

  • Identification of common resources. Resources that are used multiple times (such as an image that represents a corporate logo) are treated as shared resources and are loaded only once.

  • ZIP compression. All XPS documents use ZIP compression.




Invoke a Print Dialog


Clone a Printer


Diagnose Problematic Print Job


Discover Whether a Print Job Can Be Printed At This Time of Day


Enumerate a Subset of Print Queues


Get Print System Object Properties Without Reflection


Programmatically Print XPS Files


Remotely Survey the Status of Printers


Validate and Merge PrintTickets





RadioButton




RadioButton Class


Represents a button that can be selected, but not cleared, by a user. The IsChecked property of a RadioButton can be set by clicking it, but it can only be cleared programmatically.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.Primitives.ButtonBase
                  System.Windows.Controls.Primitives.ToggleButton
                    System.Windows.Controls.RadioButton
                      System.Windows.Controls.Ribbon.RibbonRadioButton


Remarks

RadioButton 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.

RadioButton has two states: true or false. The RadioButton is a control that is usually used as an item in a group of RadioButton controls. However, it is possible to create a single RadioButton. Whether a RadioButton is selected is determined by the state of its IsChecked property.

When a RadioButton is selected, it cannot be cleared by clicking it. When RadioButton elements are grouped, the buttons are mutually exclusive. A user can select only one item at a time within a RadioButton group. You can group RadioButton controls by placing them inside a parent or by setting the GroupName property on each RadioButton.

Customizing the RadioButton Control

To apply the same property settings to multiple RadioButton 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 RadioButton, see RadioButton 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in RadioButton 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 RadioButton controls, group them inside a container, and handle the Checked event.

<StackPanel>      
    <RadioButton Name="rb1" Checked="WriteText2">Yes</RadioButton>
    <RadioButton Name="rb2" Checked="WriteText2">No</RadioButton>
    <RadioButton Name="rb3" Checked="WriteText2">No opinion</RadioButton>
</StackPanel>
void WriteText2(object sender, RoutedEventArgs e)
{
    RadioButton li = (sender as RadioButton);
    txtb.Text = "You clicked " + li.Content.ToString() + ".";
}

The following code sample creates two separate RadioButton groups: colorgrp and numgrp. The user can choose one RadioButton in each group.

<StackPanel>
    <RadioButton GroupName="colorgrp">Red</RadioButton>
    <RadioButton GroupName="colorgrp">Blue</RadioButton>
    <RadioButton GroupName="numgrp">1</RadioButton>
    <RadioButton GroupName="numgrp">2</RadioButton>
</StackPanel>





RepeatButton




RepeatButton Class


Represents a control that raises its Click event repeatedly from the time it is pressed until it is released.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.Primitives.ButtonBase
                  System.Windows.Controls.Primitives.RepeatButton


Remarks

RepeatButton 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.

The RepeatButton class represents a control that is similar to a Button. However, repeat buttons give you control over when and how the Click event occurs. The RepeatButton raises the Click event repeatedly from the time it is pressed until it is released. The Delay property determines when the event begins. You can also control the interval of the repetitions with the Interval property.

Customizing the RepeatButton Control

To apply the same property settings to multiple RepeatButton 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 RepeatButton, see RepeatButton Syles 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.

System_CAPS_noteNote

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 shows how to create a RepeatButton.

<RepeatButton Width="100" DockPanel.Dock="Top" 
              Delay="500" Interval="100" 
              Click="Increase">
  Increase
</RepeatButton>

<TextBlock Name="valueText" 
           Width="100" DockPanel.Dock="Top" 
           TextAlignment="Center" FontSize="16">
  0
</TextBlock>

<RepeatButton Width="100" DockPanel.Dock="Top" 
              Delay="500" Interval="100" 
              Click="Decrease">
  Decrease
</RepeatButton>
void Increase(object sender, RoutedEventArgs e)
{
    Int32 Num = Convert.ToInt32(valueText.Text);

    valueText.Text = ((Num + 1).ToString());
}

void Decrease(object sender, RoutedEventArgs e)
{
    Int32 Num = Convert.ToInt32(valueText.Text);

    valueText.Text = ((Num - 1).ToString());
}





RichTextBox




RichTextBox Overview


The RichTextBox control enables you to display or edit flow content including paragraphs, images, tables, and more. This topic introduces the TextBoxclass and provides examples of how to use it in both Extensible Application Markup Language (XAML) and C#.

TextBox or RichTextBox?

Both RichTextBox and TextBox allow users to edit text, however, the two controls are used in different scenarios. A RichTextBox is a better choice when it is necessary for the user to edit formatted text, images, tables, or other rich content. For example, editing a document, article, or blog that requires formatting, images, etc is best accomplished using a RichTextBox. A TextBox requires less system resources then a RichTextBox and it is ideal when only plain text needs to be edited (i.e. usage in forms). See TextBox Overview for more information on TextBox. The table below summarizes the main features of TextBox and RichTextBox.

Control

Real-time Spellchecking

Context Menu

Formatting commands like ToggleBold (Ctr+B)

FlowDocument content like images, paragraphs, tables, etc.

TextBox

Yes

Yes

No

No.

RichTextBox

Yes

Yes

Yes

Yes

Note: Although TextBox does not support formatting related commands like ToggleBold (Ctr+B), many basic commands are supported by both controls such as MoveToLineEnd.

The features from the table above are covered in more detail later.

Creating a RichTextBox

The code below shows how to create a RichTextBox that a user can edit rich content in.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- A RichTextBox with no initial content in it. -->
    <RichTextBox />

</Page>

Specifically, the content edited in a RichTextBox is flow content. Flow content can contain many types of elements including formatted text, images, lists, and tables. See Flow Document Overview for in depth information on flow documents. In order to contain flow content, a RichTextBox hosts a FlowDocument object which in turn contains the editable content. To demonstrate flow content in a RichTextBox, the following code shows how to create a RichTextBox with a paragraph and some bolded text.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <StackPanel>
    <RichTextBox>
      <FlowDocument>
        <Paragraph>
          This is flow content and you can <Bold>edit me!</Bold>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>
  </StackPanel>

</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
namespace SDKSample
{
    public partial class BasicRichTextBoxWithContentExample : Page
    {
        public BasicRichTextBoxWithContentExample()
        {
            StackPanel myStackPanel = new StackPanel();

            // Create a FlowDocument to contain content for the RichTextBox.
            FlowDocument myFlowDoc = new FlowDocument();

            // Create a Run of plain text and some bold text.
            Run myRun = new Run("This is flow content and you can ");
            Bold myBold = new Bold(new Run("edit me!"));

            // Create a paragraph and add the Run and Bold to it.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(myRun);
            myParagraph.Inlines.Add(myBold);

            // Add the paragraph to the FlowDocument.
            myFlowDoc.Blocks.Add(myParagraph);

            RichTextBox myRichTextBox = new RichTextBox();

            // Add initial content to the RichTextBox.
            myRichTextBox.Document = myFlowDoc;

            myStackPanel.Children.Add(myRichTextBox);
            this.Content = myStackPanel;

        }
    }
}

The following illustration shows how this sample renders.

RichTextBox with content

Elements like Paragraph and Bold determine how the content inside a RichTextBox appears. As a user edits RichTextBox content, they change this flow content. To learn more about the features of flow content and how to work with it, see Flow Document Overview.

Note: Flow content inside a RichTextBox does not behave exactly like flow content contained in other controls. For example, there are no columns in a RichTextBox and hence no automatic resizing behavior. Also, built in features like search, viewing mode, page navigation, and zoom are not available within a RichTextBox.

Real-time Spell Checking

You can enable real-time spell checking in a TextBox or RichTextBox. When spellchecking is turned on, a red line appears underneath any misspelled words (see picture below).

Textbox with spell-checking

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 illustration below).

TextBox with context menu

You can create your own custom context menu to override the default one. See How to: Position a Custom Context Menu in a RichTextBox for more information.

Editing Commands

Editing commands enable users to format editable content inside a RichTextBox. Besides basic editing commands, RichTextBox includes formatting commands that TextBox does not support. For example, when editing in a RichTextBox, a user could press Ctr+B to toggle bold text formatting. See EditingCommands for a complete list of commands available. In addition to using keyboard shortcuts, you can hook commands up to other controls like buttons. The following example shows how to create a simple tool bar containing buttons that the user can use to change text formatting.

<Window x:Class="RichTextBoxInputPanelDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="600"
    >
  <Grid>

    <!-- Set the styles for the tool bar. -->
    <Grid.Resources>
      <Style TargetType="{x:Type Button}" x:Key="formatTextStyle">
        <Setter Property="FontFamily" Value="Palatino Linotype"></Setter>
        <Setter Property="Width" Value="30"></Setter>
        <Setter Property="FontSize" Value ="14"></Setter>
        <Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
      </Style>

      <Style TargetType="{x:Type Button}" x:Key="formatImageStyle">
        <Setter Property="Width" Value="30"></Setter>
        <Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
      </Style>
    </Grid.Resources>

    <DockPanel Name="mainPanel">

      <!-- This tool bar contains all the editing buttons. -->
      <ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">

        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Cut" ToolTip="Cut">
          <Image Source="Images\EditCut.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Copy" ToolTip="Copy">
          <Image Source="Images\EditCopy.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Paste" ToolTip="Paste">
          <Image Source="Images\EditPaste.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Undo" ToolTip="Undo">
          <Image Source="Images\EditUndo.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Redo" ToolTip="Redo">
          <Image Source="Images\EditRedo.png"></Image>
        </Button>

        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleBold" ToolTip="Bold">
          <TextBlock FontWeight="Bold">B</TextBlock>
        </Button>
        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleItalic" ToolTip="Italic">
          <TextBlock FontStyle="Italic" FontWeight="Bold">I</TextBlock>
        </Button>
        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleUnderline" ToolTip="Underline">
          <TextBlock TextDecorations="Underline" FontWeight="Bold">U</TextBlock>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.IncreaseFontSize" ToolTip="Grow Font">
          <Image Source="Images\CharacterGrowFont.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.DecreaseFontSize" ToolTip="Shrink Font">
          <Image Source="Images\CharacterShrinkFont.png"></Image>
        </Button>

        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.ToggleBullets" ToolTip="Bullets">
          <Image Source="Images\ListBullets.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.ToggleNumbering" ToolTip="Numbering">
          <Image Source="Images/ListNumbering.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignLeft" ToolTip="Align Left">
          <Image Source="Images\ParagraphLeftJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignCenter" ToolTip="Align Center">
          <Image Source="Images\ParagraphCenterJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignRight" ToolTip="Align Right">
          <Image Source="Images\ParagraphRightJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignJustify" ToolTip="Align Justify">
          <Image Source="Images\ParagraphFullJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.IncreaseIndentation" ToolTip="Increase Indent">
          <Image Source="Images\ParagraphIncreaseIndentation.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.DecreaseIndentation" ToolTip="Decrease Indent">
          <Image Source="Images\ParagraphDecreaseIndentation.png"></Image>
        </Button>

      </ToolBar>

      <!-- By default pressing tab moves focus to the next control. Setting AcceptsTab to true allows the 
           RichTextBox to accept tab characters. -->
      <RichTextBox Name="mainRTB" AcceptsTab="True"></RichTextBox>
    </DockPanel>
  </Grid>
</Window>

The following illustration shows how this sample displays.

RichTextBox with ToolBar

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.

Save, Load, and Print RichTextBox Content

The following example shows how to save content of a RichTextBox to a file, load that content back into the RichTextBox, and print the contents. Below is the markup for the example.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.SaveLoadPrintRTB" >

  <StackPanel>
    <RichTextBox Name="richTB">
      <FlowDocument>
        <Paragraph>
          <Run>Paragraph 1</Run>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>

    <Button Click="SaveRTBContent">Save RTB Content</Button>
    <Button Click="LoadRTBContent">Load RTB Content</Button>
    <Button Click="PrintRTBContent">Print RTB Content</Button>
  </StackPanel>

</Page>

Below is the code behind for the example.

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace SDKSample
{

    public partial class SaveLoadPrintRTB : Page
	{

        // Handle "Save RichTextBox Content" button click.
        void SaveRTBContent(Object sender, RoutedEventArgs args)
        {

            // Send an arbitrary URL and file name string specifying
            // the location to save the XAML in.
            SaveXamlPackage("C:\\test.xaml");
        }

        // Handle "Load RichTextBox Content" button click.
        void LoadRTBContent(Object sender, RoutedEventArgs args)
        {
            // Send URL string specifying what file to retrieve XAML
            // from to load into the RichTextBox.
            LoadXamlPackage("C:\\test.xaml");
        }

        // Handle "Print RichTextBox Content" button click.
        void PrintRTBContent(Object sender, RoutedEventArgs args)
        {
            PrintCommand();
        }

        // Save XAML in RichTextBox to a file specified by _fileName
        void SaveXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
            fStream = new FileStream(_fileName, FileMode.Create);
            range.Save(fStream, DataFormats.XamlPackage);
            fStream.Close();
        }

        // Load XAML into RichTextBox from a file specified by _fileName
        void LoadXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            if (File.Exists(_fileName))
            {
                range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
                fStream = new FileStream(_fileName, FileMode.OpenOrCreate);
                range.Load(fStream, DataFormats.XamlPackage);
                fStream.Close();
            }
        }

        // Print RichTextBox content
        private void PrintCommand()
        {
            PrintDialog pd = new PrintDialog();
            if ((pd.ShowDialog() == true))
            {
                //use either one of the below      
                pd.PrintVisual(richTB as Visual, "printing as visual");
                pd.PrintDocument((((IDocumentPaginatorSource)richTB.Document).DocumentPaginator), "printing as paginator");
            }
        }
    }
}




RichTextBox Class


Represents a rich editing control which operates on FlowDocument objects.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.RichTextBox


Remarks

FlowDocument is the only supported child element for a RichTextBox.

System_CAPS_importantImportant

RichTextBox has built-in handling for the bubbling  MouseUp and MouseDown events. Consequently, custom event handlers that listen for MouseUp or MouseDown events from a RichTextBox will never 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 RichTextBox native handling of these events, and be aware that this has notable effects on the control's UI.

While RichTextBox supports copying and pasting of images, certain scenarios are currently unsupported and may not work properly. The following table summarizes these scenarios and expected results.

Image Copy Source

Image Paste Result

Image source is a graphic metafile

No image is pasted

Image source uses relative path or link

Garbled or blank image is pasted

Image source link does not end with an expected image format (.PNG, .JPG, .GIF)

Garbled or blank image is pasted

Image source copied from malformed RichText (RTF)

Link to image source is pasted (rather than image)

Pasting HTML content into a RichTextBox might result in unexpected behavior because RichTextBox uses RTF format rather than directly using HTML format.

Text always wraps in a RichTextBox. If you do not want text to wrap then set the PageWidth on the FlowDocument to be larger than the width of the RichTextBox. However, once the page width is reached the text still wraps.

Horizontally and vertically aligning content within a RichTextBox is done with the HorizontalContentAlignment and VerticalContentAlignmentproperties. Aligning the RichTextBox within the layout of the page is done with the HorizontalAlignment and VerticalAlignment properties.

Scrollbars are not visible on a RichTextBox by default. To make a scrollbar visible, set the VerticalScrollBarVisibility property to Visible or Auto.

Usually, the TextChanged event should be used to detect when the text in a TextBox or RichTextBox changes, rather then KeyDown as you might expect. For an example, see How to: Detect When Text in a TextBox Has Changed.

RichTextBox supports a variety of keyboard commands. For a list of keyboard commands, see EditingCommands.

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 declares a RichTextBox that contains a simple FlowDocument.

<RichTextBox Name="richTB">
  <FlowDocument>
    <Paragraph>
      <Run>Paragraph 1</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 2</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 3</Run>
    </Paragraph>
  </FlowDocument>
</RichTextBox>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
namespace SDKSample
{
    public partial class RichTextBoxExample : Page
    {
        public RichTextBoxExample()
        {

            StackPanel myStackPanel = new StackPanel();

            // Create a FlowDocument to contain content for the RichTextBox.
            FlowDocument myFlowDoc = new FlowDocument();

            // Add paragraphs to the FlowDocument.
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
            RichTextBox myRichTextBox = new RichTextBox();

            // Add initial content to the RichTextBox.
            myRichTextBox.Document = myFlowDoc;

            myStackPanel.Children.Add(myRichTextBox);
            this.Content = myStackPanel;

        }
    }
}




How to: Extract the Text Content from a RichTextBox


This example shows how to extract the contents of a RichTextBox as plain text.

Example

The following Extensible Application Markup Language (XAML) code describes a named RichTextBox control with simple content.

<RichTextBox Name="richTB">
  <FlowDocument>
    <Paragraph>
      <Run>Paragraph 1</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 2</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 3</Run>
    </Paragraph>
  </FlowDocument>
</RichTextBox>

Example

The following code implements a method that takes a RichTextBox as an argument, and returns a string representing the plain text contents of the RichTextBox.

The method creates a new TextRange from the contents of the RichTextBox, using the ContentStart and ContentEnd to indicate the range of the contents to extract. ContentStart and ContentEnd properties each return a TextPointer, and are accessible on the underlying FlowDocument that represents the contents of the RichTextBoxTextRange provides a Text property, which returns the plain text portions of the TextRange as a string.

string StringFromRichTextBox(RichTextBox rtb)
{
    TextRange textRange = new TextRange(
        // TextPointer to the start of content in the RichTextBox.
        rtb.Document.ContentStart, 
        // TextPointer to the end of content in the RichTextBox.
        rtb.Document.ContentEnd
    );

    // The Text property on a TextRange object returns a string
    // representing the plain text content of the TextRange.
    return textRange.Text;
}




Change Selection in a RichTextBox Programmatically


This example shows how to programmatically change the current selection in a RichTextBox. This selection is the same as if the user had selected the content by using the user interface.

Example

The following Extensible Application Markup Language (XAML) code describes a named RichTextBox control with simple content.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.ChangeSelectionProgrammaticaly" >

  <StackPanel>
    <RichTextBox GotMouseCapture="ChangeSelection" Name="richTB">
      <FlowDocument>
        <Paragraph Name="myParagraph">
          <Run>
            When the user clicks in the RichTextBox, the selected
            text changes programmatically.
          </Run>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>
  </StackPanel>

</Page>

Example

The following code programmatically selects some arbitrary text when the user clicks inside the RichTextBox.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class ChangeSelectionProgrammaticaly : Page
	{

        // Change the current selection.
        void ChangeSelection(Object sender, RoutedEventArgs args)
        {
            // Create two arbitrary TextPointers to specify the range of content to select.
            TextPointer myTextPointer1 = myParagraph.ContentStart.GetPositionAtOffset(20);
            TextPointer myTextPointer2 = myParagraph.ContentEnd.GetPositionAtOffset(-10);

            // Programmatically change the selection in the RichTextBox.
            richTB.Selection.Select(myTextPointer1, myTextPointer2);
        }
    }
}




Save, Load, and Print RichTextBox Content


The following example shows how to save content of a RichTextBox to a file, load that content back into the RichTextBox, and print the contents.

Example

Below is the markup for the example.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.SaveLoadPrintRTB" >

  <StackPanel>
    <RichTextBox Name="richTB">
      <FlowDocument>
        <Paragraph>
          <Run>Paragraph 1</Run>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>

    <Button Click="SaveRTBContent">Save RTB Content</Button>
    <Button Click="LoadRTBContent">Load RTB Content</Button>
    <Button Click="PrintRTBContent">Print RTB Content</Button>
  </StackPanel>

</Page>

Example

Below is the code behind for the example.

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace SDKSample
{

    public partial class SaveLoadPrintRTB : Page
	{

        // Handle "Save RichTextBox Content" button click.
        void SaveRTBContent(Object sender, RoutedEventArgs args)
        {

            // Send an arbitrary URL and file name string specifying
            // the location to save the XAML in.
            SaveXamlPackage("C:\\test.xaml");
        }

        // Handle "Load RichTextBox Content" button click.
        void LoadRTBContent(Object sender, RoutedEventArgs args)
        {
            // Send URL string specifying what file to retrieve XAML
            // from to load into the RichTextBox.
            LoadXamlPackage("C:\\test.xaml");
        }

        // Handle "Print RichTextBox Content" button click.
        void PrintRTBContent(Object sender, RoutedEventArgs args)
        {
            PrintCommand();
        }

        // Save XAML in RichTextBox to a file specified by _fileName
        void SaveXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
            fStream = new FileStream(_fileName, FileMode.Create);
            range.Save(fStream, DataFormats.XamlPackage);
            fStream.Close();
        }

        // Load XAML into RichTextBox from a file specified by _fileName
        void LoadXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            if (File.Exists(_fileName))
            {
                range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
                fStream = new FileStream(_fileName, FileMode.OpenOrCreate);
                range.Load(fStream, DataFormats.XamlPackage);
                fStream.Close();
            }
        }

        // Print RichTextBox content
        private void PrintCommand()
        {
            PrintDialog pd = new PrintDialog();
            if ((pd.ShowDialog() == true))
            {
                //use either one of the below      
                pd.PrintVisual(richTB as Visual, "printing as visual");
                pd.PrintDocument((((IDocumentPaginatorSource)richTB.Document).DocumentPaginator), "printing as paginator");
            }
        }
    }
}




Position a Custom Context Menu in a RichTextBox


This example shows how to position a custom context menu for a RichTextBox.

When you implement a custom context menu for a RichTextBox, you are responsible for handling the placement of the context menu. By default, a custom context menu is opened at the center of the RichTextBox.

Example

To override the default placement behavior, add a listener for the ContextMenuOpening event. The following example shows how to do this programmatically.

richTextBox.ContextMenuOpening += new ContextMenuEventHandler(richTextBox_ContextMenuOpening);

Example

The following example shows an implementation the corresponding ContextMenuOpening event listener.

// This method is intended to listen for the ContextMenuOpening event from a RichTextBox.
// It will position the custom context menu at the end of the current selection.
void richTextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    // Sender must be RichTextBox.
    RichTextBox rtb = sender as RichTextBox;
    if (rtb == null) return;

    ContextMenu contextMenu = rtb.ContextMenu;
    contextMenu.PlacementTarget = rtb;

    // This uses HorizontalOffset and VerticalOffset properties to position the menu,
    // relative to the upper left corner of the parent element (RichTextBox in this case).
    contextMenu.Placement = PlacementMode.RelativePoint;

    // Compute horizontal and vertical offsets to place the menu relative to selection end.
    TextPointer position = rtb.Selection.End;

    if (position == null) return;

    Rect positionRect = position.GetCharacterRect(LogicalDirection.Forward);
    contextMenu.HorizontalOffset = positionRect.X;
    contextMenu.VerticalOffset = positionRect.Y;

    // Finally, mark the event has handled.
    contextMenu.IsOpen = true;
    e.Handled = true;
}





ScrollBar




ScrollBar Class


Represents a control that provides a scroll bar that has a sliding Thumb whose position corresponds to a value.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.RangeBase
                System.Windows.Controls.Primitives.ScrollBar

Remarks

The following illustration shows a ScrollBar control.

Scrollbar illustration

The ScrollBar control contains a Track control. The Track control consists of a Thumb control and two RepeatButton controls. You can increase and decrease the Value property of the ScrollBar control by pressing the RepeatButton controls or by moving the Thumb. The default range of values for the Value property is from 0 to 1. The Value represents the linear distance of the Thumb between the endpoints of the ScrollBar. You can change the default range of values by setting the Minimum and Maximum properties. The Orientation property determines whether the ScrollBar is displayed horizontally or vertically, and you must define this property for the ScrollBar control to appear.

The Track in a ScrollBar is oriented so that values increase from top to bottom for a vertical ScrollBar or from left to right for a horizontal ScrollBar.

The Track properties in the following table are the binding targets for the corresponding ScrollBar properties when the Track property is not explicitly defined. If you explicitly define the Track property, the binding does not occur.

You can access the Track control of a ScrollBar control by using the Track property.

To display UIElement content inside a box that has scroll bars, use the ScrollViewer control.

Customizing the ScrollBar Control

To apply the same property settings to multiple ScrollBar 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 ScrollBar, see ScrollBar 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in ScrollBar 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 horizontal ScrollBar that has a range of values between 0 and 100.

<ScrollBar Orientation="Horizontal" Width ="4in"
           Scroll="OnScroll" Minimum="1" Maximum="100" />




How to: Customize the Thumb Size on a ScrollBar


This topic explains how to set the Thumb of a ScrollBar to a fixed size and how to specify a minimum size for the Thumb of a ScrollBar.

Example

Description

The following example creates a ScrollBar that has a Thumb with a fixed size. The example sets the ViewportSize property of the Thumb to NaN and sets the height of the Thumb. To create a horizontal ScrollBar with a Thumb that has a fixed width, set the width of the Thumb.

Code

<Style TargetType="ScrollBar">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ScrollBar">
        <Grid Name="Bg"
              Background="{TemplateBinding Background}"
              SnapsToDevicePixels="true">
          <Grid.RowDefinitions>
            <RowDefinition MaxHeight="{DynamicResource 
            {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
            <RowDefinition Height="0.00001*"/>
            <RowDefinition MaxHeight="{DynamicResource 
            {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
          </Grid.RowDefinitions>
          <RepeatButton Style="{StaticResource ScrollBarButton}"
                        IsEnabled="{TemplateBinding IsMouseOver}"
                        Height="18"

                        Command="ScrollBar.LineUpCommand"
                        Content="M 0 4 L 8 4 L 4 0 Z" />
          <!-- Set the ViewporSize to NaN to disable autosizing of the Thumb. -->
          <Track Name="PART_Track" 
                 ViewportSize="NaN"
                 IsDirectionReversed="true"
                 Grid.Row="1"
                 Grid.ZIndex="-1">
            <Track.DecreaseRepeatButton>
              <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
                            Command="ScrollBar.PageUpCommand"/>
            </Track.DecreaseRepeatButton>
            <Track.IncreaseRepeatButton>
              <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
                            Command="ScrollBar.PageDownCommand"/>
            </Track.IncreaseRepeatButton>
            <Track.Thumb>
              <!-- Set the height of the Thumb.-->
              <Thumb Height="30"/>
            </Track.Thumb>
          </Track>
          <RepeatButton 
            Grid.Row="2" 
            Style="{StaticResource ScrollBarButton}"
            Height="18"
            Command="ScrollBar.LineDownCommand"
            Content="M 0 0 L 4 4 L 8 0 Z"/>

        </Grid>
        <ControlTemplate.Triggers>
          <Trigger SourceName="PART_Track" Property="IsEnabled" Value="false">
            <Setter TargetName="PART_Track" Property="Visibility" Value="Hidden"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Description

The following example creates a ScrollBar that has a Thumb with a minimum size. The example sets the value of VerticalScrollBarButtonHeightKey. To create a horizontal ScrollBar with a Thumb that has a minimum width, set the HorizontalScrollBarButtonWidthKey.

Code

<Style TargetType="ScrollBar">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ScrollBar">
        <Grid Name="Bg"
              Background="{TemplateBinding Background}"
              SnapsToDevicePixels="true">
          <Grid.RowDefinitions>
            <RowDefinition MaxHeight="{DynamicResource 
            {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
            <RowDefinition Height="0.00001*"/>
            <RowDefinition MaxHeight="{DynamicResource 
            {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
          </Grid.RowDefinitions>
          <RepeatButton Style="{StaticResource ScrollBarButton}"
                        IsEnabled="{TemplateBinding IsMouseOver}"
                        Height="18"
                        Command="ScrollBar.LineUpCommand"
                        Content="M 0 4 L 8 4 L 4 0 Z" />
          <Track Name="PART_Track" 
               IsDirectionReversed="true"
               Grid.Row="1"
               Grid.ZIndex="-1">
            <Track.Resources>
              <!-- Set the Thumb's minimum height to 50.
            The Thumb's minimum height is half the
            value of VerticalScrollBarButtonHeightKey. -->
              <sys:Double 
                x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">
                100
              </sys:Double>
            </Track.Resources>
            <Track.DecreaseRepeatButton>
              <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
                            Command="ScrollBar.PageUpCommand"/>
            </Track.DecreaseRepeatButton>
            <Track.IncreaseRepeatButton>
              <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}"
                            Command="ScrollBar.PageDownCommand"/>
            </Track.IncreaseRepeatButton>
            <Track.Thumb>
              <Thumb/>
            </Track.Thumb>
          </Track>
          <RepeatButton 
            Grid.Row="2" 
            Style="{StaticResource ScrollBarButton}"
            Height="18"
            Command="ScrollBar.LineDownCommand"
            Content="M 0 0 L 4 4 L 8 0 Z"/>
        </Grid>
        <ControlTemplate.Triggers>
          <Trigger SourceName="PART_Track" 
                   Property="IsEnabled" Value="false">
            <Setter TargetName="PART_Track" 
                    Property="Visibility" Value="Hidden"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>





ScrollViewer




ScrollViewer Overview


Content within a user interface is often larger than a computer screen's display area. The ScrollViewer control provides a convenient way to enable scrolling of content in Windows Presentation Foundation (WPF) applications. This topic introduces the ScrollViewer element and provides several usage examples.

This topic contains the following sections:

The ScrollViewer Control

There are two predefined elements that enable scrolling in WPF applications: ScrollBar and ScrollViewer. The ScrollViewer control encapsulates horizontal and vertical ScrollBar elements and a content container (such as a Panel element) in order to display other visible elements in a scrollable area. You must build a custom object in order to use the ScrollBar element for content scrolling. However, you can use the ScrollViewer element by itself because it is a composite control that encapsulates ScrollBar functionality.

The ScrollViewer control responds to both mouse and keyboard commands, and defines numerous methods with which to scroll content by predetermined increments. You can use the ScrollChanged event to detect a change in a ScrollViewer state.

ScrollViewer can only have one child, typically a Panel element that can host a Children collection of elements. The Content property defines the sole child of the ScrollViewer.

Physical vs. Logical Scrolling

Physical scrolling is used to scroll content by a predetermined physical increment, typically by a value that is declared in pixels. Logical scrolling is used to scroll to the next item in the logical tree. Physical scrolling is the default scroll behavior for most Panel elements. WPF supports both types of scrolling.

The IScrollInfo Interface

The IScrollInfo interface represents the main scrolling region within a ScrollViewer or derived control. The interface defines scrolling properties and methods that can be implemented by Panel elements that require scrolling by logical unit, rather than by a physical increment. Casting an instance of IScrollInfo to a derived Panel and then using its scrolling methods provides a useful way to scroll to the next logical unit in a child collection, rather than by pixel increment. By default, the ScrollViewer control supports scrolling by physical units.

StackPanel and VirtualizingStackPanel both implement IScrollInfo and natively support logical scrolling. For layout controls that natively support logical scrolling, you can still achieve physical scrolling by wrapping the host Panel element in a ScrollViewer and setting the CanContentScrollproperty to false.

The following code example demonstrates how to cast an instance of IScrollInfo to a StackPanel and use content scrolling methods (LineUp and LineDown) defined by the interface.

private void spLineUp(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineUp();
}
private void spLineDown(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineDown();
}

Defining and Using a ScrollViewer Element

The following example creates a ScrollViewer in a window that contains some text and a rectangle. ScrollBar elements appear only when they are necessary. When you resize the window, the ScrollBar elements appear and disappear, due to updated values of the ComputedHorizontalScrollBarVisibility and ComputedVerticalScrollBarVisibility properties.

// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "ScrollViewer Sample";

// Define a ScrollViewer
myScrollViewer = new ScrollViewer();
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

// Add Layout control
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;

TextBlock myTextBlock = new TextBlock();
myTextBlock.TextWrapping = TextWrapping.Wrap;
myTextBlock.Margin = new Thickness(0, 0, 0, 20);
myTextBlock.Text = "Scrolling is enabled when it is necessary. Resize the Window, making it larger and smaller.";

Rectangle myRectangle = new Rectangle();
myRectangle.Fill = Brushes.Red;
myRectangle.Width = 500;
myRectangle.Height = 500;

// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myTextBlock);
myStackPanel.Children.Add(myRectangle);

// Add the StackPanel as the lone Child of the Border
myScrollViewer.Content = myStackPanel;

// Add the Border as the Content of the Parent Window Object
mainWindow.Content = myScrollViewer;
mainWindow.Show ();

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      WindowTitle="ScrollViewer Sample">
  <ScrollViewer HorizontalScrollBarVisibility="Auto">
    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
      <TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary. 
      Resize the window, making it larger and smaller.</TextBlock>
      <Rectangle Fill="Red" Width="500" Height="500"></Rectangle>
    </StackPanel>
  </ScrollViewer>
</Page>

Styling a ScrollViewer

Like all controls in Windows Presentation Foundation, the ScrollViewer can be styled in order to change the default rendering behavior of the control. For additional information on control styling, see Styling and Templating.

Paginating Documents

For document content, an alternative to scrolling is to choose a document container that supports pagination. FlowDocument is for documents that are designed to be hosted within a viewing control, such as FlowDocumentPageViewer, that supports paginating content across multiple pages, preventing the need for scrolling. DocumentViewer provides a solution for viewing FixedDocument content, which uses traditional scrolling to display content outside the realm of the display area.

For additional information about document formats and presentation options, see Documents in WPF.




ScrollViewer Class


Represents a scrollable area that can contain other visible elements.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.ScrollViewer


Remarks

ScrollViewer enables content to be displayed in a smaller area than its actual size. When the content of the ScrollViewer is not entirely visible, the ScrollViewer displays scrollbars that the user can use to move the content areas that is visible. The area that includes all of the content of the ScrollViewer is the extent. The visible area of the content is the viewport.

Physical scrolling is used to scroll content by a predetermined physical increment, typically by a value that is declared in pixels. Logical scrolling is used to scroll to the next item in the logical tree. If you require physical scrolling instead of logical scrolling, wrap the host Panel element in a ScrollViewer and set its CanContentScroll property to false. Physical scrolling is the default scroll behavior for most Panel elements.

If your ScrollViewer contains a large number of items, the scrolling performance may be affected. In this case, set IsDeferredScrollingEnabled to true. This causes the content view to remain static while dragging the Thumb and to update only when the Thumb is released.

Because the scroll bars for a ScrollViewer element are defined in the default style of the element, scroll bars will no longer appear if you apply a custom style to a ScrollViewer. Scroll bars must be defined in the custom style for them to appear.

Customizing the ScrollViewer Control

To apply the same property settings to multiple ScrollViewer 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 ScrollViewer, see ScrollViewer 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in ScrollViewer 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 ScrollViewer that contains some text and a rectangle. The scroll bars appear only when they are needed. When you resize the window, the scroll bars appear and disappear.

// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "ScrollViewer Sample";

// Define a ScrollViewer
myScrollViewer = new ScrollViewer();
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

// Add Layout control
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;

TextBlock myTextBlock = new TextBlock();
myTextBlock.TextWrapping = TextWrapping.Wrap;
myTextBlock.Margin = new Thickness(0, 0, 0, 20);
myTextBlock.Text = "Scrolling is enabled when it is necessary. Resize the Window, making it larger and smaller.";

Rectangle myRectangle = new Rectangle();
myRectangle.Fill = Brushes.Red;
myRectangle.Width = 500;
myRectangle.Height = 500;

// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myTextBlock);
myStackPanel.Children.Add(myRectangle);

// Add the StackPanel as the lone Child of the Border
myScrollViewer.Content = myStackPanel;

// Add the Border as the Content of the Parent Window Object
mainWindow.Content = myScrollViewer;
mainWindow.Show ();

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      WindowTitle="ScrollViewer Sample">
  <ScrollViewer HorizontalScrollBarVisibility="Auto">
    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
      <TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary. 
      Resize the window, making it larger and smaller.</TextBlock>
      <Rectangle Fill="Red" Width="500" Height="500"></Rectangle>
    </StackPanel>
  </ScrollViewer>
</Page>




How to: Handle the ScrollChanged Event



Example

This example shows how to handle the ScrollChanged event of a ScrollViewer.

FlowDocument element with Paragraph parts is defined in XAML. When the ScrollChanged event occurs due to user interaction, a handler is invoked, and text is written to a TextBlock indicating that the event has occurred.

<ScrollViewer Name="sv1" CanContentScroll="False" ScrollChanged="sChanged">

  <FlowDocument FontFamily="Arial" PageWidth="400">
    <Paragraph>
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
    </Paragraph>
    <Paragraph>
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
      laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation
      ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
    </Paragraph>

  </FlowDocument>
</ScrollViewer>
private void sChanged(object sender, ScrollChangedEventArgs e)
{
    if (sv1.CanContentScroll == true)
    {
        tBlock1.Foreground = System.Windows.Media.Brushes.Red;
        tBlock1.Text = "ScrollChangedEvent just Occurred";
        tBlock2.Text = "ExtentHeight is now " + e.ExtentHeight.ToString();
        tBlock3.Text = "ExtentWidth is now " + e.ExtentWidth.ToString();
        tBlock4.Text = "ExtentHeightChange was " + e.ExtentHeightChange.ToString();
        tBlock5.Text = "ExtentWidthChange was " + e.ExtentWidthChange.ToString();
        tBlock6.Text = "HorizontalOffset is now " + e.HorizontalOffset.ToString();
        tBlock7.Text = "VerticalOffset is now " + e.VerticalOffset.ToString();
        tBlock8.Text = "HorizontalChange was " + e.HorizontalChange.ToString();
        tBlock9.Text = "VerticalChange was " + e.VerticalChange.ToString();
        tBlock10.Text = "ViewportHeight is now " + e.ViewportHeight.ToString();
        tBlock11.Text = "ViewportWidth is now " + e.ViewportWidth.ToString();
        tBlock12.Text = "ViewportHeightChange was " + e.ViewportHeightChange.ToString();
        tBlock13.Text = "ViewportWidthChange was " + e.ViewportWidthChange.ToString();
    }
    else
    {
        tBlock1.Text = "";
    }




How to: Scroll Content by Using the IScrollInfo Interface


This example shows how to scroll content by using the IScrollInfo interface.

Example

The following example demonstrates the features of the IScrollInfo interface. The example creates a StackPanel element in Extensible Application Markup Language (XAML) that is nested in a parent ScrollViewer. The child elements of the StackPanel can be scrolled logically by using the methods defined by the IScrollInfo interface and cast to the instance of StackPanel (sp1) in code.

<Border BorderBrush="Black" Background="White" BorderThickness="2" Width="500" Height="500">
    <ScrollViewer Name="sv1" CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
        <StackPanel Name="sp1">
            <Button>Button 1</Button>
            <Button>Button 2</Button>
            <Button>Button 3</Button>
            <Button>Button 4</Button>
            <Button>Button 5</Button>
            <Rectangle Width="700" Height="500" Fill="Purple"/>
            <TextBlock>Rectangle 1</TextBlock>
            <Rectangle Width="700" Height="500" Fill="Red"/>
            <TextBlock>Rectangle 2</TextBlock>
            <Rectangle Width="700" Height="500" Fill="Green"/>
            <TextBlock>Rectangle 3</TextBlock>
        </StackPanel> 
    </ScrollViewer>
</Border>

Each Button in the XAML file triggers an associated custom method that controls scrolling behavior in StackPanel. The following example shows how to use the LineUp and LineDown methods; it also generically shows how to use all the positioning methods that the IScrollInfo class defines.

private void spLineUp(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineUp();
}
private void spLineDown(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineDown();
}




How to: Use the Content-Scrolling Methods of ScrollViewer


This example shows how to use the scrolling methods of the ScrollViewer element. These methods provide incremental scrolling of content, either by line or by page, in a ScrollViewer.

Example

The following example creates a ScrollViewer named sv1, which hosts a child TextBlock element. Because the TextBlock is larger than the parent ScrollViewer, scroll bars appear in order to enable scrolling. Button elements that represent the various scrolling methods are docked on the left in a separate StackPanel. Each Button in the XAML file calls a related custom method that controls scrolling behavior in ScrollViewer.

<StackPanel DockPanel.Dock="Left" Width="150">
  <Button Margin="3,0,0,2" Background="White" Click="svLineUp">Adjust Line Up</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svLineDown">Adjust Line Down</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svLineRight">Adjust Line Right</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svLineLeft">Adjust Line Left</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svPageUp">Adjust Page Up</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svPageDown">Adjust Page Down</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svPageRight">Adjust Page Right</Button>
  <Button Margin="3,0,0,2" Background="White" Click="svPageLeft">Adjust Page Left</Button>
  <TextBlock Name="txt2" TextWrapping="Wrap"/>
</StackPanel>

<Border BorderBrush="Black" Background="White" BorderThickness="2" Height="520" Width="520" VerticalAlignment="Top">
  <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" Name="sv1">
    <TextBlock TextWrapping="Wrap" Width="800" Height="1000" Name="txt1"/> 
  </ScrollViewer>
</Border>

The following example uses the LineUp and LineDown methods.

private void svLineUp(object sender, RoutedEventArgs e)
{
    sv1.LineUp();
}
private void svLineDown(object sender, RoutedEventArgs e)
{
    sv1.LineDown();
}





Track




Track Class


Represents a control primitive that handles the positioning and sizing of a Thumb control and two RepeatButton controls that are used to set a Value.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Primitives.Track


Remarks

The Track control does not have a default ControlTemplate. Its ControlTemplate is implemented as part of the ControlTemplate of the ScrollBar and Slider controls. The Track has a Thumb control and two RepeatButton controls that are used to change the Value property of the Track control.

The following illustration shows a Track on a slider.

A Track on a Slider

RepeatButton, Thumb

The following table shows the Track properties and the corresponding RangeBase properties that they automatically bind to. When either property changes, the bound property also changes.

The following table shows the Track properties and the corresponding ScrollBar properties to which they bind when a Track is part of a ScrollBarcontrol and the Track properties are not explicitly set.

The following table shows the Track properties and the corresponding Slider properties to which they bind when a Track is part of a Slider control and the Track properties are not explicitly set.

Additionally, the Delay properties for the RepeatButton controls for a Slider control bind with the Delay properties for the RepeatButton controls of the Track control.

When a Track is used to scroll content, the size of the Thumb control is proportional to the percentage of the content that appears in the viewable area or viewport. The following illustration shows an example of a ScrollViewer control that implements a Track control.

A ScrollBar that has a Track control

ScrollBar illlustration

The following calculation is used to compute the size of the Thumb.

thumbSize = (viewportSize/(maximumminimum+viewportSize))×trackLength

The viewportSize parameter is the value of the ViewportSize property. The maximum and minimum parameters correspond to the Maximum and Minimum property values. The value of the expression maximumminimum+viewportSize is the size of the scrollable content. Note that the value of the Maximum property represents the Value of the Track when the content is scrolled to the bottom. This Maximum value is not the same as the length or extent of the content. For a more detailed explanation, see Track.Maximum.

The Value of a Track in a ScrollBar increases from top to bottom or from left to right depending on the orientation of the ScrollBar. Similarly, the Value of a Track in a Slider increases from bottom to top or from left to right depending on the orientation of the Slider. To change the direction of increasing value, set the IsDirectionReversed property of the Track to true.

Examples

The following example shows how to define a Track control in a ScrollBar ControlTemplate.

<ControlTemplate TargetType="{x:Type ScrollBar}">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="12"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="12" />
      <RowDefinition Height="*"/>
      <RowDefinition Height="12" />
    </Grid.RowDefinitions>
    <Border Grid.Row="1" BorderThickness="0" 
            Background="Transparent" CornerRadius="4"/>
    <RepeatButton Grid.Row="0" 
                  Style="{DynamicResource Scrollbar_LineButton}" 
                  Command="ScrollBar.LineUpCommand" Content=" ^" />

    <!--IsDirectionReversed set to true draws a ScrollBar with a 
        Track whose lowest value is at the bottom.
        The default orientation of a ScrollBar is for the Track
        values to decrease from top to bottom.-->
    <Track Grid.Row="1" Name="PART_Track"
           IsDirectionReversed="true">
      <Track.DecreaseRepeatButton>
        <RepeatButton Style="{DynamicResource ScrollBar_UpTrack}"/>
      </Track.DecreaseRepeatButton>
      <Track.Thumb>
        <Thumb Style="{DynamicResource ScrollBar_HorizontalThumb}"/>
      </Track.Thumb>
      <Track.IncreaseRepeatButton>
        <RepeatButton Style="{DynamicResource ScrollBar_DownTrack}"/>
      </Track.IncreaseRepeatButton>
    </Track>
    <RepeatButton Grid.Row="2" 
                  Style="{DynamicResource Scrollbar_LineButton}" 
                  Command="ScrollBar.LineDownCommand" Content=" v" />
  </Grid>
</ControlTemplate>





Thumb




Thumb Class


Represents a control that can be dragged by the user.

Namespace:   System.Windows.Controls.Primitives
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.Thumb
                System.Windows.Controls.GridSplitter


Remarks

The Thumb control can be included in another control, such as a ScrollBar or Slider control, to let the user change the control's value. The Thumb can also be used to resize controls. For example, a Thumb control in the corner of a window can provide a location for the user to click with the mouse to start a resize operation.

Thumb provides DragStartedDragCompleted and DragDelta events to manage drag operations associated with the mouse pointer. When the user presses the left mouse button, the Thumb control receives logical focus and mouse capture, and the DragStarted event is raised. While the Thumbcontrol has focus and mouse capture, the DragDelta event can be raised multiple times without limit. When the user releases the left mouse button, the Thumb control loses mouse capture and the DragCompleted event is raised.

The event information provides a change in position, but does not reposition the Thumb. You must manually change or reposition the Thumb or any other elements that you want to resize or change as a result of the drag operation. The Thumb control does not provide drag-and-drop functionality.

Thumb control can receive mouse capture, but cannot receive keyboard focus. Therefore, the IsKeyboardFocused property that corresponds to keyboard focus is set to false. This value overrides the parent class Control that sets this property to true.

To provide drag capability, class handling is provided for the MouseLeftButtonDownMouseLeftButtonUp and MouseMove events. For more information, see the OnMouseLeftButtonDownOnMouseLeftButtonUp and OnMouseMove methods.

When a Thumb is part of a Track control that scrolls content in a viewable area, or viewport, the size of the Thumb reflects the size of the viewport. For more information, see the Track class. The following illustration shows a Thumb control that is part of a ScrollBar control.

Scrollbar illustration

Customizing the Thumb Control

To apply the same property settings to multiple Thumb 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 Thumb, see Thumb Syles 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.

System_CAPS_noteNote

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.





Separator




Separator Class


Control that is used to separate items in items controls.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.Separator
                System.Windows.Controls.Ribbon.RibbonSeparator


Remarks

Separator control draws a line, horizontal or vertical, between items in controls, such as ListBoxMenu, and ToolBarSeparator controls do not react to any keyboard, mouse, mouse wheel, or tablet input and cannot be enabled or selected. Separator controls inside Menu elements appear differently from Separator controls outside a Menu. When you create a Menu with a Separator, the control automatically applies the Style identified by the MenuItem.SeparatorStyleKey property. Styles are placed in resource dictionaries and are searched for by their keys. To change the Style of a Separator inside a Menu, you must use the MenuItem.SeparatorStyleKey property to create your new Style. For an example, see the MenuItem.SeparatorStyleKey property.

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 shows how to use Separator controls in a ToolBar.

<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>





Slider




Slider Class


Represents a control that lets the user select from a range of values by moving a Thumb control along a Track.

Namespace:   System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)

Inheritance Hierarchy

System.Object
  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.RangeBase
                System.Windows.Controls.Slider

Remarks

Slider control lets users select a value from a range of values. The following illustration shows an example of a Slider control.

Example of a Slider Control

Slider illustration

You can customize a Slider control by setting its properties. The following list describes some of the attributes of a Slider that you can customize:

  • The orientation of the Slider, either horizontal or vertical.

  • The tick mark locations along the Slider track.

  • The display of tooltips to show the current value of the Slider.

  • The ability of the Thumb to either snap to tick marks or to be positioned at any point along the Slider.

  • The direction of increasing value along the Slider.

For more information about how to customize a Slider control, see the individual member.

Slider overrides the metadata of the Maximum property and sets its default to 10. For more information, see Dependency Properties Overview.

System_CAPS_noteNote

If the value of the Slider is animated, the user may no longer be able to interact with the Slider control after the animation finishes. See How to: Set a Property After Animating It with a Storyboard for options of how you can restore user control of a Slider after it is animated.

Customizing the Slider Control

To apply the same property settings to multiple Slider 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 Slider, see Slider 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.

System_CAPS_noteNote

Setting a visual property will only have an effect if that property is both present in Slider 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 bind the Height property of a Rectangle to the Value of a Slider control.

The following example defines a Slider control that is named RectangeHeight that can have a Value between 0 and 200.

<Slider Name="RectangleHeight"  Margin="10, 0, 0, 0" 
  Width="100" Orientation="Horizontal" HorizontalAlignment="Left" 
  Value="50" Minimum="0" Maximum="200" 
  SmallChange="1" LargeChange="10"
  TickPlacement="BottomRight" TickFrequency="10"/>

The following example shows how to define a Rectangle that binds its Height property to the Value of the Slider control. (In the complete sample, a similar binding is created for the Width property.)

<Rectangle Fill="Blue" HorizontalAlignment="Left" 
           Margin="50,20,0,0" 
           Height="{Binding ElementName=RectangleHeight,Path=Value}" 
           Width="{Binding ElementName=RectangleWidth,Path=Value}"/>




How to: Customize the Ticks on a Slider


This example shows how to create a Slider control that has tick marks.

Example

The TickBar displays when you set the TickPlacement property to a value other than None, which is the default value.

The following example shows how to create a Slider with a TickBar that displays tick marks. The TickPlacement and TickFrequency properties define the location of the tick marks and the interval between them. When you move the Thumb, tooltips display the value of the Slider. The AutoToolTipPlacement property defines where the tooltips occur. The Thumb movements correspond to the location of the tick marks because IsSnapToTickEnabled is set to true.

The following example shows how to use the Ticks property to create tick marks along the Slider at irregular intervals.

 <Slider Width="100" Value="50" Orientation="Horizontal" HorizontalAlignment="Left" 
IsSnapToTickEnabled="True" Maximum="3" TickPlacement="BottomRight" 
AutoToolTipPlacement="BottomRight" AutoToolTipPrecision="2" 
Ticks="0, 1.1, 2.5, 3"/>



































'프로그래밍 > WPF' 카테고리의 다른 글

Documents  (0) 2016.11.19
Control Library 3  (0) 2016.11.18
Controls  (0) 2016.11.05
WPF Unmanaged API Reference  (0) 2016.11.05
Threading Model  (0) 2016.11.05
:
Posted by 지훈2