Index of Locally Available Projects:: Ebook
Index of Locally Available Projects:: Ebook
© 2008 Xavier Roche & other contributors - Web Design: Leto Kauler.
Home Contact Us
                                                                                             Download as PDF
       The complete WPF tutorial
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         Welcome to this WPF tutorial, currently consisting of 93 articles, where you'll     About WPF
         learn to make your own applications using the WPF UI framework. If you're
                                                                                              What is WPF?
         brand new to WPF, then we recommend that you start from the first chapter
                                                                                              WPF vs. WinForms
         and then read your way through all of it.
         Have a look at the Table of contents to the right, where all the chapters are
         listed and be sure to come back regularly, as we will keep adding new               Getting started
         chapters to it. We hope that this tutorial will get you started properly on WPF.     Visual Studio Express
                                                                                              Hello, WPF!
         Everything here is free, and we hope you like our work. If you do, then all we
         ask is that you link to this tutorial on your website, Facebook profile, personal
         blog or anything else where a link is possible. Also, if you see anything
                                                                                             XAML
         interesting in one of our ad blocks, please click it to help us maintain this
         tutorial. Thank you!                                                                 What is XAML?
                                                                                              Basic XAML
         A basic knowledge of C# is recommended when learning to use WPF. If you              Events in XAML
         don't already know some C#, you may wish to get a better sense of by going
         through a C# tutorial.
                                                                                             A WPF application
                                                                                              Introduction
         >> Start the tutorial
                                                               The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                             Next
                                                                                             Basic controls
                                                                                              The TextBlock control
         comments powered by Disqus
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                   Panels
                                    Introduction to WPF Panels
                                    The Canvas
                                    The WrapPanel
                                    The StackPanel
                                    The DockPanel
                                    The Grid
                                    The Grid - Rows & Columns
                                    The Grid - Units
                                    The Grid - Spanning
                                    The Grid - GridSplitter
                                    Using the Grid: A contact
                                     form
                                   Data binding
                                    Introduction
                                    Hello, bound world!
                                    Using the DataContext
                                    The UpdateSourceTrigger
                                     property
                                    Responding to changes
                                    Value conversion with
                                     IValueConverter
                                    The StringFormat property
                                    Debugging data bindings
                                   Commands
                                    Introduction
                                    Using commands
                                    Implementing custom
                                     commands
                                   Common interface
                                   controls
                                    The Menu control
                                    The ContextMenu
                                    The ToolBar control
                                    The StatusBar control
                                    The Ribbon Control
                                     Introduction
                                     The
                                      FlowDocumentScrollViewer
                                      control
                                     The
                                      FlowDocumentPageViewer
                                      control
                                     The FlowDocumentReader
                                      control
                                     Creating a FlowDocument
                                      from Code-behind
                                     Advanced FlowDocument
                                      content
                                     The RichTextBox control
                                   Misc. controls
                                     The Border control
                                     The Slider control
                                     The ProgressBar control
                                     The WebBrowser control
                                     The WindowsFormsHost
                                     control
                                   The TabControl
                                     Using the TabControl
                                     Tab positions
                                     Styling the TabItems
                                   List controls
                                     The ItemsControl
                                     The ListBox control
                                     The ComboBox control
ListView filtering
                                                                    Styles
                                                                     Introduction
                                                                     Using styles
                                                                     Triggers
                                                                     Multi triggers
                                                                     Trigger animations
                                                                    Misc.
                                                                     The DispatcherTimer
                                         
         
Download
                                          PDF!
                                   
Back to Top
Home Contact Us
                                                                                             Download as PDF
       The complete WPF tutorial
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         Welcome to this WPF tutorial, currently consisting of 93 articles, where you'll     About WPF
         learn to make your own applications using the WPF UI framework. If you're
                                                                                              What is WPF?
         brand new to WPF, then we recommend that you start from the first chapter
                                                                                              WPF vs. WinForms
         and then read your way through all of it.
         Have a look at the Table of contents to the right, where all the chapters are
         listed and be sure to come back regularly, as we will keep adding new               Getting started
         chapters to it. We hope that this tutorial will get you started properly on WPF.     Visual Studio Express
                                                                                              Hello, WPF!
         Everything here is free, and we hope you like our work. If you do, then all we
         ask is that you link to this tutorial on your website, Facebook profile, personal
         blog or anything else where a link is possible. Also, if you see anything
                                                                                             XAML
         interesting in one of our ad blocks, please click it to help us maintain this
         tutorial. Thank you!                                                                 What is XAML?
                                                                                              Basic XAML
         A basic knowledge of C# is recommended when learning to use WPF. If you              Events in XAML
         don't already know some C#, you may wish to get a better sense of by going
         through a C# tutorial.
                                                                                             A WPF application
                                                                                              Introduction
         >> Start the tutorial
                                                               The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                             Next
                                                                                             Basic controls
                                                                                              The TextBlock control
         comments powered by Disqus
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                   Panels
                                    Introduction to WPF Panels
                                    The Canvas
                                    The WrapPanel
                                    The StackPanel
                                    The DockPanel
                                    The Grid
                                    The Grid - Rows & Columns
                                    The Grid - Units
                                    The Grid - Spanning
                                    The Grid - GridSplitter
                                    Using the Grid: A contact
                                     form
                                   Data binding
                                    Introduction
                                    Hello, bound world!
                                    Using the DataContext
                                    The UpdateSourceTrigger
                                     property
                                    Responding to changes
                                    Value conversion with
                                     IValueConverter
                                    The StringFormat property
                                    Debugging data bindings
                                   Commands
                                    Introduction
                                    Using commands
                                    Implementing custom
                                     commands
                                   Common interface
                                   controls
                                    The Menu control
                                    The ContextMenu
                                    The ToolBar control
                                    The StatusBar control
                                    The Ribbon Control
                                     Introduction
                                     The
                                      FlowDocumentScrollViewer
                                      control
                                     The
                                      FlowDocumentPageViewer
                                      control
                                     The FlowDocumentReader
                                      control
                                     Creating a FlowDocument
                                      from Code-behind
                                     Advanced FlowDocument
                                      content
                                     The RichTextBox control
                                   Misc. controls
                                     The Border control
                                     The Slider control
                                     The ProgressBar control
                                     The WebBrowser control
                                     The WindowsFormsHost
                                     control
                                   The TabControl
                                     Using the TabControl
                                     Tab positions
                                     Styling the TabItems
                                   List controls
                                     The ItemsControl
                                     The ListBox control
                                     The ComboBox control
ListView filtering
                                                                    Styles
                                                                     Introduction
                                                                     Using styles
                                                                     Triggers
                                                                     Multi triggers
                                                                     Trigger animations
                                                                    Misc.
                                                                     The DispatcherTimer
                                         
         
Download
                                          PDF!
                                   
Back to Top
Home Contact Us
                                                                                                Download as PDF
       WPF vs. WinForms
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
         In the previous chapter, we talked about what WPF is and a little bit about            About WPF
          WinForms. In this chapter, I will try to compare the two, because while they
                                                                                                 What is WPF?
          do serve the same purpose, there is a LOT of differences between them. If
                                                                                                 WPF vs. WinForms
          you have never worked with WinForms before, and especially if WPF is your
          very first GUI framework, you may skip this chapter, but if you're interested in
          the differences then read on.
                                                                                                Getting started
         The single most important difference between WinForms and WPF is the fact               Visual Studio Express
         that while WinForms is simply a layer on top of the standard Windows                    Hello, WPF!
         controls (e.g. a TextBox), WPF is built from scratch and doesn't rely on
         standard Windows controls in almost all situations. This might seem like a
         subtle difference, but it really isn't, which you will definitely notice if you have
                                                                                                XAML
         ever worked with a framework that depends on Win32/WinAPI.
                                                                                                 What is XAML?
         A great example of this is a button with an image and text on it. This is not a         Basic XAML
         standard Windows control, so WinForms doesn't offer you this possibility out            Events in XAML
         of the box. Instead you will have to draw the image yourself, implement your
         own button that supports images or use a 3rd party control. With WPF, a
         button can contain anything because it's essentially a border with content             A WPF application
         and various states (e.g. untouched, hovered, pressed). The WPF button is                Introduction
         "look-less", as are most other WPF controls, which means that it can contain            The Window
         a range of other controls inside of it. You want a button with an image and             Working with App.xaml
         some text? Just put an Image and a TextBlock control inside of the button               Command-line parameters
         and you're done! You simply don’t get this kind of flexibility out of the               Resources
         standard WinForms controls, which is why there's a big market for rather                Handling exceptions
         simple implementations of controls like buttons with images and so on.
         The drawback to this flexibility is that sometimes you will have to work harder
         to achieve something that was very easy with WinForms, because it was
                                                                                                Basic controls
         created for just the scenario you need it for. At least that's how it feels in the      The TextBlock control
         beginning, where you find yourself creating templates to make a ListView                The TextBlock control - Inline
         with an image and some nicely aligned text, something that the WinForms                 formatting
         ListViewItem does in a single line of code.                                             The Label control
                                                                                                 The TextBox control
         This was just one difference, but as you work with WPF, you will realize that it        The CheckBox control
          is in fact the underlying reason for many of the other differences - WPF is           The RadioButton control
          simply just doing things in its own way, for better and for worse. You're no          The PasswordBox control
          longer constrained to doing things the Windows way, but to get this kind of
          flexibility, you pay with a little more work when you're really just looking to do
          things the Windows way.                                                              Panels
         The following is a completely subjective list of the key advantages for WPF            Introduction to WPF Panels
         and WinForms. It should give you a better idea of what you're going into.              The Canvas
                                                                                                The WrapPanel
         WPF advantages                                                                         The StackPanel
                                                                                                The DockPanel
             It's newer and thereby more in tune with current standards                         The Grid
             Microsoft is using it for a lot of new applications, e.g. Visual Studio            The Grid - Rows & Columns
             It's more flexible, so you can do more things without having to write or           The Grid - Units
              buy new controls                                                                  The Grid - Spanning
             When you do need to use 3rd party controls, the developers of these                The Grid - GridSplitter
              controls will likely be more focused on WPF because it's newer                    Using the Grid: A contact
             XAML makes it easy to create and edit your GUI, and allows the work                 form
              to be split between a designer (XAML) and a programmer (C#,
              VB.NET etc.)
             Databinding, which allows you to get a more clean separation of data
                                                                                               Data binding
              and layout
                                                                                                Introduction
             Uses hardware acceleration for drawing the GUI, for better
                                                                                                Hello, bound world!
              performance
                                                                                                Using the DataContext
             It allows you to make user interfaces for both Windows applications
                                                                                                The UpdateSourceTrigger
              and web applications (Silverlight/XBAP)
                                                                                                 property
         WinForms advantages                                                                    Responding to changes
                                                                                                Value conversion with
             It's older and thereby more tried and tested                                        IValueConverter
             There are already a lot of 3rd party controls that you can buy or get for          The StringFormat property
              free                                                                              Debugging data bindings
             The designer in Visual Studio is still, as of writing, better for WinForms
              than for WPF, where you will have to do more of the work yourself
              with WPF                                                                         Commands
                                                                                                Introduction
               Previous                                                        Next             Using commands
                                                                                                Implementing custom
                                                                                                 commands
                                                 Introduction
                                                 The
                                                  FlowDocumentScrollViewer
                                                  control
                                                 The
                                                  FlowDocumentPageViewer
                                                  control
                                                 The FlowDocumentReader
                                                  control
                                                 Creating a FlowDocument
                                                  from Code-behind
                                                 Advanced FlowDocument
                                                  content
                                                 The RichTextBox control
                                               Misc. controls
                                                 The Border control
                                                 The Slider control
                                                 The ProgressBar control
                                                 The WebBrowser control
                                                 The WindowsFormsHost
                                                 control
                                               The TabControl
                                                 Using the TabControl
                                                 Tab positions
                                                 Styling the TabItems
                                               List controls
                                                 The ItemsControl
                                                 The ListBox control
                                                 The ComboBox control
ListView filtering
                                                                                Styles
                                                                                 Introduction
                                                                                 Using styles
                                                                                 Triggers
                                                                                 Multi triggers
                                                                                 Trigger animations
                                                                                Misc.
                                                                                 The DispatcherTimer
                                                     
         
Download
                                                      PDF!
                                               
Back to Top
Home Contact Us
                                                                                          Download as PDF
       What is WPF?
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         WPF, which stands for Windows Presentation Foundation, is Microsoft's latest     About WPF
         approach to a GUI framework, used with the .NET framework.
                                                                                           What is WPF?
         But what IS a GUI framework? GUI stands for Graphical User Interface, and         WPF vs. WinForms
         you're probably looking at one right now. Windows has a GUI for working
         with your computer, and the browser that you're likely reading this document
         in has a GUI that allows you to surf the web.                                    Getting started
                                                                                           Visual Studio Express
         A GUI framework allows you to create an application with a wide range of GUI
                                                                                           Hello, WPF!
         elements, like labels, textboxes and other well known elements. Without a
         GUI framework you would have to draw these elements manually and handle
         all of the user interaction scenarios like text and mouse input. This is a LOT
                                                                                          XAML
         of work, so instead, most developers will use a GUI framework which will do
         all the basic work and allow the developers to focus on making great              What is XAML?
         applications.                                                                     Basic XAML
                                                                                           Events in XAML
         There are a lot of GUI frameworks out there, but for .NET developers, the
         most interesting ones are currently WinForms and WPF. WPF is the newest,
         but Microsoft is still maintaining and supporting WinForms. As you will see in   A WPF application
         the next chapter, there are quite a few differences between the two
                                                                                           Introduction
         frameworks, but their purpose is the same: To make it easy to create
                                                                                           The Window
         applications with a great GUI.
                                                                                           Working with App.xaml
         In the next chapter, we will look at the differences between WinForms and         Command-line parameters
          WPF.                                                                             Resources
                                                                                           Handling exceptions
                                                                           Next
                                                                                          Basic controls
                                                                                           The TextBlock control
         comments powered by Disqus
                                                                                           The TextBlock control - Inline
                                                                                           formatting
                                                                                           The Label control
                                                                                           The TextBox control
                                                                                           The CheckBox control
                                           Panels
                                            Introduction to WPF Panels
                                            The Canvas
                                            The WrapPanel
                                            The StackPanel
                                            The DockPanel
                                            The Grid
                                            The Grid - Rows & Columns
                                            The Grid - Units
                                            The Grid - Spanning
                                            The Grid - GridSplitter
                                            Using the Grid: A contact
                                             form
                                           Data binding
                                            Introduction
                                            Hello, bound world!
                                            Using the DataContext
                                            The UpdateSourceTrigger
                                             property
                                            Responding to changes
                                            Value conversion with
                                             IValueConverter
                                            The StringFormat property
                                            Debugging data bindings
                                           Commands
                                            Introduction
                                            Using commands
                                            Implementing custom
                                             commands
                                           Common interface
                                           controls
                                            The Menu control
                                            The ContextMenu
                                            The ToolBar control
                                            The StatusBar control
                                            The Ribbon Control
                                             Introduction
                                             The
                                              FlowDocumentScrollViewer
                                              control
                                             The
                                              FlowDocumentPageViewer
                                              control
                                             The FlowDocumentReader
                                              control
                                             Creating a FlowDocument
                                              from Code-behind
                                             Advanced FlowDocument
                                              content
                                             The RichTextBox control
                                           Misc. controls
                                             The Border control
                                             The Slider control
                                             The ProgressBar control
                                             The WebBrowser control
                                             The WindowsFormsHost
                                             control
                                           The TabControl
                                             Using the TabControl
                                             Tab positions
                                             Styling the TabItems
                                           List controls
                                             The ItemsControl
                                             The ListBox control
                                             The ComboBox control
ListView filtering
                                                                            Styles
                                                                             Introduction
                                                                             Using styles
                                                                             Triggers
                                                                             Multi triggers
                                                                             Trigger animations
                                                                            Misc.
                                                                             The DispatcherTimer
                                                 
         
Download
                                                  PDF!
                                           
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Visual Studio Express
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          WPF is, as already described, a combination of XAML (markup) and                   About WPF
          C#/VB.NET/any other .NET language. All of it can be edited in any text
                                                                                              What is WPF?
          editor, even Notepad included in Windows, and then compiled from the
                                                                                              WPF vs. WinForms
          command line. However, most developers prefer to use an IDE (Integrated
          Development Environment), since it makes everything, from writing code to
          designing the interface and compiling it all so much easier.
                                                                                             Getting started
          The preferred choice for a .NET/WPF IDE is Visual Studio, which costs a lot         Visual Studio Express
          quite a bit of money though. Luckily, Microsoft has decided to make it easy         Hello, WPF!
          and absolutely free for everyone to get started with .NET and WPF, so they
          have created a free version of Visual Studio, called Visual Studio Express.
          This version contains less functionality than the real Visual Studio, but it has
                                                                                             XAML
          everything that you need to get started learning WPF and make real
                                                                                              What is XAML?
          applications.
                                                                                              Basic XAML
          The latest version, as of writing this text, is Microsoft Visual Studio Express     Events in XAML
          2012. To create WPF applications, you should get the Windows Desktop
          edition, which can be downloaded for free from this website:
          http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-      A WPF application
          windows-desktop.                                                                    Introduction
                                                                                              The Window
          After downloading and installing, you can use this product for 30 days without
                                                                                              Working with App.xaml
          any registration. After that, you will need to register it on the above
                                                                                              Command-line parameters
          mentioned website, which is also completely free.
                                                                                              Resources
                                                                                              Handling exceptions
                Previous                                                      Next
                                                                                             Basic controls
          comments powered by Disqus
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                                    Panels
                                                     Introduction to WPF Panels
                                                     The Canvas
                                                     The WrapPanel
                                                     The StackPanel
                                                     The DockPanel
                                                     The Grid
                                                     The Grid - Rows & Columns
                                                     The Grid - Units
                                                     The Grid - Spanning
                                                     The Grid - GridSplitter
                                                     Using the Grid: A contact
                                                      form
                                                    Data binding
                                                     Introduction
                                                     Hello, bound world!
                                                     Using the DataContext
                                                     The UpdateSourceTrigger
                                                      property
                                                     Responding to changes
                                                     Value conversion with
                                                      IValueConverter
                                                     The StringFormat property
                                                     Debugging data bindings
                                                    Commands
                                                     Introduction
                                                     Using commands
                                                     Implementing custom
                                                      commands
                                                    Common interface
                                                    controls
                                                     The Menu control
                                                     The ContextMenu
                                                     The ToolBar control
                                                     The StatusBar control
                                                     The Ribbon Control
                                                      Introduction
                                                      The
                                                       FlowDocumentScrollViewer
                                                       control
                                                      The
                                                       FlowDocumentPageViewer
                                                       control
                                                      The FlowDocumentReader
                                                       control
                                                      Creating a FlowDocument
                                                       from Code-behind
                                                      Advanced FlowDocument
                                                       content
                                                      The RichTextBox control
                                                    Misc. controls
                                                      The Border control
                                                      The Slider control
                                                      The ProgressBar control
                                                      The WebBrowser control
                                                      The WindowsFormsHost
                                                      control
                                                    The TabControl
                                                      Using the TabControl
                                                      Tab positions
                                                      Styling the TabItems
                                                    List controls
                                                      The ItemsControl
                                                      The ListBox control
                                                      The ComboBox control
ListView filtering
                                                                                     Styles
                                                                                      Introduction
                                                                                      Using styles
                                                                                      Triggers
                                                                                      Multi triggers
                                                                                      Trigger animations
                                                                                     Misc.
                                                                                      The DispatcherTimer
                                                          
         
Download
                                                           PDF!
                                                    
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Hello, WPF!
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         The first and very classic example in pretty much any programming tutorial is       About WPF
         the "Hello, world!" example, but in this tutorial we'll go nuts and change that
                                                                                              What is WPF?
         into "Hello, WPF!" instead. The goal is simply to get this piece of text onto the
                                                                                              WPF vs. WinForms
         screen, to show you how easy it is to get started.
         The rest of this tutorial assumes that you have an IDE installed, preferably
         Visual Studio or Visual Studio Express (see the previous article for                Getting started
         instructions on how to get it). If you're using another product, you will have to    Visual Studio Express
         adapt the instructions to your product.                                              Hello, WPF!
         In Visual Studio, start by selecting New project from the File menu. On the
          left, you should have a tree of categories. This tutorial will focus on C#
                                                                                             XAML
          whenever code is involved, so you should select that from the list of
          templates, and since we'll be creating Windows applications, you should             What is XAML?
          select Windows from the tree. This will give you a list of possible Windows         Basic XAML
          application types to the right, where you should select a WPF Application. I        Events in XAML
          named my project "HelloWPF" in the Name text field. Make sure that the rest
          of the settings in the bottom part of the dialog are okay and then press the
          Ok button.                                                                         A WPF application
                                                                                              Introduction
         Your new project will have a couple of files, but we will focus on just one of
                                                                                              The Window
         them now: MainWindox.xaml. This is the applications primary window, the
                                                                                              Working with App.xaml
         one shown first when launching the application, unless you specifically
                                                                                              Command-line parameters
         change this. The XAML code found in it (XAML is discussed in details in
                                                                                              Resources
         another chapter of this tutorial) should look something like this:
                                                                                              Handling exceptions
<Window x:Class="WpfApplication1.MainWindow"
                                                                                             Basic controls
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            formatting
                       Title="MainWindow" Height="350" Width="525">                           The Label control
                  <Grid>                                                                      The TextBox control
                                                                                              The CheckBox control
         This is the base XAML that Visual Studio creates for our window, all parts of it
                                                                                             Panels
         explained in the chapters on XAML and "The Window". You can actually run             Introduction to WPF Panels
         the application now (select Debug -> Start debugging or press F5) to see the         The Canvas
         empty window that our application currently consists of, but now it's time to        The WrapPanel
         get our message on the screen. We'll do it by adding a TextBlock control to          The StackPanel
         the Grid panel, with our aforementioned message as the content:                      The DockPanel
                                                                                              The Grid
            <Window x:Class="WpfApplication1.MainWindow"                                      The Grid - Rows & Columns
                                                                                              The Grid - Units
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The Grid - Spanning
                                                                                              The Grid - GridSplitter
                                                                                              Using the Grid: A contact
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             form
                       Title="MainWindow" Height="350" Width="525">
                  <Grid>
            		<TextBlock HorizontalAlignment="Center"                                        Data binding
            VerticalAlignment="Center" FontSize="72">                                         Introduction
            			Hello, WPF!                                                                    Hello, bound world!
            		</TextBlock>                                                                    Using the DataContext
                  </Grid>                                                                     The UpdateSourceTrigger
            </Window>                                                                          property
                                                                                              Responding to changes
                                                                                              Value conversion with
         Try running the application now (select Debug -> Start debugging or press             IValueConverter
         F5) and see the beautiful result of your hard work - your first WPF                  The StringFormat property
         application:                                                                         Debugging data bindings
                                                                                             Commands
                                                                                              Introduction
                                                                                              Using commands
                                                                                              Implementing custom
                                                                                               commands
                                                                                             Common interface
                                                                                             controls
                                                                                              The Menu control
                                                                                              The ContextMenu
                                                                                              The ToolBar control
                                                                                              The StatusBar control
                                                                                              The Ribbon Control
         You will notice that we used three different attributes on the TextBlock to get a
         custom alignment (in the middle of the window), as well the FontSize
                                                                                             Rich Text controls
         property to get bigger text. All of these concepts will be treated in later
          articles.                                                                          Introduction
                                                                                             The
         Congratulations on making it this far. Now go read the rest of the tutorial and      FlowDocumentScrollViewer
         soon you will master WPF!                                                            control
                                                                                             The
                Previous                                                    Next              FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
         comments powered by Disqus
                                                                                              from Code-behind
                                                                                             Advanced FlowDocument
                                                                                              content
                                                                                             The RichTextBox control
                                                                                           Misc. controls
                                                                                             The Border control
                                                                                             The Slider control
                                                                                             The ProgressBar control
                                                                                             The WebBrowser control
                                                                                             The WindowsFormsHost
                                                                                             control
                                                                                           The TabControl
                                                                                             Using the TabControl
                                                                                             Tab positions
                                                                                             Styling the TabItems
                                                                                           List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
                                                                                             The ComboBox control
ListView filtering
                                                                           Styles
                                                                            Introduction
                                                                            Using styles
                                                                            Triggers
                                                                            Multi triggers
                                                                            Trigger animations
                                                                           Misc.
                                                                            The DispatcherTimer
                                                
         
Download
                                                 PDF!
                                          
Back to Top
Home Contact Us
                                                                                             Download as PDF
       What is XAML?
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         XAML, which stands for eXtensible Application Markup Language, is                   About WPF
         Microsoft's variant of XML for describing a GUI. In previous GUI frameworks,
                                                                                              What is WPF?
         like WinForms, a GUI was created in the same language that you would use
                                                                                              WPF vs. WinForms
         for interacting with the GUI, e.g. C# or VB.NET and usually maintained by the
         designer (e.g. Visual Studio), but with XAML, Microsoft is going another way.
         Much like with HTML, you are able to easily write and edit your GUI.
                                                                                             Getting started
         This is not really a XAML tutorial, but I will briefly tell you about how you use    Visual Studio Express
         it, because it's such an essential part of WPF. Whether you're creating a            Hello, WPF!
         Window or a Page, it will consist of a XAML document and a CodeBehind
         file, which together creates the Window/Page. The XAML file describes the
         interface with all its elements, while the CodeBehind handles all the events
                                                                                             XAML
         and has access to manipulate with the XAML controls.
                                                                                              What is XAML?
         In the next chapters, we will have a look at how XAML works and how you              Basic XAML
          use it to create your interface.                                                    Events in XAML
               Previous                                                       Next
                                                                                             A WPF application
                                                                                              Introduction
         comments powered by Disqus                                                           The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                            Panels
                                             Introduction to WPF Panels
                                             The Canvas
                                             The WrapPanel
                                             The StackPanel
                                             The DockPanel
                                             The Grid
                                             The Grid - Rows & Columns
                                             The Grid - Units
                                             The Grid - Spanning
                                             The Grid - GridSplitter
                                             Using the Grid: A contact
                                              form
                                            Data binding
                                             Introduction
                                             Hello, bound world!
                                             Using the DataContext
                                             The UpdateSourceTrigger
                                              property
                                             Responding to changes
                                             Value conversion with
                                              IValueConverter
                                             The StringFormat property
                                             Debugging data bindings
                                            Commands
                                             Introduction
                                             Using commands
                                             Implementing custom
                                              commands
                                            Common interface
                                            controls
                                             The Menu control
                                             The ContextMenu
                                             The ToolBar control
                                             The StatusBar control
                                             The Ribbon Control
                                              Introduction
                                              The
                                               FlowDocumentScrollViewer
                                               control
                                              The
                                               FlowDocumentPageViewer
                                               control
                                              The FlowDocumentReader
                                               control
                                              Creating a FlowDocument
                                               from Code-behind
                                              Advanced FlowDocument
                                               content
                                              The RichTextBox control
                                            Misc. controls
                                              The Border control
                                              The Slider control
                                              The ProgressBar control
                                              The WebBrowser control
                                              The WindowsFormsHost
                                              control
                                            The TabControl
                                              Using the TabControl
                                              Tab positions
                                              Styling the TabItems
                                            List controls
                                              The ItemsControl
                                              The ListBox control
                                              The ComboBox control
ListView filtering
                                                                             Styles
                                                                              Introduction
                                                                              Using styles
                                                                              Triggers
                                                                              Multi triggers
                                                                              Trigger animations
                                                                             Misc.
                                                                              The DispatcherTimer
                                                  
         
Download
                                                   PDF!
                                            
Back to Top
Home Contact Us
                                                                                         Download as PDF
       Basic XAML
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         In the previous chapter, we talked about what XAML is and what you use it       About WPF
          for, but how do you create a control in XAML? As you will see from the next
                                                                                          What is WPF?
          example, creating a control in XAML is as easy as writing it's name,
                                                                                          WPF vs. WinForms
          surrounded by angle brackets. For instance, a Button looks like this:
            <Button>
                                                                                         Getting started
                                                                                          Visual Studio Express
         XAML tags has to be ended, either by writing the end tag or by putting a
                                                                                          Hello, WPF!
         forward slash at the end of the start tag:
            <Button></Button>
                                                                                         XAML
                                                                                          What is XAML?
         Or
                                                                                          Basic XAML
                                                                                          Events in XAML
            <Button />
         A lot of controls allow you to put content between the start and end tags,      A WPF application
         which is then the content of the control. For instance, the Button control       Introduction
         allows you to specify the text shown on it between the start and end tags:       The Window
                                                                                          Working with App.xaml
            <Button>A button</Button>                                                     Command-line parameters
                                                                                          Resources
         HTML is not case-sensitive, but XAML is, because the control name has to         Handling exceptions
         correspond to a type in the .NET framework. The same goes for attribute
         names, which corresponds to the properties of the control. Here's a button
         where we define a couple of properties by adding attributes to the tag:         Basic controls
                                                                                          The TextBlock control
            <Button FontWeight="Bold" Content="A button" />                               The TextBlock control - Inline
                                                                                          formatting
                                                                                          The Label control
         We set the FontWeight property, giving us bold text, and then we set the
                                                                                          The TextBox control
         Content property, which is the same as writing the text between the start and
                                                                                          The CheckBox control
         end tag. However, all attributes of a control may also be defined like this,
            <Button>
                                                                                             Panels
                 <Button.FontWeight>Bold</Button.FontWeight>
                 <Button.Content>A button</Button.Content>                                    Introduction to WPF Panels
            </Button>                                                                         The Canvas
                                                                                              The WrapPanel
                                                                                              The StackPanel
         The result is exactly the same as above, so in this case, it's all about syntax
                                                                                              The DockPanel
         and nothing else. However, a lot of controls allow content other than text, for
                                                                                              The Grid
         instance other controls. Here's an example where we have text in different
                                                                                              The Grid - Rows & Columns
         colors on the same button by using several TextBlock controls inside of the
                                                                                              The Grid - Units
         Button:
                                                                                              The Grid - Spanning
                                                                                              The Grid - GridSplitter
            <Button>                                                                          Using the Grid: A contact
                 <Button.FontWeight>Bold</Button.FontWeight>
                                                                                               form
                 <Button.Content>
                       <WrapPanel>
                            <TextBlock Foreground="Blue">Multi</TextBlock>
                                                                                             Data binding
                            <TextBlock Foreground="Red">Color</TextBlock>
                            <TextBlock>Button</TextBlock>                                     Introduction
                       </WrapPanel>                                                           Hello, bound world!
                 </Button.Content>                                                            Using the DataContext
            </Button>                                                                         The UpdateSourceTrigger
                                                                                               property
                                                                                              Responding to changes
         The Content property only allows for a single child element, so we use a
                                                                                              Value conversion with
         WrapPanel to contain the differently colored blocks of text. Panels, like the
                                                                                               IValueConverter
         WrapPanel, plays an important role in WPF and we will discuss them in much
                                                                                              The StringFormat property
         more details later on - for now, just consider them as containers for other
                                                                                              Debugging data bindings
         controls. The exact same result can be accomplished with the following
         markup, which is simply another way of writing the same:
                                                                                             Commands
            <Button FontWeight="Bold">
                                                                                              Introduction
                 <WrapPanel>
                                                                                              Using commands
                       <TextBlock Foreground="Blue">Multi</TextBlock>
                                                                                              Implementing custom
                       <TextBlock Foreground="Red">Color</TextBlock>
                                                                                               commands
                       <TextBlock>Button</TextBlock>
                 </WrapPanel>
            </Button>
                                                                                             Common interface
                                                                                             controls
         Code vs. XAML
                                                                                              The Menu control
         Hopefully the above examples show you that XAML is pretty easy to write, but         The ContextMenu
         with a lot of different ways of doing it, and if you think that the above example    The ToolBar control
         is a lot of markup to get a button with text in different colors, then try           The StatusBar control
         comparing it to doing the exact same thing in C#:                                    The Ribbon Control
                                                                                             Introduction
            WrapPanel pnl = new WrapPanel();                                                 The
                                                                                              FlowDocumentScrollViewer
            TextBlock txt = new TextBlock();                                                  control
            txt.Text = "Multi";                                                              The
            txt.Foreground = Brushes.Blue;                                                    FlowDocumentPageViewer
            pnl.Children.Add(txt);                                                            control
                                                                                             The FlowDocumentReader
            txt = new TextBlock();                                                            control
            txt.Text = "Color";                                                              Creating a FlowDocument
            txt.Foreground = Brushes.Red;                                                     from Code-behind
            pnl.Children.Add(txt);                                                           Advanced FlowDocument
                                                                                              content
            txt = new TextBlock();                                                           The RichTextBox control
            txt.Text = "Button";
            pnl.Children.Add(txt);
                                                                                           Misc. controls
            btn.Content = pnl;
                                                                                             The Border control
            pnlMain.Children.Add(btn);
                                                                                             The Slider control
                                                                                             The ProgressBar control
         Of course the above example could be written less explicitly and using more         The WebBrowser control
         syntactical sugar, but I think the point still stands: XAML is pretty short and     The WindowsFormsHost
         concise for describing interfaces.                                                  control
               Previous                                                     Next
                                                                                           The TabControl
                                                                                             Using the TabControl
                                                                                             Tab positions
         comments powered by Disqus                                                          Styling the TabItems
                                                                                           List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
                                                                                             The ComboBox control
ListView filtering
                                                                          Styles
                                                                           Introduction
                                                                           Using styles
                                                                           Triggers
                                                                           Multi triggers
                                                                           Trigger animations
                                                                          Misc.
                                                                           The DispatcherTimer
                                               
         
Download
                                                PDF!
                                         
Back to Top
Home Contact Us
                                                                                         Download as PDF
       Events in XAML
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         Most modern UI frameworks are event driven and so is WPF. All of the            About WPF
         controls, including the Window (which also inherits the Control class)
                                                                                          What is WPF?
         exposes a range of events that you may subscribe to. You can subscribe to
                                                                                          WPF vs. WinForms
         these events, which means that your application will be notified when they
         occur and you may react to that.
         There are many types of events, but some of the most commonly used are          Getting started
         there to respond to the user's interaction with your application using the       Visual Studio Express
         mouse or the keyboard. On most controls you will find events like KeyDown,       Hello, WPF!
         KeyUp, MouseDown, MouseEnter, MouseLeave, MouseUp and several
         others.
                                                                                         XAML
         We will look more closely at how events work in WPF, since this is a complex
         topic, but for now, you need to know how to link a control event in XAML to a    What is XAML?
         piece of code in your Code-behind file. Have a look at this example:             Basic XAML
                                                                                          Events in XAML
<Window x:Class="WpfTutorialSamples.XAML.EventsSample"
            		
                 </Grid>                                                                 Basic controls
            </Window>
                                                                                          The TextBlock control
                                                                                          The TextBlock control - Inline
                                                                                          formatting
         Notice how we have subscribed to the MouseUp event of the Grid by writing a      The Label control
         method name. This method needs to be defined in code-behind, using the           The TextBox control
         correct event signature. In this case it should look like this:                  The CheckBox control
         Fortunately, Visual Studio can help us to generate a correct event handler for      Data binding
         an event. The easiest way to do this is to simply write the name of the event        Introduction
         in XAML and then let the IntelliSense of VS do the rest for you:                     Hello, bound world!
                                                                                              Using the DataContext
                                                                                              The UpdateSourceTrigger
                                                                                               property
                                                                                              Responding to changes
                                                                                              Value conversion with
                                                                                               IValueConverter
         When you select <New Event Handler> Visual Studio will generate an                   The StringFormat property
         appropriate event handler in your Code-behind file. It will be named <control        Debugging data bindings
         name>_<event name>, in our case pnlMainGrid_MouseDown. Right-click
         in the event name and select Navigate to Event Handler and VS will take
         you right to it.                                                                    Commands
                                                                                              Introduction
         Subscribing to an event from Code-behind                                             Using commands
                                                                                              Implementing custom
         The most common way to subscribe to events is explained above, but there
                                                                                               commands
          may be times where you want to subscribe to the event directly from Code-
         behind instead. This is done using the += C# syntax, where you add an event
          handler to event directly on the object. The full explanation of this belongs in
          a dedicated C# example, but for comparison, here's an example:                     Common interface
                                                                                             controls
            using System;                                                                     The Menu control
            using System.Windows;                                                             The ContextMenu
            using System.Windows.Input;                                                       The ToolBar control
                                                                                              The StatusBar control
                                                                                              The Ribbon Control
            namespace WpfTutorialSamples.XAML
            {
            	          public partial class EventsSample : Window                            Rich Text controls
            	{                                                                            Introduction
            		public EventsSample()                                                       The
            		{                                                                            FlowDocumentScrollViewer
            			InitializeComponent();                                                      control
            			pnlMainGrid.MouseUp += new                                                 The
            MouseButtonEventHandler(pnlMainGrid_MouseUp);                                  FlowDocumentPageViewer
            		}                                                                            control
                                                                                          The FlowDocumentReader
            		                     private void pnlMainGrid_MouseUp(object                 control
            sender, MouseButtonEventArgs e)                                               Creating a FlowDocument
            		{                                                                            from Code-behind
            			                              MessageBox.Show("You clicked me at           Advanced FlowDocument
             " + e.GetPosition(this).ToString());                                          content
            		}                                                                           The RichTextBox control
            	}
            }
                                                                                        Misc. controls
                                                                                          The Border control
         Once again, you need to know which delegate to use, and once again, Visual       The Slider control
         Studio can help you with this. As soon as you write:                             The ProgressBar control
                                                                                          The WebBrowser control
         pnlMainGrid.MouseDown +=
                                                                                          The WindowsFormsHost
         Visual Studio will offer its assistance:                                         control
                                                                                        The TabControl
                                                                                          Using the TabControl
                                                                                          Tab positions
         Simply press the [Tab] key twice to have Visual Studio generate the correct      Styling the TabItems
         event handler for you, right below the current method, ready for
         imeplentation. When you subscribe to the events like this, you don't need to
         do it in XAML.                                                                 List controls
                                                                                          The ItemsControl
                Previous                                                  Next            The ListBox control
                                                                                          The ComboBox control
ListView filtering
                                                                              Styles
                                                                               Introduction
                                                                               Using styles
                                                                               Triggers
                                                                               Multi triggers
                                                                               Trigger animations
                                                                              Misc.
                                                                               The DispatcherTimer
                                                   
         
Download
                                                    PDF!
                                             
Back to Top
Home Contact Us
                                                                                             Download as PDF
        A WPF Application - Introduction
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          In this tutorial, our primary focus will be on using WPF to create applications.   About WPF
           As you may know, .NET can be executed on all platforms which have a .NET
                                                                                              What is WPF?
           implementation, but the most common platform is still Microsoft Windows.
                                                                                              WPF vs. WinForms
           When we talk about Windows applications in this tutorial, it really just means
           an application that runs on Windows (or another .NET compatible platform)
           and not in a browser or remotely over the Internet.
                                                                                             Getting started
          A WPF application requires the .NET framework to run, just like any other           Visual Studio Express
          .NET application type. Fortunately, Microsoft has been including the .NET           Hello, WPF!
          framework on all versions of Windows since Vista, and they have been
          pushing out the framework on older versions through Windows Update. In
          other words, you can be pretty sure that most Windows users out there will
                                                                                             XAML
          be able to run your WPF application.
                                                                                              What is XAML?
          In the following chapters we will have a look at the structure and various          Basic XAML
           aspects of a WPF application.                                                      Events in XAML
                Previous                                                     Next
                                                                                             A WPF application
                                                                                              Introduction
          comments powered by Disqus                                                          The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                                               Panels
                                                                Introduction to WPF Panels
                                                                The Canvas
                                                                The WrapPanel
                                                                The StackPanel
                                                                The DockPanel
                                                                The Grid
                                                                The Grid - Rows & Columns
                                                                The Grid - Units
                                                                The Grid - Spanning
                                                                The Grid - GridSplitter
                                                                Using the Grid: A contact
                                                                 form
                                                               Data binding
                                                                Introduction
                                                                Hello, bound world!
                                                                Using the DataContext
                                                                The UpdateSourceTrigger
                                                                 property
                                                                Responding to changes
                                                                Value conversion with
                                                                 IValueConverter
                                                                The StringFormat property
                                                                Debugging data bindings
                                                               Commands
                                                                Introduction
                                                                Using commands
                                                                Implementing custom
                                                                 commands
                                                               Common interface
                                                               controls
                                                                The Menu control
                                                                The ContextMenu
                                                                The ToolBar control
                                                                The StatusBar control
                                                                The Ribbon Control
                                                                 Introduction
                                                                 The
                                                                  FlowDocumentScrollViewer
                                                                  control
                                                                 The
                                                                  FlowDocumentPageViewer
                                                                  control
                                                                 The FlowDocumentReader
                                                                  control
                                                                 Creating a FlowDocument
                                                                  from Code-behind
                                                                 Advanced FlowDocument
                                                                  content
                                                                 The RichTextBox control
                                                               Misc. controls
                                                                 The Border control
                                                                 The Slider control
                                                                 The ProgressBar control
                                                                 The WebBrowser control
                                                                 The WindowsFormsHost
                                                                 control
                                                               The TabControl
                                                                 Using the TabControl
                                                                 Tab positions
                                                                 Styling the TabItems
                                                               List controls
                                                                 The ItemsControl
                                                                 The ListBox control
                                                                 The ComboBox control
ListView filtering
                                                                                                Styles
                                                                                                 Introduction
                                                                                                 Using styles
                                                                                                 Triggers
                                                                                                 Multi triggers
                                                                                                 Trigger animations
                                                                                                Misc.
                                                                                                 The DispatcherTimer
                                                                     
         
Download
                                                                      PDF!
                                                               
Back to Top
Home Contact Us
                                                                                           Download as PDF
       The Window
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
         When creating a WPF application, the first thing you will meet is the Window      About WPF
         class. It serves as the root of a window and provides you with the standard
                                                                                            What is WPF?
         border, title bar and maximize, minimize and close buttons. A WPF window is
                                                                                            WPF vs. WinForms
         a combination of a XAML (.xaml) file, where the <Window> element is the
         root, and a CodeBehind (.cs) file. If you're using Visual Studio (Express) and
         you create a new WPF application, it will create a default window for you,
         which will look something like this:                                              Getting started
                                                                                            Visual Studio Express
            <Window x:Class="WpfApplication1.Window1"                                       Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           XAML
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     What is XAML?
                 Title="Window1" Height="300" Width="300">                                  Basic XAML
                 <Grid>                                                                     Events in XAML
                 </Grid>
            </Window>
                                                                                           A WPF application
                                                                                            Introduction
                                                                                            The Window
         
The x:class attribute tells the XAML file which class to use, in this case
                                                                                            Working with App.xaml
          Window1, which Visual Studio has created for us as well. You will find it in
                                                                                            Command-line parameters
          the project tree in VS, as a child node of the XAML file. By default, it looks
                                                                                            Resources
          something like this:
                                                                                            Handling exceptions
            using System;
            using System.Windows;
                                                                                           Basic controls
            using System.Windows.Controls;
                                                                                            The TextBlock control
            //…more using statements
                                                                                            The TextBlock control - Inline
                                                                                            formatting
            namespace WpfApplication1
                                                                                            The Label control
            {
                                                                                            The TextBox control
                 /// <summary>
                                                                                            The CheckBox control
                 /// Interaction logic for Window1.xaml
          and each of them will automatically adjust the window size horizontally,            Introduction
          vertically or both.                                                                 The
                                                                                               FlowDocumentScrollViewer
         Topmost - The default is false, but if set to true, your Window will stay on top      control
         of other windows unless minimized. Only useful for special situations.               The
                                                                                               FlowDocumentPageViewer
         WindowStartupLocation - Controls the initial position of your window. The
                                                                                               control
         default is Manual, which means that the window will be initially positioned
                                                                                              The FlowDocumentReader
         according to the Top and Left properties of your window. Other options are
                                                                                               control
         CenterOwner, which will position the window in the center of it's owner
                                                                                              Creating a FlowDocument
         window, and CenterScreen, which will position the window in the center of
                                                                                               from Code-behind
         the screen.
                                                                                              Advanced FlowDocument
         WindowState - Controls the initial window state. It can be either Normal,             content
         Maximized or Minimized. The default is Normal, which is what you should              The RichTextBox control
         use unless you want your window to start either maximized or minimized.
         There are lots of other attributes though, so have a look for yourself and then    Misc. controls
         move on to the next chapter.
                                                                                              The Border control
                                                                                              The Slider control
               Previous                                                     Next              The ProgressBar control
                                                                                              The WebBrowser control
                                                                                              The WindowsFormsHost
                                                                                              control
         comments powered by Disqus
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
                                                                                            List controls
                                                                                              The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
ListView filtering
                                                                          Styles
                                                                           Introduction
                                                                           Using styles
                                                                           Triggers
                                                                           Multi triggers
                                                                           Trigger animations
                                                                          Misc.
                                                                           The DispatcherTimer
                                               
         
Download
                                                PDF!
                                         
Back to Top
Home Contact Us
                                                                                              Download as PDF
       Working with App.xaml
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
         App.xaml is the declarative starting point of your application. Visual Studio will   About WPF
         automatically create it for you when you start a new WPF application,
                                                                                               What is WPF?
         including a Code-behind file called App.xaml.cs. They work much like for a
                                                                                               WPF vs. WinForms
         Window, where the two files are partial classes, working together to allow you
         to work in both markup (XAML) and Code-behind.
         App.xaml.cs extends the Application class, which is a central class in a WPF         Getting started
         Windows application. .NET will go to this class for starting instructions and         Visual Studio Express
         then start the desired Window or Page from there. This is also the place to           Hello, WPF!
         subscribe to important application events, like application start, unhandled
         exceptions and so on. More about that later.
                                                                                              XAML
         One of the most commonly used features of the App.xaml file is to define
         global resources that may be used and accessed from all over an application,          What is XAML?
         for instance global styles. This will be discussed in detail later on.                Basic XAML
                                                                                               Events in XAML
         App.xaml structure
         When creating a new application, the automatically generated App.xaml will
                                                                                              A WPF application
         look something like this:
                                                                                               Introduction
                                                                                               The Window
            <Application x:Class="WpfTutorialSamples.App"
                                                                                               Working with App.xaml
                                                                                               Command-line parameters
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                               Resources
                                                                                               Handling exceptions
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                              StartupUri="MainWindow.xaml">
                 <Application.Resources>
                                                                                              Basic controls
                                                                                               The TextBlock control
                 </Application.Resources>                                                      The TextBlock control - Inline
            </Application>                                                                     formatting
                                                                                               The Label control
                                                                                               The TextBox control
         The main thing to notice here is the StartupUri property. This is actually the        The CheckBox control
          part that instructs which Window or Page to start up when the application is      The RadioButton control
          launched. In this case, MainWindow.xaml will be started, but if you would like    The PasswordBox control
          to use another window as the starting point, you can simply change this.
         In some situations, you want more control over how and when the first             Panels
          window is displayed. In that case, you can remove the StartupUri property         Introduction to WPF Panels
          and value and then do it all from Code-Behind instead. This will be               The Canvas
          demonstrated below.                                                               The WrapPanel
                                                                                            The StackPanel
         App.xaml.cs structure                                                              The DockPanel
         The matching App.xaml.cs will usually look like this for a new project:            The Grid
                                                                                            The Grid - Rows & Columns
                                                                                            The Grid - Units
            using System;
                                                                                            The Grid - Spanning
            using System.Collections.Generic;
                                                                                            The Grid - GridSplitter
            using System.Windows;
                                                                                            Using the Grid: A contact
                                                                                             form
            namespace WpfTutorialSamples
            {
            	          public partial class App : Application
            	{                                                                             Data binding
                                                                                            Introduction
            	}                                                                              Hello, bound world!
            }                                                                               Using the DataContext
                                                                                            The UpdateSourceTrigger
                                                                                             property
         You will see how this class extends the Application class, allowing us to do
                                                                                            Responding to changes
         stuff on the application level. For instance, you can subscribe to the Startup
                                                                                            Value conversion with
         event, where you can manually create your starting window. Here's an
                                                                                             IValueConverter
         example:
                                                                                            The StringFormat property
                                                                                            Debugging data bindings
            <Application x:Class="WpfTutorialSamples.App"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Commands
                                                                                            Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          Using commands
            			 Startup="Application_Startup">                                              Implementing custom
                 <Application.Resources></Application.Resources>                             commands
            </Application>
                                                                                           Common interface
         Notice how the StartupUri has been replaced with a subscription to the            controls
         Startup event (subscribing to events through XAML is explained in another          The Menu control
         chapter). In Code-Behind, you can use the event like this:                         The ContextMenu
                                                                                            The ToolBar control
            using System;                                                                   The StatusBar control
            using System.Collections.Generic;                                               The Ribbon Control
            using System.Windows;
            {                                                                                   Introduction
            	          public partial class App : Application                                   The
            	{                                                                                   FlowDocumentScrollViewer
                                                                                                 control
            		                     private void Application_Startup(object                      The
            sender, StartupEventArgs e)                                                          FlowDocumentPageViewer
            		{                                                                                  control
            			                              // Create the startup window                       The FlowDocumentReader
            			                              MainWindow wnd = new MainWindow();                  control
            			                              // Do stuff here, e.g. to the                      Creating a FlowDocument
            window                                                                               from Code-behind
            			                              wnd.Title = "Something else";                      Advanced FlowDocument
            			                              // Show the window                                  content
            			wnd.Show();                                                                      The RichTextBox control
            		}
            	}
            }
                                                                                              Misc. controls
                                                                                                The Border control
         The cool thing in this example, compared to just using the StartupUri property,
                                                                                                The Slider control
         is that we get to manipulate the startup window before showing it. In this, we
                                                                                                The ProgressBar control
         change the title of it, which is not terribly useful, but you could also subscribe
                                                                                                The WebBrowser control
         to events or perhaps show a splash screen. When you have all the control,
                                                                                                The WindowsFormsHost
         there are many possibilities. We will look deeper into several of them in the
                                                                                                control
         next articles of this tutorial.
                                                                                              List controls
                                                                                                The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
ListView filtering
                                                                                     Styles
                                                                                      Introduction
                                                                                      Using styles
                                                                                      Triggers
                                                                                      Multi triggers
                                                                                      Trigger animations
                                                                                     Misc.
                                                                                      The DispatcherTimer
                                                          
         
Download
                                                           PDF!
                                                    
Back to Top
Home Contact Us
                                                                                         Download as PDF
       Command-line parameters in WPF
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         Command-line parameters are a technique where you can pass a set of             About WPF
         parameters to an application that you wish to start, to somehow influence it.
                                                                                          What is WPF?
         The most common example is to make the application open with a specific
                                                                                          WPF vs. WinForms
         file, e.g. in an editor. You can try this yourself with the built-in Notepad
         application of Windows, by running (select Run from the Start menu or press
         [WindowsKey-R]):
                                                                                         Getting started
         notepad.exe c:\Windows\win.ini                                                   Visual Studio Express
                                                                                          Hello, WPF!
         This will open Notepad with the win.ini file opened (you may have to adjust
         the path to match your system). Notepad simply looks for one or several
         parameters and then uses them and your application can do the same!
                                                                                         XAML
         Command-line parameters are passed to your WPF application through the           What is XAML?
         Startup event, which we subscribed to in the App.xaml article. We will do the    Basic XAML
         same in this example, and then use the value passed on to through the            Events in XAML
         method arguments. First, the App.xaml file:
                                                                                         Basic controls
                                                                                          The TextBlock control
         All we do here is to subscribe to the Startup event, replacing the StartupUri
                                                                                          The TextBlock control - Inline
         property. The event is then implemented in App.xaml.cs:
                                                                                          formatting
                                                                                          The Label control
            using System;                                                                 The TextBox control
            using System.Collections.Generic;                                             The CheckBox control
            using System.Windows;
         The StartupEventArgs is what we use here. It's passed into the Application
                                                                                          Data binding
         Startup event, with the name e. It has the property Args, which is an array of
         strings. Command-line parameters are separated by spaces, unless the              Introduction
         space is inside a quoted string.                                                  Hello, bound world!
                                                                                           Using the DataContext
         Testing the command-line parameter                                                The UpdateSourceTrigger
                                                                                            property
         If you run the above example, nothing will happen, because no command-line        Responding to changes
          parameters have been specified. Fortunately, Visual Studio makes it easy to      Value conversion with
          test this in your application. From the Project menu select "[Project name]       IValueConverter
          properties" and then go to the Debug tab, where you can define a                 The StringFormat property
          command-line parameter. It should look something like this:                      Debugging data bindings
                                                                                          Commands
                                                                                           Introduction
                                                                                           Using commands
                                                                                           Implementing custom
                                                                                            commands
                                                                                          Common interface
                                                                                          controls
                                                                                           The Menu control
                                                                                           The ContextMenu
         Try running the application and you will see it respond to your parameter. Of
                                                                                           The ToolBar control
         course, the message isn't terribly useful. Instead you might want to either
                                                                                           The StatusBar control
         pass it to the constructor of your main window or call a public open method
                                                                                           The Ribbon Control
         on it, like this:
            using System.Collections.Generic;
                                                                                               Introduction
            using System.Windows;
                                                                                               The
                                                                                                FlowDocumentScrollViewer
            namespace WpfTutorialSamples
                                                                                                control
            {
                                                                                               The
            	          public partial class App : Application
                                                                                                FlowDocumentPageViewer
            	{
                                                                                                control
                                                                                               The FlowDocumentReader
            		                     private void Application_Startup(object
                                                                                                control
            sender, StartupEventArgs e)
                                                                                               Creating a FlowDocument
            		{
                                                                                                from Code-behind
            			                             MainWindow wnd = new MainWindow();
                                                                                               Advanced FlowDocument
            			                             // The OpenFile() method is just
                                                                                                content
            an example of what you could do with the
                                                                                               The RichTextBox control
            			                             // parameter. The method should be
                declared on your MainWindow class, where
            			                             // you could use a range of
            methods to process the passed file path                                          Misc. controls
            			if(e.Args.Length == 1)                                                          The Border control
            				wnd.OpenFile(e.Args[0]);                                                       The Slider control
            			wnd.Show();                                                                     The ProgressBar control
            		}                                                                                The WebBrowser control
            	}                                                                                 The WindowsFormsHost
            }                                                                                  control
         Command-line possibilities
                                                                                             The TabControl
         In this example, we test if there is exactly one argument and if so, we use it as     Using the TabControl
          a filename. In a real world example, you might collect several arguments and         Tab positions
          even use them for options, e.g. toggling a certain feature on or off. You would      Styling the TabItems
          do that by looping through the entire list of arguments passed while collecting
          the information you need to proceed, but that's beyond the scope of this
          article.
                                                                                             List controls
                                                                                               The ItemsControl
                 Previous                                                   Next
                                                                                               The ListBox control
                                                                                               The ComboBox control
ListView filtering
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                                   
         
Download
                                                                    PDF!
                                                             
Back to Top
Home Contact Us
                                                                                                    Download as PDF
        Resources
                                                                                                           Download this entire
                                                                                                           tutorial as PDF right
                                                                                                    now!
          
WPF introduces a very handy concept: The ability to store data as a                      About WPF
           resource, either locally for a control, locally for the entire window or globally
                                                                                                     What is WPF?
           for
the entire application. The data can be pretty much whatever you want,
                                                                                                     WPF vs. WinForms
           from actual information to a hierarchy of WPF controls. This allows you to
           place
data in one place and then use it from or several other places, which is
           very useful.
                                                                                                    Getting started
          
The concept is used a lot for styles and templates, which we'll discuss later             Visual Studio Express
           on in this tutorial, but as it will be illustrated in this chapter, you can
use it for    Hello, WPF!
           many other things as well. Allow me to demonstrate it with a simple example:
            <Window                                                                                 XAML
            x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"
                                                                                                     What is XAML?
                                                                                                     Basic XAML
                                                                                                     Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                    A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:sys="clr-namespace:System;assembly=mscorlib"                            Introduction
                       Title="ResourceSample" Height="150" Width="350">                              The Window
                  <Window.Resources>                                                                 Working with App.xaml
                       <sys:String x:Key="strHelloWorld">Hello, world!                               Command-line parameters
            </sys:String>                                                                            Resources
                  </Window.Resources>                                                                Handling exceptions
                  <StackPanel Margin="10">
                       <TextBlock Text="{StaticResource strHelloWorld}"
            FontSize="56" />                                                                        Basic controls
                       <TextBlock>Just another "<TextBlock Text="                                    The TextBlock control
            {StaticResource strHelloWorld}" />" example, but with                                    The TextBlock control - Inline
            resources!</TextBlock>                                                                   formatting
                  </StackPanel>                                                                      The Label control
            </Window>                                                                                The TextBox control
                                                                                                     The CheckBox control
                                                                                                Panels
                                                                                                 Introduction to WPF Panels
                                                                                                 The Canvas
                                                                                                 The WrapPanel
                                                                                                 The StackPanel
          
Resources are given a key, using the x:Key attribute, which allows you to             The DockPanel
           reference it from other parts of the application by using this key, in                The Grid
          
combination with the StaticResource markup extension. In this example, I              The Grid - Rows & Columns
           just store a simple string, which I then use from two different TextBlock             The Grid - Units
           controls.                                                                             The Grid - Spanning
                                                                                                 The Grid - GridSplitter
          
StaticResource vs. DynamicResource                                                    Using the Grid: A contact
                                                                                                  form
          
In the examples so far, I have used the StaticResource markup extension to
           reference a resource. However, an alternative exists, in form of the
           DynamicResource.
                                                                                                Data binding
          
The main difference is that a static resource is resolved only once, which is at      Introduction
           the point where the XAML is loaded. If the resource is then changed later
on,         Hello, bound world!
           this change will not be reflected where you have used the StaticResource.             Using the DataContext
                                                                                                 The UpdateSourceTrigger
          
A DynamicResource on the other hand, is resolved once it's actually needed,            property
           and then again if the resource changes. Think of it as binding to a static
value      Responding to changes
           vs. binding to a function that monitors this value and sends it to you each           Value conversion with
           time it's changed - it's not exactly how it works, but it should give you
a better     IValueConverter
           idea of when to use what. Dynamic resources also allows you to use                    The StringFormat property
           resources which are not even there during design time, e.g. if you add them           Debugging data bindings
           from Code-behind during the startup of the application.
          
More resource types                                                                  Commands
          
Sharing a simple string was easy, but you can do much more. In the next               Introduction
           example, I'll also store a complete array of strings, along with a gradient           Using commands
           brush
to be used for the background. This should give you a pretty good idea          Implementing custom
           of just how much you can do with resources:                                            commands
            <Window
            x:Class="WpfTutorialSamples.WPF_Application.ExtendedResource                        Common interface
                                                                                                controls
                                                                                                 The Menu control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                         The ContextMenu
                                                                                                 The ToolBar control
                                                                                                 The StatusBar control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                               The Ribbon Control
                       xmlns:sys="clr-namespace:System;assembly=mscorlib"
                       Title="ExtendedResourceSample" Height="160"
            Width="300"                                                                         Rich Text controls
                       Background="{DynamicResource
                                                                                              Introduction
            WindowBackgroundBrush}">
                                                                                              The
                  <Window.Resources>
                                                                                               FlowDocumentScrollViewer
                       <sys:String x:Key="ComboBoxTitle">Items:
                                                                                               control
            </sys:String>
                                                                                              The
                                                                                               FlowDocumentPageViewer
                       <x:Array x:Key="ComboBoxItems" Type="sys:String">
                                                                                               control
                             <sys:String>Item #1</sys:String>
                                                                                              The FlowDocumentReader
                             <sys:String>Item #2</sys:String>
                                                                                               control
                             <sys:String>Item #3</sys:String>
                                                                                              Creating a FlowDocument
                       </x:Array>
                                                                                               from Code-behind
                                                                                              Advanced FlowDocument
                       <LinearGradientBrush
                                                                                               content
            x:Key="WindowBackgroundBrush">
                                                                                              The RichTextBox control
                             <GradientStop Offset="0" Color="Silver"/>
                             <GradientStop Offset="1" Color="Gray"/>
                       </LinearGradientBrush>
                  </Window.Resources>                                                       Misc. controls
                  <StackPanel Margin="10">                                                    The Border control
                       <Label Content="{StaticResource ComboBoxTitle}" />                     The Slider control
                       <ComboBox ItemsSource="{StaticResource                                 The ProgressBar control
            ComboBoxItems}" />                                                                The WebBrowser control
                  </StackPanel>                                                               The WindowsFormsHost
            </Window>                                                                         control
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
                                                                                            List controls
                                                                                              The ItemsControl
                                                                                              The ListBox control
          
This time, we've added a couple of extra resources, so that our Window now
                                                                                              The ComboBox control
           contains a simple string, an array of strings and a LinearGradientBrush. The
           string is used for the label, the array of strings is used as items for the
           ComboBox control and the gradient brush is used as background for the
                                                                                            The ListView control
           entire
window. So, as you can see, pretty much anything can be stored as a
           resource.                                                                          Introduction
                                                                                              A simple ListView
          
Local and application wide resources                                               ListView, data binding and
                                                                                               ItemTemplate
          
For now, we have stored resources on a window-level, which means that you          ListView with a GridView
           can access them from all over the window.                                          How-to: Left aligned column
                                                                                               names
          
If you only need a given resource for a specific control, you can make it more
                                                                                              ListView grouping
           local by adding it to this specific control, instead of the window. It works
                                                                                              ListView sorting
           exactly the same way, the only difference being that you can now only
                                                                                              How-to: ListView with
           access from inside the scope of the control where you put it:
                                                                                               column sorting
                                                                                               ListView filtering
            <StackPanel Margin="10">
                  <StackPanel.Resources>
                       <sys:String x:Key="ComboBoxTitle">Items:
                                                                                              The TreeView control
            </sys:String>
                                                                                               Introduction
                  </StackPanel.Resources>
                                                                                               A simple TreeView
                  <Label Content="{StaticResource ComboBoxTitle}" />
                                                                                               TreeView, data binding and
            </StackPanel>
                                                                                                multiple templates
                                                                                               Handling
          
In this case, we add the resource to the StackPanel and then use it from its         Selection/Expansion state
           child control, the Label. Other controls inside of the StackPanel could have        Lazy loading TreeView items
           used it as well, just like children of these child controls would have been able
           to access it. Controls outside of this particular StackPanel wouldn't have
           access to it, though.
                                                                                              The DataGrid control
          
If you need the ability to access the resource from several windows, this is        Introduction
           possible as well. The App.xaml file can contain resources
just like the             Custom columns
           window and any kind of WPF control, and when you store them in App.xaml,            Details row
           they are globally accessible in all of windows and user controls of
the project.
           It works exactly the same way as when storing and using from a Window:
                                                                                              Styles
            <Application x:Class="WpfTutorialSamples.App"                                      Introduction
                                                                                               Using styles
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                              xmlns:sys="clr-
            namespace:System;assembly=mscorlib"
                                                                                              Misc.
                              StartupUri="WPF
                                                                                               The DispatcherTimer
            application/ExtendedResourceSample.xaml">
                  <Application.Resources>
                       <sys:String x:Key="ComboBoxTitle">Items:
            </sys:String>                                                                     Audio & Video
                  </Application.Resources>                                                     Playing audio
            </Application>                                                                     Playing video
                                                                                               How-to: Complete media
                                                                                               player
          
Using it is also the same - WPF will automatically go up the scope, from the        Speech synthesis
           local control to the window and then to App.xaml, to find a given resource:         Speech recognition
          
Resources from Code-behind
          
So far, we've accessed all of our resources directly from XAML, using a
           markup extension. However, you can of course access your resources from
           Code-behind
as well, which can be useful in several situations. In the
           previous example, we saw how we could store resources in several different
           places, so in this
example, we'll be accessing three different resources from
App.xaml:
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                              xmlns:sys="clr-
            namespace:System;assembly=mscorlib"
                              StartupUri="WPF
            application/ResourcesFromCodeBehindSample.xaml">
                  <Application.Resources>
                       <sys:String x:Key="strApp">Hello, Application
            world!</sys:String>
                  </Application.Resources>
            </Application>
Window:
            <Window
            x:Class="WpfTutorialSamples.WPF_Application.ResourcesFromCod
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:sys="clr-namespace:System;assembly=mscorlib"
                       Title="ResourcesFromCodeBehindSample" Height="175"
              Width="250">
                  <Window.Resources>
                       <sys:String x:Key="strWindow">Hello, Window world!
            </sys:String>
                  </Window.Resources>
                  <DockPanel Margin="10" Name="pnlMain">
                       <DockPanel.Resources>
                             <sys:String x:Key="strPanel">Hello, Panel
            world!</sys:String>
                       </DockPanel.Resources>
                       <WrapPanel DockPanel.Dock="Top"
            HorizontalAlignment="Center" Margin="10">
                             <Button Name="btnClickMe"
            Click="btnClickMe_Click">Click me!</Button>
                       </WrapPanel>
                  </DockPanel>
            </Window>
Code-behind:
            using System;
            using System.Windows;
            namespace WpfTutorialSamples.WPF_Application
            {
            	          public partial class ResourcesFromCodeBehindSample
              : Window
            	{
            		public ResourcesFromCodeBehindSample()
            		{
            			InitializeComponent();
            		}
            			
            lbResult.Items.Add(this.FindResource("strWindow").ToString()
            			
            lbResult.Items.Add(Application.Current.FindResource("strApp"
            		}
            	}
            }
          
So, as you can see, we store three different "Hello, world!" messages: One in
           App.xaml, one inside the window, and one locally for the main panel. The
           interface consists of a button and a ListBox.
          
In Code-behind, we handle the click event of the button, in which we add
           each of the text strings to the ListBox, as seen on the screenshot. We use
           the FindResource() method, which will return the resource as an object (if
           found), and then we turn it into the string that we know it is by
using the
           ToString() method.
          
Notice how we use the FindResource() method on different scopes - first on
           the panel, then on the window and then on the current Application object. It
           makes sense to look for the resource where we know it is, but as already
           mentioned, if a resource is not found, the
search progresses up the
           hierarchy, so in principal, we could have used the FindResource() method on
           the panel in all three cases, since it would have
continued up to the window
           and later on up to the application level, if not found.
          
The same is not true the other way around - the search doesn't navigate
           down the tree, so you can't start looking for a resource on the application
           level,
if it has been defined locally for the control or for the window.
Previous Next
                                                                  
         
Download
                                                                   PDF!
                                                                                             
Back to Top
Home Contact Us
                                                                                            Download as PDF
        Handling exceptions in WPF
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
If you're familiar with C# or any of the other .NET languages that you may        About WPF
          use with WPF, then exception handling should not be new to you: Whenever
                                                                                             What is WPF?
          you
have a piece of code that are likely to throw an exception, then you
                                                                                             WPF vs. WinForms
          should wrap it in a try-catch block to handle the exception gracefully. For
          instance,
consider this example:
                                                                                            Getting started
            private void Button_Click(object sender, RoutedEventArgs
            e)                                                                               Visual Studio Express
            {                                                                                Hello, WPF!
            	          string s = null;
            	s.Trim();
            }                                                                               XAML
                                                                                             What is XAML?
         
Obviously it will go wrong, since I try to perform the Trim() method on a          Basic XAML
          variable that's currently null. If you don't handle the exception, your            Events in XAML
          application will crash and Windows will have to deal with the problem. As you
          can see, that isn't very user friendly:
                                                                                            A WPF application
                                                                                             Introduction
                                                                                             The Window
                                                                                             Working with App.xaml
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
                                                                                            Basic controls
                                                                                             The TextBlock control
                                                                                             The TextBlock control - Inline
                                                                                             formatting
                                                                                             The Label control
         
In this case, the user would be forced to close your application, due to such a
                                                                                             The TextBox control
          simple and easily avoided error. So, if you know that things might go
wrong,
                                                                                             The CheckBox control
          then you should use a try-catch block, like this:
         
However, sometimes even the simplest code can throw an exception, and
          instead of wrapping every single line of code with a try- catch block, WPF lets
                                                                                            Data binding
          you
handle all unhandled exceptions globally. This is done through the
          DispatcherUnhandledException event on the Application class. If                    Introduction
          subscribed to, WPF will call the subscribing method once an exception is           Hello, bound world!
          thrown which is not handled in your own code. Here's a complete example,           Using the DataContext
          based on
the stuff we just went through:                                           The UpdateSourceTrigger
                                                                                              property
                                                                                             Responding to changes
            <Window
                                                                                             Value conversion with
            x:Class="WpfTutorialSamples.WPF_Application.ExceptionHandlin
                                                                                              IValueConverter
                                                                                             The StringFormat property
                                                                                             Debugging data bindings
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          Commands
                       Title="ExceptionHandlingSample" Height="200"                          Introduction
            Width="200">                                                                     Using commands
                  <Grid>                                                                     Implementing custom
                       <Button HorizontalAlignment="Center"                                   commands
            VerticalAlignment="Center" Click="Button_Click">
                             Do something bad!
                       </Button>                                                            Common interface
                  </Grid>                                                                   controls
            </Window>
                                                                                             The Menu control
                                                                                             The ContextMenu
                                                                                             The ToolBar control
            using System;                                                                    The StatusBar control
            using System.Windows;                                                            The Ribbon Control
            namespace WpfTutorialSamples.WPF_Application
            {                                                                               Rich Text controls
            <Application x:Class="WpfTutorialSamples.App"
                                                                                              List controls
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                        The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
                                                                                            Misc.
                                                                                             The DispatcherTimer
         
Summary
         
Exception handling is a very important part of any application and fortunately,
          WPF and .NET makes it very easy to handle exceptions both locally and
          globally. You should handle exceptions locally when it makes sense and only
          use the global handling as a fallback mechanism, since local handling allows
          you to be more specific and deal with the problem in a more specialized way.
Previous Next
                                                               
         
Download
                                                                PDF!
                                                                                          
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The TextBlock control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          TextBlock is not a control, per se, since it doesn't inherit from the Control      About WPF
          class, but it's used much like any other control in the WPF framework, so
                                                                                              What is WPF?
          we'll call it a control to keep things simple.
                                                                                              WPF vs. WinForms
          The TextBlock control is one of the most fundamental controls in WPF, yet
          it's very useful. It allows you to put text on the screen, much like a Label
          control does, but in a simpler and less resource demanding way. A common           Getting started
          understanding is that a Label is for short, one-line texts (but may include e.g.    Visual Studio Express
          an image), while the TextBlock works very well for multiline strings as well,       Hello, WPF!
          but can only contain text (strings). Both the Label and the TextBlock offers
          their own unique advantages, so what you should use very much depends on
          the situation.
                                                                                             XAML
          We already used a TextBlock control in the "Hello, WPF!" article, but for now,      What is XAML?
          let's have a look at the TextBlock in its simplest form:                            Basic XAML
                                                                                              Events in XAML
            <Window
            x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
                                                                                             A WPF application
                                                                                              Introduction
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Resources
                        Title="TextBlockSample" Height="100" Width="200">                     Handling exceptions
                  <Grid>
            		                     <TextBlock>This is a TextBlock</TextBlock>
                  </Grid>                                                                    Basic controls
            </Window>
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          That's as simple as it comes and if you have read the previous chapters of
          this tutorial, then there should be nothing new here. The text between the
                                                                                            Panels
          TextBlock is simply a shortcut for setting the Text property of the TextBlock.
                                                                                             Introduction to WPF Panels
          For the next example, let's try a longer text to show how the TextBlock deals      The Canvas
          with that. I've also added a bit of margin, to make it look just a bit better:     The WrapPanel
                                                                                             The StackPanel
                                                                                             The DockPanel
            <Window
                                                                                             The Grid
            x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
                                                                                             The Grid - Rows & Columns
                                                                                             The Grid - Units
                                                                                             The Grid - Spanning
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             The Grid - GridSplitter
                                                                                             Using the Grid: A contact
                                                                                              form
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="TextBlockSample" Height="100" Width="200">
                  <Grid>
            		                     <TextBlock Margin="10">This is a TextBlock               Data binding
              control and it comes with a very long text</TextBlock>                         Introduction
                  </Grid>                                                                    Hello, bound world!
            </Window>                                                                        Using the DataContext
                                                                                             The UpdateSourceTrigger
                                                                                              property
                                                                                             Responding to changes
                                                                                             Value conversion with
                                                                                              IValueConverter
                                                                                             The StringFormat property
                                                                                             Debugging data bindings
                                                                                            Common interface
            <Window
                                                                                            controls
            x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
                                                                                             The Menu control
                                                                                             The ContextMenu
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     The ToolBar control
                                                                                             The StatusBar control
                                                                                             The Ribbon Control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="TextBlockSample" Height="200" Width="250">
                  <StackPanel>                                                                Rich Text controls
            		                     <TextBlock Margin="10" Foreground="Red">                     Introduction
            			                               This is a TextBlock                               The
            control<LineBreak />                                                                 FlowDocumentScrollViewer
            			                               with multiple lines of text.                       control
            		</TextBlock>		                                                                    The
            		<TextBlock Margin="10"                                                             FlowDocumentPageViewer
            TextTrimming="CharacterEllipsis" Foreground="Green">                                 control
            			                               This is a TextBlock control with                  The FlowDocumentReader
            text that may not be rendered completely, which will be                              control
            indicated with an ellipsis.                                                         Creating a FlowDocument
            		</TextBlock>                                                                       from Code-behind
            		                     <TextBlock Margin="10" TextWrapping="Wrap"                   Advanced FlowDocument
              Foreground="Blue">                                                                 content
            			                               This is a TextBlock control with                  The RichTextBox control
            automatically wrapped text, using the TextWrapping
            property.
            		</TextBlock>                                                                    Misc. controls
            	</StackPanel>
                                                                                                The Border control
            </Window>
                                                                                                The Slider control
                                                                                                The ProgressBar control
                                                                                                The WebBrowser control
                                                                                                The WindowsFormsHost
                                                                                                control
                                                                                              The TabControl
                                                                                                Using the TabControl
                                                                                                Tab positions
                                                                                                Styling the TabItems
                                                                                              List controls
          So, we have three TextBlock controls, each with a different color (using the
          Foreground property) for an easier overview. They all handle the fact that            The ItemsControl
          their text content is too long in different ways:                                     The ListBox control
                                                                                                The ComboBox control
          The red TextBlock uses a LineBreak tag to manually break the line at a
          designated location. This gives you absolute control over where you want the
          text to break onto a new line, but it's not very flexible for most situations. If   The ListView control
          the user makes the window bigger, the text will still wrap at the same
                                                                                                Introduction
          position, even though there may now be room enough to fit the entire text
                                                                                                A simple ListView
          onto one line.
                                                                                                ListView, data binding and
          The green TextBlock uses the TextTrimming property with the value                      ItemTemplate
          CharacterEllipsis to make the TextBlock show an ellipsis (...) when it can't          ListView with a GridView
          fit any more text into the control. This is a common way of showing that              How-to: Left aligned column
          there's more text, but not enough room to show it. This is great when you              names
          have text that might be too long but you absolutely don't want it to use more         ListView grouping
          than one line. As an alternative to CharacterEllipsis you may use                   ListView sorting
          WordEllipsis, which will trim the text at the end of the last possible word         How-to: ListView with
          instead of the last possible character, preventing that a word is only shown in      column sorting
          part.                                                                               ListView filtering
          The blue TextBlock uses the TextWrapping property with the value Wrap, to
          make the TextBlock wrap to the next line whenever it can't fit anymore text        The TreeView control
          into the previous line. Contrary to the first TextBlock, where we manually          Introduction
          define where to wrap the text, this happens completely automatic and even           A simple TreeView
          better: It's also automatically adjusted as soon as the TextBlock get more or       TreeView, data binding and
          less space available. Try making the window in the example bigger or smaller         multiple templates
          and you will see how the wrapping is updated to match the situation.                Handling
                                                                                               Selection/Expansion state
          This was all about dealing with simple strings in the TextBlock. In the next
                                                                                              Lazy loading TreeView items
          chapter, we'll look into some of the more advanced functionality of the
          TextBlock, which allows us to create text of various styles within the
          TextBlock and much more.
                                                                                             The DataGrid control
                Previous                                                        Next          Introduction
                                                                                              Custom columns
                                                                                              Details row
                                                                                             Misc.
                                                                                              The DispatcherTimer
                                                    
   
Download
                                                     PDF!
                                                                    
Back to Top
Home Contact Us
                                                                                              Download as PDF
        The TextBlock control - Inline
        formatting                                                                                   Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
                                                                                              About WPF
          In the last article we looked at the core functionality of the TextBlock control:
                                                                                               What is WPF?
           Displaying a simple string and wrapping it if necessary. We even used
                                                                                               WPF vs. WinForms
           another color than the default for rendering the text, but what if you wanted to
           do more than just define a static color for all the text in the TextBlock?
          Luckily the TextBlock control supports inline content. These small control-like     Getting started
           constructs all inherit from the Inline class, which means that they can be          Visual Studio Express
           rendered inline, as a part of a larger text. As of writing, the supported           Hello, WPF!
           elements include AnchoredBlock, Bold, Hyperlink, InlineUIContainer, Italic,
           LineBreak, Run, Span, and Underline. In the following examples, we'll have a
           look at most of them.
                                                                                              XAML
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="TextBlockInlineSample" Height="100"
                                                                                              Basic controls
             Width="300">
                   <Grid>                                                                      The TextBlock control
             		<TextBlock Margin="10"                                                          The TextBlock control - Inline
             TextWrapping="Wrap">                                                              formatting
             			TextBlock with <Bold>bold</Bold>,                                              The Label control
             <Italic>italic</Italic> and                                                       The TextBox control
             <Underline>underlined</Underline> text.                                           The CheckBox control
                                                                                             Panels
                                                                                              Introduction to WPF Panels
                                                                                              The Canvas
                                                                                              The WrapPanel
                                                                                              The StackPanel
                                                                                              The DockPanel
                                                                                              The Grid
          Much like with HTML, you just surround your text with a Bold tag to get bold        The Grid - Rows & Columns
          text and so on. This makes it very easy to create and display diverse text in       The Grid - Units
          your applications.                                                                  The Grid - Spanning
                                                                                              The Grid - GridSplitter
          All three of these tags are just child classes of the Span element, each setting    Using the Grid: A contact
          a specific property on the Span element to create the desired effect. For            form
          instance, the Bold tag just sets the FontWeight property on the underlying
          Span element, the Italic element sets the FontStyle and so on.
                                                                                             Data binding
          LineBreak
                                                                                              Introduction
          Simply inserts a line break into the text. Please see the previous chapter for      Hello, bound world!
          an example where we use the LineBreak element.                                      Using the DataContext
                                                                                              The UpdateSourceTrigger
          Hyperlink                                                                            property
                                                                                              Responding to changes
          The Hyperlink element allows you to have links in your text. It's rendered with     Value conversion with
          a style that suits your current Windows theme, which will usually be some            IValueConverter
          sort of underlined blue text with a red hover effect and a hand mouse cursor.       The StringFormat property
          You can use the NavigateUri property to define the URL that you wish to             Debugging data bindings
          navigate to. Here's an example:
             <Window                                                                         Commands
             x:Class="WpfTutorialSamples.Basic_controls.TextBlockHyperlin
                                                                                              Introduction
                                                                                              Using commands
                                                                                              Implementing custom
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                               commands
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="TextBlockHyperlinkSample" Height="100"                        Common interface
             Width="300">                                                                    controls
             	<Grid>                                                                          The Menu control
             		<TextBlock Margin="10"                                                         The ContextMenu
             TextWrapping="Wrap">                                                             The ToolBar control
             			                                This text has a <Hyperlink                    The StatusBar control
             RequestNavigate="Hyperlink_RequestNavigate"                                      The Ribbon Control
             NavigateUri="https://www.google.com">link</Hyperlink> in
             it.
             		</TextBlock>                                                                  Rich Text controls
             	</Grid>
                                                                                                Introduction
             </Window>
                                                                                                The
                                                                                                 FlowDocumentScrollViewer
                                                                                                 control
                                                                                                The
                                                                                                 FlowDocumentPageViewer
                                                                                                 control
                                                                                                The FlowDocumentReader
                                                                                                 control
                                                                                                Creating a FlowDocument
          The Hyperlink is also used inside of WPF Page's, where it can be used to               from Code-behind
          navigate between pages. In that case, you won't have to specifically handle           Advanced FlowDocument
          the RequestNavigate event, like we do in the example, but for launching                content
          external URL's from a regular WPF application, we need a bit of help from             The RichTextBox control
          this event and the Process class. We subscribe to the RequestNavigate
          event, which allows us to launch the linked URL in the users default browser
          with a simple event handler like this one in the code behind file:                  Misc. controls
                                                                                                The Border control
             private void Hyperlink_RequestNavigate(object sender,                              The Slider control
             System.Windows.Navigation.RequestNavigateEventArgs e)
                                                                                                The ProgressBar control
             {
                                                                                                The WebBrowser control
             	
                                                                                                The WindowsFormsHost
             System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
                                                                                                control
             }
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
          So as you can see, if none of the other elements doesn't make sense in your
          situation or if you just want a blank canvas when starting to format your text,   Misc.
          the Span element is a great choice.                                                The DispatcherTimer
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="TextBlockCodeBehindSample" Height="100"
             Width="300">
                   <Grid></Grid>
             </Window>
             using System;
             using System.Windows;
             using System.Windows.Controls;
             using System.Windows.Documents;
             using System.Windows.Media;
             namespace WpfTutorialSamples.Basic_controls
             {
             	          public partial class TextBlockCodeBehindSample :
             Window
             	{
             		public TextBlockCodeBehindSample()
             		{
             			InitializeComponent();
             			                                TextBlock tb = new TextBlock();
             			tb.TextWrapping =
             TextWrapping.Wrap;
             			                                tb.Margin = new Thickness(10);
             			                                tb.Inlines.Add("An example on ");
             			tb.Inlines.Add(new Run("the
             TextBlock control ") { FontWeight = FontWeights.Bold });
             			tb.Inlines.Add("using ");
             			tb.Inlines.Add(new Run("inline ")
             { FontStyle = FontStyles.Italic });
             			tb.Inlines.Add(new Run("text
             formatting ") { Foreground = Brushes.Blue });
             			tb.Inlines.Add("from ");
             			tb.Inlines.Add(new Run("Code-
             Behind") { TextDecorations = TextDecorations.Underline });
             			tb.Inlines.Add(".");
             			this.Content = tb;
             		}
             	}
             }
          It's great to have the possibility, and it can be necessary to do it like this in
           some cases, but this example will probably make you appreciate XAML even
           more.
Previous Next
                                                                         
         
Download
                                                                          PDF!
                                                                                                    
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The Label control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          The Label control, in its most simple form, will look very much like the           About WPF
          TextBlock which we used in another article. You will quickly notice though
                                                                                              What is WPF?
          that instead of a Text property, the Label has a Content property. The reason
                                                                                              WPF vs. WinForms
          for that is that the Label can host any kind of control directly inside of it,
          instead of just text. This content can be a string as well though, as you will
          see in this first and very basic example:
                                                                                             Getting started
             <Window                                                                          Visual Studio Express
             x:Class="WpfTutorialSamples.Basic_controls.LabelControlSampl                     Hello, WPF!
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    XAML
                                                                                              What is XAML?
                                                                                              Basic XAML
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           Events in XAML
                        Title="LabelControlSample" Height="100"
             Width="200">
                  <Grid>
                                                                                             A WPF application
             		                    <Label Content="This is a Label control."
                                                                                              Introduction
             />
                                                                                              The Window
             	</Grid>
                                                                                              Working with App.xaml
             </Window>
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
          Another thing you might notice is the fact that the Label, by default, has a bit    formatting
          of padding, allowing the text to be rendered a few pixels away from the top,        The Label control
          left corner. This is not the case for the TextBlock control, where you will have    The TextBox control
          to specify it manually.                                                             The CheckBox control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Commands
                                                                                              Introduction
                                                                                              Using commands
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                              Implementing custom
                        Title="LabelControlSample" Height="180"
                                                                                               commands
             Width="250">
             	          <StackPanel Margin="10">
             		                    <Label Content="_Name:" Target="{Binding
                                                                                             Common interface
             ElementName=txtName}" />
                                                                                             controls
             		                    <TextBox Name="txtName" />
             		                    <Label Content="_Mail:" Target="{Binding                   The Menu control
             ElementName=txtMail}" />                                                         The ContextMenu
             		                    <TextBox Name="txtMail" />                                 The ToolBar control
             	</StackPanel>                                                                   The StatusBar control
             </Window>                                                                        The Ribbon Control
                                                                                               Introduction
                                                                                               The
                                                                                                FlowDocumentScrollViewer
                                                                                                control
                                                                                               The
                                                                                                FlowDocumentPageViewer
                                                                                                control
                                                                                               The FlowDocumentReader
                                                                                                control
          The screenshot shows our sample dialog as it looks when the Alt key is               Creating a FlowDocument
          pressed. Try running it, holding down the [Alt] key and then pressing N and           from Code-behind
          M. You will see how focus is moved between the two textboxes.                        Advanced FlowDocument
                                                                                                content
          So, there's several new concepts here. First of all, we define the access key        The RichTextBox control
          by placing an underscore (_) before the character. It doesn't have to be the
          first character, it can be before any of the characters in your label content.
          The common practice is to use the first character that's not already used as       Misc. controls
          an access key for another control.                                                   The Border control
                                                                                               The Slider control
          We use the Target property to connect the Label and the designated control.
                                                                                               The ProgressBar control
          We use a standard WPF binding for this, using the ElementName property,
                                                                                               The WebBrowser control
          all of which we will describe later on in this tutorial. The binding is based on
                                                                                               The WindowsFormsHost
          the name of the control, so if you change this name, you will also have to
                                                                                               control
          remember to change the binding.
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
          This is just an extended version of the previous example - instead of a simple
          text string, our Label will now host both and image and a piece of text (inside
          the AccessText control, which allows us to still use an access key for the
                                                                                              Audio & Video
          label). Both controls are inside a horizontal StackPanel, since the Label, just
                                                                                               Playing audio
          like any other ContentControl derivate, can only host one direct child control.
                                                                                               Playing video
          The Image control, described later in this tutorial, uses a remote image - this      How-to: Complete media
          is ONLY for demonstrational purposes and is NOT a good idea for most real            player
          life applications.                                                                   Speech synthesis
                                                                                               Speech recognition
          Summary
          In most situations, the Label control does exactly what the name implies: It
           acts as a text label for another control. This is the primary purpose of it. For
           most other cases, you should probably use a TextBlock control or one of the
           other text containers that WPF offers.
Previous Next
                                                      
         
Download
                                                       PDF!
                                                                                 
Back to Top
Home Contact Us
                                                                                            Download as PDF
        The TextBox control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          
The TextBox control is the most basic text-input control found in WPF,           About WPF
           allowing the end-user to write plain text, either on a single line, for dialog
                                                                                             What is WPF?
           input, or in multiple lines, like an editor.
                                                                                             WPF vs. WinForms
          
Single-line TextBox
          
The TextBox control is such a commonly used thing that you actually don't        Getting started
           have to use any properties on it, to have a full-blown editable text field.
                                                                                             Visual Studio Express
           Here's a barebone example:
                                                                                             Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Basic_controls.TextBoxSample"
                                                                                            XAML
                                                                                             What is XAML?
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             Basic XAML
                                                                                             Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="TextBoxSample" Height="80" Width="250">
                  <StackPanel Margin="10">                                                  A WPF application
            		<TextBox />                                                                    Introduction
            	</StackPanel>                                                                   The Window
            </Window>                                                                        Working with App.xaml
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
                                                                                            Basic controls
                                                                                             The TextBlock control
          
That's all you need to get a text field. I added the text after running the       The TextBlock control - Inline
           sample and before taking the screenshot, but you can do it through markup         formatting
           as
well, to pre-fill the textbox, using the Text property:                        The Label control
                                                                                             The TextBox control
            <TextBox Text="Hello, world!" />                                                 The CheckBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                              Data binding
                       Title="TextBoxSample" Height="160" Width="280">
                  <Grid Margin="10">                                                           Introduction
            		<TextBox AcceptsReturn="True"                                                    Hello, bound world!
            TextWrapping="Wrap" />                                                             Using the DataContext
            	</Grid>                                                                           The UpdateSourceTrigger
            </Window>                                                                           property
                                                                                               Responding to changes
                                                                                               Value conversion with
                                                                                                IValueConverter
                                                                                               The StringFormat property
                                                                                               Debugging data bindings
                                                                                              Commands
                                                                                               Introduction
                                                                                               Using commands
                                                                                               Implementing custom
          
I have added two properties: The AcceptsReturn makes the TextBox into a              commands
           multi-line control by allowing the use of the Enter/Return key to go to the next
          
line, and the TextWrapping property, which will make the text wrap
           automatically when the end of a line is reached.                                   Common interface
                                                                                              controls
          
Spellcheck with TextBox                                                             The Menu control
                                                                                               The ContextMenu
          
As an added bonus, the TextBox control actually comes with automatic spell
                                                                                               The ToolBar control
           checking for English and a couple of other languages (as of writing, English,
                                                                                               The StatusBar control
           French, German, and Spanish languages are supported). It works much like
                                                                                               The Ribbon Control
           in Microsoft Word, where spelling errors are underlined and you can right-
          click it
for suggested alternatives. Enabling spell checking is very easy:
            x:Class="WpfTutorialSamples.Basic_controls.TextBoxSample"                         Introduction
                                                                                              The
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       FlowDocumentScrollViewer
                                                                                               control
                                                                                              The
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             FlowDocumentPageViewer
                       Title="TextBoxSample" Height="160" Width="280">                         control
                  <Grid Margin="10">                                                          The FlowDocumentReader
            		<TextBox AcceptsReturn="True"                                                    control
            TextWrapping="Wrap" SpellCheck.IsEnabled="True"                                   Creating a FlowDocument
            Language="en-US" />                                                                from Code-behind
            	</Grid>                                                                          Advanced FlowDocument
            </Window>                                                                          content
                                                                                              The RichTextBox control
                                                                                            Misc. controls
                                                                                              The Border control
                                                                                              The Slider control
                                                                                              The ProgressBar control
                                                                                              The WebBrowser control
                                                                                              The WindowsFormsHost
                                                                                              control
          
We have used the previous, multi-line textbox example as the basis and then
           I have added two new properties: The attached property from the SpellCheck       The TabControl
          
class called IsEnabled, which simply enables spell checking on the parent          Using the TabControl
           control, and the Language property, which instructs the spell checker which        Tab positions
           language to use.                                                                   Styling the TabItems
          
Working with TextBox selections
          
Just like any other editable control in Windows, the TextBox allows for          List controls
           selection of text, e.g. to delete an entire word at once or to copy a piece of     The ItemsControl
           the
text to the clipboard. The WPF TextBox has several properties for              The ListBox control
           working with selected text, all of them which you can read or even modify. In      The ComboBox control
           the next
example, we will be reading these properties:
                                                                                           ListView filtering
            DockPanel.Dock="Top" />
            		<TextBox Name="txtStatus"
            AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True"
                                                                                          The TreeView control
                />
                                                                                           Introduction
            	</DockPanel>                                                                  A simple TreeView
            </Window>                                                                      TreeView, data binding and
                                                                                            multiple templates
                                                                                           Handling
                                                                                            Selection/Expansion state
          
The example consists of two TextBox controls: One for editing and one for
                                                                                           Lazy loading TreeView items
           outputting the current selection status to. For this, we set the IsReadOnly
           property to true, to prevent editing of the status TextBox. We subscribe the
           SelectionChanged event on the first TextBox, which we handle in the
Code-
          behind:                                                                         The DataGrid control
                                                                                           Introduction
            using System;                                                                  Custom columns
            using System.Text;                                                             Details row
            using System.Windows;
            using System.Windows.Controls;
                                                                                          Styles
            namespace WpfTutorialSamples.Basic_controls                                    Introduction
            {                                                                              Using styles
            	          public partial class TextBoxSelectionSample :                       Triggers
            Window                                                                         Multi triggers
            	{                                                                             Trigger animations
            		public TextBoxSelectionSample()
            		{
            			InitializeComponent();
                                                                                          Misc.
            		}
                                                                                           The DispatcherTimer
            		private void
            TextBox_SelectionChanged(object sender, RoutedEventArgs e)
            		{                                                                           Audio & Video
            			                               TextBox textBox = sender as                  Playing audio
            TextBox;                                                                       Playing video
            			                               txtStatus.Text = "Selection starts           How-to: Complete media
                at character #" + textBox.SelectionStart +                                 player
            Environment.NewLine;                                                           Speech synthesis
            			                               txtStatus.Text += "Selection is "            Speech recognition
            + textBox.SelectionLength + " character(s) long" +
            Environment.NewLine;
            			                               txtStatus.Text += "Selected text:
            '" + textBox.SelectedText + "'";
            		}
            	}
            }
          
We use three interesting properties to accomplish this:
          SelectionStart
, which gives us the current cursor position or if there's a
          selection: Where it starts.
          SelectionLength
, which gives us the length of the current selection, if any.
          Otherwise it will just return 0.
          SelectedText
, which gives us the currently selected string if there's a
          selection. Otherwise an empty string is returned.
          
Modifying the selection
          
All of these properties are both readable and writable, which means that you
           can modify them as well. For instance, you can set the SelectionStart and
           SelectionLength properties to select a custom range of text, or you can use
           the SelectedText property to insert and select a string. Just remember that
           the
TextBox has to have focus, e.g. by calling the Focus() method first, for
           this to work.
Previous Next
                                                                  
         
Download
                                                                   PDF!
                                                                                             
Back to Top
Home Contact Us
                                                                                            Download as PDF
       The CheckBox control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
The CheckBox control allows the end-user to toggle an option on or off,           About WPF
          usually reflecting a Boolean value in the Code-behind. Let's jump straight into
                                                                                             What is WPF?
          an
example, in case you're not sure how a CheckBox looks:
                                                                                             WPF vs. WinForms
            <Window
            x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
                                                                                            Getting started
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Visual Studio Express
                                                                                             Hello, WPF!
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="CheckBoxSample" Height="140" Width="250">                     XAML
                  <StackPanel Margin="10">                                                   What is XAML?
            		<Label FontWeight="Bold">Application                                           Basic XAML
            Options</Label>                                                                  Events in XAML
            		                     <CheckBox>Enable feature ABC</CheckBox>
            		                     <CheckBox IsChecked="True">Enable feature
            XYZ</CheckBox>
                                                                                            A WPF application
            		                     <CheckBox>Enable feature WWW</CheckBox>
                                                                                             Introduction
            	</StackPanel>
                                                                                             The Window
            </Window>
                                                                                             Working with App.xaml
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
                                                                                            Basic controls
                                                                                             The TextBlock control
                                                                                             The TextBlock control - Inline
                                                                                             formatting
                                                                                             The Label control
         
As you can see, the CheckBox is very easy to use. On the second                    The TextBox control
          CheckBox, I use the IsChecked property to have it checked by default, but          The CheckBox control
         
Custom content                                                                      Panels
                                                                                               Introduction to WPF Panels
         
The CheckBox control inherits from the ContentControl class, which means
                                                                                               The Canvas
          that it can take custom content and display next to it. If you just specify a
                                                                                               The WrapPanel
          piece of text, like I did in the example above, WPF will put it inside a
                                                                                               The StackPanel
          TextBlock control and display it, but this is just a shortcut to make things
                                                                                               The DockPanel
          easier for you. You can use any type of control inside of it, as we'll see in the
                                                                                               The Grid
          next example:
                                                                                               The Grid - Rows & Columns
                                                                                               The Grid - Units
            <Window                                                                            The Grid - Spanning
            x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
                                                                                               The Grid - GridSplitter
                                                                                               Using the Grid: A contact
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                form
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                              Data binding
                       Title="CheckBoxSample" Height="140" Width="250">
                  <StackPanel Margin="10">                                                     Introduction
            		<Label FontWeight="Bold">Application                                             Hello, bound world!
            Options</Label>                                                                    Using the DataContext
            		<CheckBox>                                                                       The UpdateSourceTrigger
            			<TextBlock>                                                                      property
            				Enable feature <Run                                                            Responding to changes
            Foreground="Green" FontWeight="Bold">ABC</Run>                                     Value conversion with
            			</TextBlock>                                                                     IValueConverter
            		</CheckBox>                                                                      The StringFormat property
            		<CheckBox IsChecked="True">                                                      Debugging data bindings
            			<WrapPanel>
            				<TextBlock>
            					Enable feature                                                               Commands
            <Run FontWeight="Bold">XYZ</Run>                                                   Introduction
            				</TextBlock>                                                                   Using commands
            				<Image                                                                         Implementing custom
            Source="/WpfTutorialSamples;component/Images/question.png"                          commands
             Width="16" Height="16" Margin="5,0" />
            			</WrapPanel>
            		</CheckBox>
                                                                                              Common interface
            		<CheckBox>
                                                                                              controls
            			<TextBlock>
                                                                                               The Menu control
            				Enable feature <Run
                                                                                               The ContextMenu
            Foreground="Blue" TextDecorations="Underline"
                                                                                               The ToolBar control
            FontWeight="Bold">WWW</Run>
                                                                                               The StatusBar control
            			</TextBlock>
                                                                                               The Ribbon Control
            		</CheckBox>
            	</StackPanel>
            </Window>
                                                                                              Rich Text controls
                                                                                             Introduction
                                                                                             The
                                                                                              FlowDocumentScrollViewer
                                                                                              control
                                                                                             The
                                                                                              FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
         
As you can see from the sample markup, you can do pretty much whatever
                                                                                              from Code-behind
          you want with the content. On all three check boxes, I do something
                                                                                             Advanced FlowDocument
          differently with
the text, and on the middle one I even throw in an Image
                                                                                              content
          control. By specifying a control as the content, instead of just text, we get
                                                                                             The RichTextBox control
          much more control of
the appearance, and the cool thing is that no matter
          which part of the content you click on, it will activate the CheckBox and
          toggle it on or off.
                                                                                           Misc. controls
         
The IsThreeState property                                                          The Border control
                                                                                             The Slider control
         
As mentioned, the CheckBox usually corresponds to a boolean value, which
                                                                                             The ProgressBar control
          means that it only has two states: true or false (on or off). However, since a
                                                                                             The WebBrowser control
          boolean data type might be nullable, effectively allowing for a third option
                                                                                             The WindowsFormsHost
          (true, false or null), the CheckBox control can also support this case. By
                                                                                             control
          setting the IsThreeState property to true, the CheckBox will get a third state
          called "the indeterminate state".
         
A common usage for this is to have a "Enable all" CheckBox, which can            The TabControl
          control a set of child checkboxes, as well as show their collective state. Our     Using the TabControl
          example shows how you may create a list of features that can be toggled on         Tab positions
          and off, with a common "Enable all" CheckBox in the top:                           Styling the TabItems
            <Window
            x:Class="WpfTutorialSamples.Basic_controls.CheckBoxThreeStat                   List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             The ComboBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                           The ListView control
                       Title="CheckBoxThreeStateSample" Height="170"
            Width="300">                                                                     Introduction
            	          <StackPanel Margin="10">                                              A simple ListView
            		<Label FontWeight="Bold">Application                                           ListView, data binding and
            Options</Label>                                                                   ItemTemplate
            		<StackPanel Margin="10,5">                                                     ListView with a GridView
            			<CheckBox IsThreeState="True"                                                 How-to: Left aligned column
            Name="cbAllFeatures"                                                              names
            Checked="cbAllFeatures_CheckedChanged"                                           ListView grouping
            Unchecked="cbAllFeatures_CheckedChanged">Enable                                  ListView sorting
            all</CheckBox>                                                                   How-to: ListView with
            			<StackPanel Margin="20,5">                                                     column sorting
                                                                         Styles
            using System;
                                                                          Introduction
            using System.Windows;
                                                                          Using styles
                                                                          Triggers
            namespace WpfTutorialSamples.Basic_controls
                                                                          Multi triggers
            {
                                                                          Trigger animations
            	          public partial class CheckBoxThreeStateSample :
            Window
            	{
                                                                         Misc.
            		public CheckBoxThreeStateSample()
            		{                                                           The DispatcherTimer
            			InitializeComponent();
            		}
                                                                         Audio & Video
                                                                          Playing audio
            		private void                                                Playing video
            cbAllFeatures_CheckedChanged(object sender,                   How-to: Complete media
            RoutedEventArgs e)                                            player
            		{                                                           Speech synthesis
            			bool newVal =                                              Speech recognition
            (cbAllFeatures.IsChecked == true);
            			cbFeatureAbc.IsChecked = newVal;
            			cbFeatureXyz.IsChecked = newVal;
            			cbFeatureWww.IsChecked = newVal;
            		}
            		private void
            cbFeature_CheckedChanged(object sender, RoutedEventArgs e)
            		{
            			cbAllFeatures.IsChecked = null;
            			if((cbFeatureAbc.IsChecked ==
            	}
            }
         
This example works from two different angles: If you check or uncheck the
          "Enable all" CheckBox, then all of the child check boxes, each representing
          an
application feature in our example, is either checked or unchecked. It also
          works the other way around though, where checking or unchecking a child
          CheckBox affects the "Enable all" CheckBox state: If they are all checked or
          unchecked, then the "Enable all" CheckBox gets the same state - otherwise
          the
value will be left with a null, which forces the CheckBox into the
          indeterminate state.
         
All of this behavior can be seen on the screenshots above, and is achieved
          by subscribing to the Checked and Unchecked events of the CheckBox
          controls. In
a real world example, you would likely bind the values instead,
          but this example shows the basics of using the IsThreeState property to
          create a "Toggle
all" effect.
Previous Next
                                                                
         
Download
                                                                 PDF!
                                                                                           
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The RadioButton control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
The RadioButton control allows you to give your user a list of possible           About WPF
           options, with only one of them selected at the same time. You can achieve
                                                                                              What is WPF?
           the same
effect, using less space, with the ComboBox control, but a set of
                                                                                              WPF vs. WinForms
           radio buttons tend to give the user a better overview of the options they have.
            <Window
                                                                                             Getting started
            x:Class="WpfTutorialSamples.Basic_controls.RadioButtonSample
                                                                                              Visual Studio Express
                                                                                              Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            What is XAML?
                        Title="RadioButtonSample" Height="150"                                Basic XAML
            Width="250">                                                                      Events in XAML
            	           <StackPanel Margin="10">
            		                     <Label FontWeight="Bold">Are you ready?
            </Label>
                                                                                             A WPF application
            		<RadioButton>Yes</RadioButton>
                                                                                              Introduction
            		<RadioButton>No</RadioButton>
                                                                                              The Window
            		<RadioButton
                                                                                              Working with App.xaml
            IsChecked="True">Maybe</RadioButton>
                                                                                              Command-line parameters
            	</StackPanel>
                                                                                              Resources
            </Window>
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          
RadioButton groups                                                                The StackPanel
                                                                                             The DockPanel
          
If you try running the example above, you will see that, as promised, only one    The Grid
           RadioButton can be checked at the same time. But what if you want several         The Grid - Rows & Columns
           groups of radio buttons, each with their own, individual selection? This is       The Grid - Units
           what the GroupName property comes into play, which allows you
to specify          The Grid - Spanning
           which radio buttons belong together. Here's an example:                           The Grid - GridSplitter
                                                                                             Using the Grid: A contact
            <Window                                                                           form
            x:Class="WpfTutorialSamples.Basic_controls.RadioButtonSample
                                                                                            Data binding
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Introduction
                                                                                             Hello, bound world!
                                                                                             Using the DataContext
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           The UpdateSourceTrigger
                        Title="RadioButtonSample" Height="230"                                property
            Width="250">                                                                     Responding to changes
            	           <StackPanel Margin="10">                                             Value conversion with
            		                     <Label FontWeight="Bold">Are you ready?                    IValueConverter
            </Label>                                                                         The StringFormat property
            		<RadioButton                                                                   Debugging data bindings
            GroupName="ready">Yes</RadioButton>
            		<RadioButton
            GroupName="ready">No</RadioButton>
                                                                                            Commands
            		<RadioButton GroupName="ready"
                                                                                             Introduction
            IsChecked="True">Maybe</RadioButton>
                                                                                             Using commands
                                                                                             Implementing custom
            		                     <Label FontWeight="Bold">Male or female?
                                                                                              commands
            </Label>
            		<RadioButton
            GroupName="sex">Male</RadioButton>
            		<RadioButton                                                                  Common interface
            GroupName="sex">Female</RadioButton>                                            controls
            		<RadioButton GroupName="sex"                                                   The Menu control
          
Custom content
          
The RadioButton inherits from the ContentControl class, which means that it         Misc. controls
           can take custom content and display next to it. If you just specify a piece of        The Border control
           text, like I did in the example above, WPF will put it inside a TextBlock control     The Slider control
           and display it, but this is just a shortcut to make things easier for
you. You        The ProgressBar control
           can use any type of control inside of it, as we'll see in the next example:           The WebBrowser control
                                                                                                 The WindowsFormsHost
            <Window                                                                              control
            x:Class="WpfTutorialSamples.Basic_controls.RadioButtonCustom
                                                                                               The TabControl
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                 Using the TabControl
                                                                                                 Tab positions
                                                                                                 Styling the TabItems
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="RadioButtonCustomContentSample"
            Height="150" Width="250">
                                                                                               List controls
            	           <StackPanel Margin="10">
            		                     <Label FontWeight="Bold">Are you ready?                       The ItemsControl
            </Label>                                                                             The ListBox control
            		<RadioButton>                                                                      The ComboBox control
            			<WrapPanel>
            				<Image
            Source="/WpfTutorialSamples;component/Images/accept.png"                           The ListView control
            Width="16" Height="16" Margin="0,0,5,0" />                                           Introduction
            				<TextBlock Text="Yes"                                                            A simple ListView
            Foreground="Green" />                                                                ListView, data binding and
            			</WrapPanel>                                                                       ItemTemplate
                                                                                             Styles
                                                                                              Introduction
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
          
Markup-wise, this example gets a bit heavy, but the concept is pretty simple.
                                                                                              Trigger animations
           For each RadioButton, we have a WrapPanel with an image and a piece of
           text
inside of it. Since we now take control of the text using a TextBlock
           control, this also allows us to format the text in any way we want to. For this
           example, I have changed the text color to match the choice. An Image control      Misc.
           (read more about those later) is used to display an image for each choice.         The DispatcherTimer
          
Notice how you can click anywhere on the RadioButton, even on the image
           or the text, to toggle it on, because we have specified it as content of the
                                                                                             Audio & Video
           RadioButton. If you had placed it as a separate panel, next to the
           RadioButton, the user would have to click directly on the round circle of the      Playing audio
           RadioButton to activate it, which is less practical.                               Playing video
                                                                                              How-to: Complete media
                                                                                              player
                Previous                                                     Next             Speech synthesis
                                                                                              Speech recognition
                                                            
         
Download
                                                             PDF!
                                                                                       
Back to Top
Home Contact Us
                                                                                         Download as PDF
       The PasswordBox control
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         
For editing regular text in WPF we have the TextBox, but what about editing    About WPF
          passwords? The functionality is very much the same, but we want WPF to
                                                                                          What is WPF?
          display
something else than the actual characters when typing in a password,
                                                                                          WPF vs. WinForms
          to shield it from nosy people looking over your shoulder. For this purpose,
          WPF has
the PasswordBox control, which is just as easy to use as the
          TextBox. Allow me to illustrate with an example:
                                                                                         Getting started
            <Window                                                                       Visual Studio Express
            x:Class="WpfTutorialSamples.Basic_controls.PasswordBoxSample                  Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                 XAML
                                                                                          What is XAML?
                                                                                          Basic XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                        Events in XAML
                       Title="PasswordBoxSample" Height="160"
            Width="300">
                  <StackPanel Margin="10">
                                                                                         A WPF application
                       <Label>Text:</Label>
                                                                                          Introduction
                       <TextBox />
                                                                                          The Window
                       <Label>Password:</Label>
                                                                                          Working with App.xaml
                       <PasswordBox />
                                                                                          Command-line parameters
                  </StackPanel>
                                                                                          Resources
            </Window>
                                                                                          Handling exceptions
                                                                                         Basic controls
                                                                                          The TextBlock control
                                                                                          The TextBlock control - Inline
                                                                                          formatting
                                                                                          The Label control
                                                                                          The TextBox control
                                                                                          The CheckBox control
                                                                                           Common interface
                                                                                           controls
                                                                                            The Menu control
                                                                                            The ContextMenu
                                                                                            The ToolBar control
                                                                                            The StatusBar control
         
Notice how the characters are now X's instead, and that I was only allowed to
                                                                                            The Ribbon Control
          enter 6 characters in the box.
         
PasswordBox and binding
                                                                                           Rich Text controls
         
When you need to obtain the password from the PasswordBox, you can use
                                                                                         Introduction
          the Password property from Code-behind. However, for security
reasons,
                                                                                         The
          the Password property is not implemented as a dependency property, which
                                                                                          FlowDocumentScrollViewer
          means that you can't bind to it.
                                                                                          control
         
This may or may not be important to you - as already stated, you can still     The
          read the password from Code-behind, but for MVVM implementations or if          FlowDocumentPageViewer
          you just
love data bindings, a workaround has been developed. You can read      control
          much more about it here:
http://blog.functionalfun.net/2008/06/wpf-            The FlowDocumentReader
         passwordbox-and-data-binding.html                                                control
                                                                                         Creating a FlowDocument
                                                                                          from Code-behind
                Previous                                               Next              Advanced FlowDocument
                                                                                          content
                                                                                         The RichTextBox control
                                                                                       The TabControl
                                                                                         Using the TabControl
                                                                                         Tab positions
                                                                                         Styling the TabItems
                                                                                       List controls
                                                                                         The ItemsControl
                                                                                         The ListBox control
                                                                                         The ComboBox control
ListView filtering
                                                                                       Styles
                                                                                        Introduction
                                                                                        Using styles
                                                                                        Triggers
                                                                                        Multi triggers
                                                                                        Trigger animations
                                                                                       Misc.
                                                                                        The DispatcherTimer
                                                            
         
Download
                                                             PDF!
                                                      
Back to Top
Home Contact Us
                                                                                              Download as PDF
        Introduction to WPF panels
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          Panels are one of the most important control types of WPF. They act as              About WPF
          containers for other controls and control the layout of your windows/pages.
                                                                                               What is WPF?
          Since a window can only contain ONE child control, a panel is often used to
                                                                                               WPF vs. WinForms
          divide up the space into areas, where each area can contain a control or
          another panel (which is also a control, of course).
          Panels come in several different flavors, with each of them having its own way      Getting started
          of dealing with layout and child controls. Picking the right panel is therefore      Visual Studio Express
          essential to getting the behavior and layout you want, and especially in the         Hello, WPF!
          start of your WPF career, this can be a difficult job. The next section will
          describe each of the panels shortly and give you an idea of when to use it.
          After that, move on to the next chapters, where each of the panels will be
                                                                                              XAML
          described in detail.
                                                                                               What is XAML?
          Canvas                                                                               Basic XAML
                                                                                               Events in XAML
          
A simple panel, which mimics the WinForms way of doing things. It allows
           you to assign specific coordinates to each of the child controls, giving you
           total control of the layout. This is not very flexible though, because you have    A WPF application
           to manually move the child controls around and make sure that they align the
                                                                                               Introduction
           way you want them to. Use it (only) when you want complete control of the
                                                                                               The Window
           child control positions.
                                                                                               Working with App.xaml
          based on the largest item, each item is stretched to take up the full width or            The RadioButton control
          height. Use the StackPanel when you want a list of controls that takes up all             The PasswordBox control
          the available room, without wrapping.
          DockPanel                                                                                Panels
          
The DockPanel allows you to dock the child controls to the top, bottom, left or          Introduction to WPF Panels
           right. By default, the last control, if not given a specific dock position, will fill    The Canvas
           the remaining space. You can achieve the same with the Grid panel, but for               The WrapPanel
           the simpler situations, the DockPanel will be easier to use. Use the                     The StackPanel
           DockPanel whenever you need to dock one or several controls to one of the                The DockPanel
           sides, like for dividing up the window into specific areas.                              The Grid
                                                                                                    The Grid - Rows & Columns
          Grid                                                                                      The Grid - Units
                                                                                                    The Grid - Spanning
          
The Grid is probably the most complex of the panel types. A Grid can contain
                                                                                                    The Grid - GridSplitter
           multiple rows and columns. You define a height for each of the rows and a
                                                                                                    Using the Grid: A contact
           width for each of the columns, in either an absolute amount of pixels, in a
                                                                                                     form
           percentage of the available space or as auto, where the row or column will
           automatically adjust its size depending on the content. Use the Grid when the
           other panels doesn't do the job, e.g. when you need multiple columns and
           often in combination with the other panels.
                                                                                                   Data binding
                                                                                                    Introduction
          UniformGrid                                                                               Hello, bound world!
                                                                                                    Using the DataContext
          
The UniformGrid is just like the Grid, with the possibility of multiple rows and
                                                                                                    The UpdateSourceTrigger
           columns, but with one important difference: All rows and columns will have
                                                                                                     property
           the same size! Use this when you need the Grid behavior without the need to
                                                                                                    Responding to changes
           specify different sizes for the rows and columns.
                                                                                                    Value conversion with
                                                                                                     IValueConverter
                Previous                                                         Next               The StringFormat property
                                                                                                    Debugging data bindings
                                                                                                   Common interface
                                                                                                   controls
                                                                                                    The Menu control
                                                                                                    The ContextMenu
                                                                                                    The ToolBar control
                                                                                                    The StatusBar control
                                                                                                    The Ribbon Control
                                                           Introduction
                                                           The
                                                            FlowDocumentScrollViewer
                                                            control
                                                           The
                                                            FlowDocumentPageViewer
                                                            control
                                                           The FlowDocumentReader
                                                            control
                                                           Creating a FlowDocument
                                                            from Code-behind
                                                           Advanced FlowDocument
                                                            content
                                                           The RichTextBox control
                                                         Misc. controls
                                                           The Border control
                                                           The Slider control
                                                           The ProgressBar control
                                                           The WebBrowser control
                                                           The WindowsFormsHost
                                                           control
                                                         The TabControl
                                                           Using the TabControl
                                                           Tab positions
                                                           Styling the TabItems
                                                         List controls
                                                           The ItemsControl
                                                           The ListBox control
                                                           The ComboBox control
ListView filtering
                                                                                          Styles
                                                                                           Introduction
                                                                                           Using styles
                                                                                           Triggers
                                                                                           Multi triggers
                                                                                           Trigger animations
                                                                                          Misc.
                                                                                           The DispatcherTimer
                                                               
         
Download
                                                                PDF!
                                                         
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The Canvas control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
The Canvas is probably the simplest Panel of them all. It doesn't really do       About WPF
           anything by default, it just allows you to put controls in it and then position
                                                                                              What is WPF?
           them yourself using explicit coordinates.
                                                                                              WPF vs. WinForms
          
If you have ever used another UI library like WinForms, this will probably
           make you feel right at home, but while it can be tempting to have absolute
           control of all the child controls, this also means that the Panel won't do        Getting started
           anything for you once the user starts resizing your window, if you localize        Visual Studio Express
           absolutely positioned text or if the content is scaled.                            Hello, WPF!
          
More about that later, let's get into a simple example. This one is mostly
           about showing you just how little the Canvas does by default:
                                                                                             XAML
                                                                                              What is XAML?
            <Window x:Class="WpfTutorialSamples.Panels.Canvas"
                                                                                              Basic XAML
                                                                                              Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          
As you can see, even though we have two buttons, they are both placed in            Panels
           the exact same place, so only the last one is visible. The Canvas does
                                                                                                Introduction to WPF Panels
           absolutely
nothing until you start giving coordinates to the child controls. This
                                                                                                The Canvas
           is done using the Left, Right, Top and Bottom attached properties from the
                                                                                                The WrapPanel
           Canvas
control.
                                                                                                The StackPanel
                                                                                                The DockPanel
          
These properties allow you to specify the position relative to the four edges of
                                                                                                The Grid
           the Canvas. By default, they are all set to NaN (Not a Number), which will
                                                                                                The Grid - Rows & Columns
           make the Canvas place them in the upper left corner, but as mentioned, you
                                                                                                The Grid - Units
           can easily change this:
                                                                                                The Grid - Spanning
                                                                                                The Grid - GridSplitter
            <Window x:Class="WpfTutorialSamples.Panels.Canvas"
                                                                                                Using the Grid: A contact
                                                                                                 form
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                               Data binding
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="Canvas" Height="200" Width="200">                                Introduction
            	<Canvas>                                                                           Hello, bound world!
            		                     <Button Canvas.Left="10">Top left</Button>                   Using the DataContext
            		<Button Canvas.Right="10">Top                                                     The UpdateSourceTrigger
            right</Button>                                                                       property
            		<Button Canvas.Left="10"                                                          Responding to changes
            Canvas.Bottom="10">Bottom left</Button>                                             Value conversion with
            		<Button Canvas.Right="10"                                                          IValueConverter
            Canvas.Bottom="10">Bottom right</Button>                                            The StringFormat property
            	</Canvas>                                                                          Debugging data bindings
            </Window>
                                                                                               Commands
                                                                                                Introduction
                                                                                                Using commands
                                                                                                Implementing custom
                                                                                                 commands
                                                                                               Common interface
                                                                                               controls
                                                                                                The Menu control
                                                                                                The ContextMenu
                                                                                                The ToolBar control
          
Notice how I only set the property or properties that I need. For the first two      The StatusBar control
           buttons, I only wish to specify a value for the X axis, so I use the Left
and        The Ribbon Control
           Right properties to push the buttons towards the center, from each direction.
          
For the bottom buttons, I use both Left/Right and Bottom to push them
                                                                                              Rich Text controls
           towards the center in both directions. You will usually specify either a Top or
           a
Bottom value and/or a Left or a Right value.                                       Introduction
                                                                                                The
          
As mentioned, since the Canvas gives you complete control of positions, it            FlowDocumentScrollViewer
           won't really care whether or not there's enough room for all your controls or if      control
           one is on top of another. This makes it a bad choice for pretty much any kind        The
           of dialog design, but the Canvas is, as the name implies, great for at least          FlowDocumentPageViewer
           one thing: Painting. WPF has a bunch of controls that you can place inside a          control
           Canvas, to make nice illustrations.                                                  The FlowDocumentReader
                                                                                                 control
          
Z-Index                                                                              Creating a FlowDocument
                                                                                                 from Code-behind
          
In the next example, we'll use a couple of the shape related controls of WPF
                                                                                                Advanced FlowDocument
           to illustrate another very important concept when using the Canvas: Z-Index.
                                                                                                 content
           Normally, if two controls within a Canvas overlaps, the one defined last in the
                                                                                                The RichTextBox control
           markup will take precedence and overlap the other(s). However, by using the
          
attached ZIndex property on the Panel class, this can easily be changed.
          
First, an example where we don't use z-index at all:                               Misc. controls
                                                                                                The Border control
            <Window x:Class="WpfTutorialSamples.Panels.CanvasZIndex"                            The Slider control
                                                                                                The ProgressBar control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                        The WebBrowser control
                                                                                                The WindowsFormsHost
                                                                                                control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="CanvasZIndex" Height="275" Width="260">
                  <Canvas>                                                                    The TabControl
                        <Ellipse Fill="Gainsboro" Canvas.Left="25"                              Using the TabControl
            Canvas.Top="25" Width="200" Height="200" />                                         Tab positions
                        <Rectangle Fill="LightBlue" Canvas.Left="25"                            Styling the TabItems
            Canvas.Top="25" Width="50" Height="50" />
                        <Rectangle Fill="LightCoral" Canvas.Left="50"
            Canvas.Top="50" Width="50" Height="50" />
                                                                                              List controls
                        <Rectangle Fill="LightCyan" Canvas.Left="75"
                                                                                                The ItemsControl
          
Notice that because each of the rectangles are defined after the circle, they   The TreeView control
           all overlap the circle, and each of them will overlap the previously defined     Introduction
           one. Let's try changing that:                                                    A simple TreeView
                                                                                            TreeView, data binding and
            <Window x:Class="WpfTutorialSamples.Panels.CanvasZIndex"                         multiple templates
                                                                                            Handling
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Selection/Expansion state
                                                                                            Lazy loading TreeView items
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="CanvasZIndex" Height="275" Width="260">                     The DataGrid control
                  <Canvas>                                                                  Introduction
                        <Ellipse Panel.ZIndex="2" Fill="Gainsboro"                          Custom columns
            Canvas.Left="25" Canvas.Top="25" Width="200" Height="200"                       Details row
            />
                        <Rectangle Panel.ZIndex="3" Fill="LightBlue"
            Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
                                                                                           Styles
                        <Rectangle Panel.ZIndex="2" Fill="LightCoral"
                                                                                            Introduction
            Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
                                                                                            Using styles
                        <Rectangle Panel.ZIndex="4" Fill="LightCyan"
                                                                                            Triggers
            Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
                                                                                            Multi triggers
                  </Canvas>
                                                                                            Trigger animations
            </Window>
                                                                                           Misc.
                                                                                            The DispatcherTimer
                                                                                           Playing audio
                                                                                           Playing video
                                                                                           How-to: Complete media
                                                                                           player
                                                                                           Speech synthesis
                                                                                           Speech recognition
          
The default ZIndex value is 0, but we assign a new one to each of the
           shapes. The rule is that the element with the higher z-index overlaps the
           ones with
the lower values. If two values are identical, the last defined
           element "wins". As you can see from the screenshot, changing the ZIndex
           property gives
quite another look.
Previous Next
                                                                
         
Download
                                                                 PDF!
                                                                                                 
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The WrapPanel control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          The WrapPanel will position each of its child controls next to the other,          About WPF
          horizontally (default) or vertically, until there is no more room, where it will
                                                                                              What is WPF?
          wrap to the next line and then continue. Use it when you want a vertical or
                                                                                              WPF vs. WinForms
          horizontal list controls that automatically wraps when there's no more room.
          When the WrapPanel uses the Horizontal orientation, the child controls will be
          given the same height, based on the tallest item. When the WrapPanel is the        Getting started
          Vertical orientation, the child controls will be given the same width, based on     Visual Studio Express
          the widest item.                                                                    Hello, WPF!
          In the first example, we'll check out a WrapPanel with the default (Horizontal)
           orientation:
                                                                                             XAML
                                                                                              What is XAML?
            <Window x:Class="WpfTutorialSamples.Panels.WrapPanel"
                                                                                              Basic XAML
                                                                                              Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                 Panels
                                                                                                  Introduction to WPF Panels
                                                                                                  The Canvas
          Notice how I set a specific height on one of the buttons in the second row. In          The WrapPanel
          the resulting screenshot, you will see that this causes the entire row of               The StackPanel
          buttons to have the same height instead of the height required, as seen on              The DockPanel
          the first row. You will also notice that the panel does exactly what the name           The Grid
          implies: It wraps the content when it can't fit any more of it in. In this case, the    The Grid - Rows & Columns
          fourth button couldn't fit in on the first line, so it automatically wraps to the       The Grid - Units
          next line.                                                                              The Grid - Spanning
                                                                                                  The Grid - GridSplitter
          Should you make the window, and thereby the available space, smaller, you               Using the Grid: A contact
          will see how the panel immediately adjusts to it:                                        form
                                                                                                 Data binding
                                                                                                  Introduction
                                                                                                  Hello, bound world!
                                                                                                  Using the DataContext
                                                                                                  The UpdateSourceTrigger
                                                                                                   property
                                                                                                  Responding to changes
                                                                                                  Value conversion with
                                                                                                   IValueConverter
          All of this behavior is also true when you set the Orientation to Vertical. Here's
                                                                                                  The StringFormat property
          the exact same example as before, but with a Vertical WrapPanel:
                                                                                                  Debugging data bindings
<Window x:Class="WpfTutorialSamples.Panels.WrapPanel"
                                                                                                 Commands
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                  Introduction
                                                                                                  Using commands
                                                                                                  Implementing custom
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                   commands
                       Title="WrapPanel" Height="120" Width="300">
            	          <WrapPanel Orientation="Vertical">
            		                     <Button>Test button 1</Button>
            		                     <Button>Test button 2</Button>                                Common interface
            		                     <Button>Test button 3</Button>                                controls
            		                     <Button Width="140">Test button 4</Button>                     The Menu control
            		                     <Button>Test button 5</Button>                                 The ContextMenu
            		                     <Button>Test button 6</Button>                                 The ToolBar control
            	</WrapPanel>                                                                         The StatusBar control
            </Window>                                                                             The Ribbon Control
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
          Notice how button 5 only uses the width - it doesn't care about the height,
          although it causes the sixth button to be pushed to a new column.
                                                                                            List controls
                Previous                                                    Next              The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
                                                                                      ListView sorting
                                                                                      How-to: ListView with
                                                                                       column sorting
                                                                                      ListView filtering
                                                                                     Styles
                                                                                      Introduction
                                                                                      Using styles
                                                                                      Triggers
                                                                                      Multi triggers
                                                                                      Trigger animations
                                                                                     Misc.
                                                                                      The DispatcherTimer
                                                    
   
Download
                                                     PDF!
                                                                    
Back to Top
Home Contact Us
                                                                                            Download as PDF
        The StackPanel control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          The StackPanel is very similar to the WrapPanel, but with at least one            About WPF
          important difference: The StackPanel doesn't wrap the content. Instead it
                                                                                             What is WPF?
          stretches it content in one direction, allowing you to stack item after item on
                                                                                             WPF vs. WinForms
          top of each other. Let's first try a very simple example, much like we did with
          the WrapPanel:
                                                                                            Getting started
            <Window x:Class="WpfTutorialSamples.Panels.StackPanel"
                                                                                             Visual Studio Express
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Hello, WPF!
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          XAML
                        Title="StackPanel" Height="160" Width="300">                         What is XAML?
            	<StackPanel>                                                                    Basic XAML
            		<Button>Button 1</Button>                                                      Events in XAML
            		<Button>Button 2</Button>
            		<Button>Button 3</Button>
            		<Button>Button 4</Button>
                                                                                            A WPF application
            		<Button>Button 5</Button>
                                                                                             Introduction
            		<Button>Button 6</Button>
                                                                                             The Window
            	</StackPanel>
                                                                                             Working with App.xaml
            </Window>
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
                                                                                            Basic controls
                                                                                             The TextBlock control
                                                                                             The TextBlock control - Inline
                                                                                             formatting
                                                                                             The Label control
                                                                                             The TextBox control
                                                                                             The CheckBox control
          The first thing you should notice is how the StackPanel doesn't really care
                                                                                              Data binding
                                                                                               Introduction
          Another thing you will likely notice is that the StackPanel stretches its child      Hello, bound world!
          control by default. On a vertically aligned StackPanel, like the one in the first    Using the DataContext
          example, all child controls get stretched horizontally. On a horizontally            The UpdateSourceTrigger
          aligned StackPanel, all child controls get stretched vertically, as seen above.       property
          The StackPanel does this by setting the HorizontalAlignment or                       Responding to changes
          VerticalAlignment property on its child controls to Stretch, but you can easily      Value conversion with
          override this if you want to. Have a look at the next example, where we use           IValueConverter
          the same markup as we did in the previous example, but this time we assign           The StringFormat property
          values to the VerticalAlignment property for all the child controls:                 Debugging data bindings
            <Window x:Class="WpfTutorialSamples.Panels.StackPanel"
                                                                                              Commands
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       Introduction
                                                                                               Using commands
                                                                                               Implementing custom
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                              commands
                        Title="StackPanel" Height="160" Width="300">
            	           <StackPanel Orientation="Horizontal">
            		<Button VerticalAlignment="Top">Button
                                                                                              Common interface
            1</Button>
                                                                                              controls
            		<Button VerticalAlignment="Center">Button
                                                                                               The Menu control
            2</Button>
                                                                                               The ContextMenu
            		<Button VerticalAlignment="Bottom">Button
                                                                                               The ToolBar control
            3</Button>
                                                                                               The StatusBar control
            		<Button VerticalAlignment="Bottom">Button
                                                                                               The Ribbon Control
            4</Button>
            		<Button VerticalAlignment="Center">Button
            5</Button>
            		<Button VerticalAlignment="Top">Button                                          Rich Text controls
            6</Button>                                                                 Introduction
            	</StackPanel>                                                             The
            </Window>                                                                   FlowDocumentScrollViewer
                                                                                        control
                                                                                       The
                                                                                        FlowDocumentPageViewer
                                                                                        control
                                                                                       The FlowDocumentReader
                                                                                        control
                                                                                       Creating a FlowDocument
                                                                                        from Code-behind
                                                                                       Advanced FlowDocument
                                                                                        content
                                                                                       The RichTextBox control
          We use the Top, Center and Bottom values to place the buttons in a nice
          pattern, just for kicks. The same can of course be done for a vertically
          aligned StackPanel, where you would use the HorizontalAlignment on the     Misc. controls
          child controls:                                                              The Border control
                                                                                       The Slider control
            <Window x:Class="WpfTutorialSamples.Panels.StackPanel"                     The ProgressBar control
                                                                                       The WebBrowser control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta               The WindowsFormsHost
                                                                                       control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="StackPanel" Height="160" Width="300">                 The TabControl
            	           <StackPanel Orientation="Vertical">                            Using the TabControl
            		<Button HorizontalAlignment="Left">Button                                Tab positions
            1</Button>                                                                 Styling the TabItems
            		<Button
            HorizontalAlignment="Center">Button 2</Button>
            		<Button HorizontalAlignment="Right">Button
                                                                                     List controls
              3</Button>
                                                                                       The ItemsControl
            		<Button HorizontalAlignment="Right">Button
                                                                                       The ListBox control
              4</Button>
                                                                                       The ComboBox control
            		<Button
            HorizontalAlignment="Center">Button 5</Button>
            		<Button HorizontalAlignment="Left">Button
            6</Button>                                                               The ListView control
            	</StackPanel>                                                             Introduction
            </Window>                                                                  A simple ListView
                                                                                       ListView, data binding and
                                                                                        ItemTemplate
                                                                                       ListView with a GridView
                                                                                       How-to: Left aligned column
                                                                                        names
                                                                                       ListView grouping
                                                                                       ListView sorting
                                                                                       How-to: ListView with
                                                                                        column sorting
ListView filtering
          As you can see, the controls still go from top to bottom, but instead of having    The TreeView control
          the same width, each control is aligned to the left, the right or center.
                                                                                              Introduction
                                                                                              A simple TreeView
                Previous                                                        Next          TreeView, data binding and
                                                                                               multiple templates
                                                                                              Handling
                                                                                               Selection/Expansion state
          comments powered by Disqus                                                          Lazy loading TreeView items
                                                                                             Styles
                                                                                              Introduction
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
                                                                                              Trigger animations
                                                                                             Misc.
                                                                                              The DispatcherTimer
                                                     
   
Download
                                                     PDF!
                                                                     
Back to Top
Home Contact Us
                                                                                                Download as PDF
        The DockPanel control
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          The DockPanel makes it easy to dock content in all four directions (top,              About WPF
          bottom, left and right). This makes it a great choice in many situations, where
                                                                                                 What is WPF?
          you want to divide the window into specific areas, especially because by
                                                                                                 WPF vs. WinForms
          default, the last element inside the DockPanel, unless this feature is
          specifically disabled, will automatically fill the rest of the space (center).
          As we've seen with many of the other panels in WPF, you start taking                  Getting started
          advantage of the panel possibilities by using an attached property of it, in this      Visual Studio Express
          case the DockPanel.Dock property, which decides in which direction you                 Hello, WPF!
          want the child control to dock to. If you don't use this, the first control(s) will
          be docked to the left, with the last one taking up the remaining space. Here's
          an example on how you use it:
                                                                                                XAML
                                                                                                 What is XAML?
            <Window x:Class="WpfTutorialSamples.Panels.DockPanel"
                                                                                                 Basic XAML
                                                                                                 Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="DockPanel" Height="250" Width="250">                               Introduction
            	<DockPanel>                                                                         The Window
            		<Button                                                                            Working with App.xaml
            DockPanel.Dock="Left">Left</Button>                                                  Command-line parameters
            		<Button DockPanel.Dock="Top">Top</Button>                                          Resources
            		<Button                                                                            Handling exceptions
            DockPanel.Dock="Right">Right</Button>
            		<Button
            DockPanel.Dock="Bottom">Bottom</Button>                                             Basic controls
            		<Button>Center</Button>                                                            The TextBlock control
            	</DockPanel>                                                                        The TextBlock control - Inline
            </Window>                                                                            formatting
                                                                                                 The Label control
                                                                                                 The TextBox control
                                                                                                 The CheckBox control
                                                                                            Panels
                                                                                             Introduction to WPF Panels
                                                                                             The Canvas
                                                                                             The WrapPanel
                                                                                             The StackPanel
                                                                                             The DockPanel
                                                                                             The Grid
                                                                                             The Grid - Rows & Columns
                                                                                             The Grid - Units
          As already mentioned, we don't assign a dock position for the last child,
                                                                                             The Grid - Spanning
          because it automatically centers the control, allowing it to fill the remaining
                                                                                             The Grid - GridSplitter
          space. You will also notice that the controls around the center only takes up
                                                                                             Using the Grid: A contact
          the amount of space that they need - everything else is left for the center
                                                                                              form
          position. That is also why you will see the Right button take up a bit more
          space than the Left button - the extra character in the text simply requires
          more pixels.
                                                                                            Data binding
          The last thing that you will likely notice, is how the space is divided. For       Introduction
          instance, the Top button doesn't get all of the top space, because the Left        Hello, bound world!
          button takes a part of it. The DockPanel decides which control to favor by         Using the DataContext
          looking at their position in the markup. In this case, the Left button gets        The UpdateSourceTrigger
          precedence because it's placed first in the markup. Fortunately, this also          property
          means that it's very easy to change, as we'll see in the next example, where       Responding to changes
          we have also evened out the space a bit by assigning widths/heights to the         Value conversion with
          child controls:                                                                     IValueConverter
                                                                                             The StringFormat property
            <Window x:Class="WpfTutorialSamples.Panels.DockPanel"                            Debugging data bindings
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            Commands
                                                                                             Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                             Using commands
                       Title="DockPanel" Height="250" Width="250">
                                                                                             Implementing custom
            	<DockPanel>
                                                                                              commands
            		<Button DockPanel.Dock="Top"
            Height="50">Top</Button>
            		<Button DockPanel.Dock="Bottom"
                                                                                            Common interface
            Height="50">Bottom</Button>
                                                                                            controls
            		<Button DockPanel.Dock="Left"
            Width="50">Left</Button>                                                         The Menu control
            		<Button DockPanel.Dock="Right"                                                 The ContextMenu
            Width="50">Right</Button>	                                                       The ToolBar control
            		<Button>Center</Button>                                                        The StatusBar control
            	</DockPanel>                                                                    The Ribbon Control
            </Window>
                                                                                                column sorting
                                                                                               ListView filtering
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                                   
         
Download
                                                    PDF!
                                                           
Back to Top
Home Contact Us
                                                                                               Download as PDF
        The Grid Control
                                                                                                      Download this entire
                                                                                                      tutorial as PDF right
                                                                                               now!
          The Grid is probably the most complex of the panel types. A Grid can contain         About WPF
          multiple rows and columns. You define a height for each of the rows and a
                                                                                                What is WPF?
          width for each of the columns, in either an absolute amount of pixels, in a
                                                                                                WPF vs. WinForms
          percentage of the available space or as auto, where the row or column will
          automatically adjust its size depending on the content. Use the Grid when the
          other panels doesn't do the job, e.g. when you need multiple columns and
          often in combination with the other panels.                                          Getting started
                                                                                                Visual Studio Express
          In its most basic form, the Grid will simply take all of the controls you put into    Hello, WPF!
           it, stretch them to use the maximum available space and place it on top of
           each other:
                                                                                               XAML
            <Window x:Class="WpfTutorialSamples.Panels.Grid"
                                                                                                What is XAML?
                                                                                                Basic XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                               A WPF application
                        Title="Grid" Height="300" Width="300">
                  <Grid>                                                                        Introduction
            		<Button>Button 1</Button>                                                         The Window
            		<Button>Button 2</Button>                                                         Working with App.xaml
            	</Grid>                                                                            Command-line parameters
            </Window>                                                                           Resources
                                                                                                Handling exceptions
                                                                                               Basic controls
                                                                                                The TextBlock control
                                                                                                The TextBlock control - Inline
                                                                                                formatting
                                                                                                The Label control
                                                                                                The TextBox control
                                                                                                The CheckBox control
                                                                                            Commands
                                                                                             Introduction
                                                                                             Using commands
                                                                                             Implementing custom
                                                                                              commands
                                                                                            Common interface
                                                                                            controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                              Misc. controls
                        Title="Grid" Height="300" Width="300">
                                                                                                The Border control
                  <Grid>
                                                                                                The Slider control
            		<Grid.ColumnDefinitions>
                                                                                                The ProgressBar control
            			<ColumnDefinition Width="*" />
                                                                                                The WebBrowser control
            			<ColumnDefinition Width="*" />
                                                                                                The WindowsFormsHost
            		</Grid.ColumnDefinitions>		
                                                                                                control
            		<Button VerticalAlignment="Top"
            HorizontalAlignment="Center">Button 1</Button>
            		<Button Grid.Column="1"
            VerticalAlignment="Center"                                                        The TabControl
            HorizontalAlignment="Right">Button 2</Button>                                       Using the TabControl
            	</Grid>                                                                            Tab positions
            </Window>                                                                           Styling the TabItems
                                                                                              List controls
                                                                                                The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
                                                                                              ItemTemplate
          As you can see from the resulting screenshot, the first button is now placed in    ListView with a GridView
          the top and centered. The second button is placed in the middle, aligned to        How-to: Left aligned column
          the right.                                                                          names
                                                                                             ListView grouping
                Previous                                                    Next             ListView sorting
                                                                                             How-to: ListView with
                                                                                              column sorting
                                                                                             ListView filtering
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
                                                                                            Misc.
                                                                                             The DispatcherTimer
                                                     
         
Download
                                                      PDF!
                                                                                
Back to Top
Home Contact Us
                                                                                          Download as PDF
       The Grid - Rows & columns
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         In the last chapter, we introduced you to the great Grid panel and showed you    About WPF
          a couple of basic examples on how to use it. In this chapter we will do some
                                                                                           What is WPF?
          more advanced layouts, as this is where the Grid really shines. First of all,
                                                                                           WPF vs. WinForms
          let's throw in more columns and even some rows, for a true tabular layout:
            <Window x:Class="WpfTutorialSamples.Panels.TabularGrid"
                                                                                          Getting started
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                   Visual Studio Express
                                                                                           Hello, WPF!
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="TabularGrid" Height="300" Width="300">                      XAML
                  <Grid>                                                                   What is XAML?
            		<Grid.ColumnDefinitions>                                                     Basic XAML
            			<ColumnDefinition Width="2*" />                                             Events in XAML
            			<ColumnDefinition Width="1*" />
            			<ColumnDefinition Width="1*" />
            		</Grid.ColumnDefinitions>
                                                                                          A WPF application
            		<Grid.RowDefinitions>
                                                                                           Introduction
            			<RowDefinition Height="2*" />
                                                                                           The Window
            			<RowDefinition Height="1*" />
                                                                                           Working with App.xaml
            			<RowDefinition Height="1*" />
                                                                                           Command-line parameters
            		</Grid.RowDefinitions>
                                                                                           Resources
            		<Button>Button 1</Button>
                                                                                           Handling exceptions
            		                     <Button Grid.Column="1">Button 2</Button>
            		                     <Button Grid.Column="2">Button 3</Button>
            		                     <Button Grid.Row="1">Button 4</Button>
            		<Button Grid.Column="1"                                                     Basic controls
            Grid.Row="1">Button 5</Button>                                                 The TextBlock control
            		<Button Grid.Column="2"                                                      The TextBlock control - Inline
            Grid.Row="1">Button 6</Button>                                                 formatting
            		                     <Button Grid.Row="2">Button 7</Button>                  The Label control
            		<Button Grid.Column="1"                                                      The TextBox control
            Grid.Row="2">Button 8</Button>                                                 The CheckBox control
                                                                                             Data binding
                                                                                              Introduction
                                                                                              Hello, bound world!
         A total of nine buttons, each placed in their own cell in a grid containing three    Using the DataContext
         rows and three columns. We once again use a star based width, but this time          The UpdateSourceTrigger
         we assign a number as well - the first row and the first column has a width of        property
         2*, which basically means that it uses twice the amount of space as the rows         Responding to changes
         and columns with a width of 1* (or just * - that's the same).                        Value conversion with
                                                                                               IValueConverter
         You will also notice that I use the Attached properties Grid.Row and                 The StringFormat property
         Grid.Column to place the controls in the grid, and once again you will notice        Debugging data bindings
         that I have omitted these properties on the controls where I want to use either
         the first row or the first column (or both). This is essentially the same as
         specifying a zero. This saves a bit of typing, but you might prefer to assign
                                                                                             Commands
         them anyway for a better overview - that's totally up to you!
                                                                                              Introduction
                                                                                              Using commands
               Previous                                                      Next
                                                                                              Implementing custom
                                                                                               commands
                                                          Introduction
                                                          The
                                                           FlowDocumentScrollViewer
                                                           control
                                                          The
                                                           FlowDocumentPageViewer
                                                           control
                                                          The FlowDocumentReader
                                                           control
                                                          Creating a FlowDocument
                                                           from Code-behind
                                                          Advanced FlowDocument
                                                           content
                                                          The RichTextBox control
                                                        Misc. controls
                                                          The Border control
                                                          The Slider control
                                                          The ProgressBar control
                                                          The WebBrowser control
                                                          The WindowsFormsHost
                                                          control
                                                        The TabControl
                                                          Using the TabControl
                                                          Tab positions
                                                          Styling the TabItems
                                                        List controls
                                                          The ItemsControl
                                                          The ListBox control
                                                          The ComboBox control
ListView filtering
                                                                                         Styles
                                                                                          Introduction
                                                                                          Using styles
                                                                                          Triggers
                                                                                          Multi triggers
                                                                                          Trigger animations
                                                                                         Misc.
                                                                                          The DispatcherTimer
                                                              
         
Download
                                                               PDF!
                                                        
Back to Top
Home Contact Us
                                                                                            Download as PDF
        The Grid - Units
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          So far we have mostly used the star width/height, which specifies that a row      About WPF
          or a column should take up a certain percentage of the combined space.
                                                                                             What is WPF?
          However, there are two other ways of specifying the width or height of a
                                                                                             WPF vs. WinForms
          column or a row: Absolute units and the Auto width/height. Let's try creating a
          Grid where we mix these:
                                                                                            Getting started
             <Window x:Class="WpfTutorialSamples.Panels.GridUnits"
                                                                                             Visual Studio Express
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Hello, WPF!
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                         XAML
                        Title="GridUnits" Height="200" Width="400">                          What is XAML?
             	<Grid>                                                                         Basic XAML
             		<Grid.ColumnDefinitions>                                                      Events in XAML
             			<ColumnDefinition Width="1*" />
             			<ColumnDefinition Width="Auto" />
             			<ColumnDefinition Width="100" />
                                                                                            A WPF application
             		</Grid.ColumnDefinitions>
                                                                                             Introduction
             		<Button>Button 1</Button>
                                                                                             The Window
             		                     <Button Grid.Column="1">Button 2 with long
                                                                                             Working with App.xaml
              text</Button>
                                                                                             Command-line parameters
             		                     <Button Grid.Column="2">Button 3</Button>
                                                                                             Resources
             	</Grid>
                                                                                             Handling exceptions
             </Window>
                                                                                            Basic controls
                                                                                             The TextBlock control
                                                                                             The TextBlock control - Inline
                                                                                             formatting
                                                                                             The Label control
                                                                                             The TextBox control
                                                                                             The CheckBox control
          In this example, the first button has a star width, the second one has its width   Panels
           set to Auto and the last one has a static width of 100 pixels.                     Introduction to WPF Panels
                                                                                              The Canvas
          The result can be seen on the screenshot, where the second button only              The WrapPanel
          takes exactly the amount of space it needs to render its longer text, the third     The StackPanel
          button takes exactly the 100 pixels it was promised and the first button, with      The DockPanel
          the variable width, takes the rest.                                                 The Grid
                                                                                              The Grid - Rows & Columns
          In a Grid where one or several columns (or rows) have a variable (star) width,
                                                                                              The Grid - Units
           they automatically get to share the width/height not already used by the
                                                                                              The Grid - Spanning
           columns/rows which uses an absolute or Auto width/height. This becomes
                                                                                              The Grid - GridSplitter
           more obvious when we resize the window:
                                                                                              Using the Grid: A contact
                                                                                               form
                                                                                             Data binding
                                                                                              Introduction
                                                                                              Hello, bound world!
                                                                                              Using the DataContext
                                                                                              The UpdateSourceTrigger
                                                                                               property
                                                                                              Responding to changes
                                                                                              Value conversion with
                                                                                               IValueConverter
                                                                                              The StringFormat property
                                                                                              Debugging data bindings
                                                                                             Commands
                                                                                              Introduction
                                                                                              Using commands
                                                                                              Implementing custom
          On the first screenshot, you will see that the Grid reserves the space for the       commands
          last two buttons, even though it means that the first one doesn't get all the
          space it needs to render properly. On the second screenshot, you will see the
          last two buttons keeping the exact same amount of space, leaving the               Common interface
          surplus space to the first button.                                                 controls
                                                                                              The Menu control
          This can be a very useful technique when designing a wide range of dialogs.
                                                                                             The ContextMenu
           For instance, consider a simple contact form where the user enters a name,        The ToolBar control
           an e-mail address and a comment. The first two fields will usually have a         The StatusBar control
           fixed height, while the last one might as well take up as much space as           The Ribbon Control
           possible, leaving room to type a longer comment. In the next chapter, we will
           try building a contact form, using the grid and rows and columns of different
           heights and widths.
                                                                                           Rich Text controls
                                                                                             Introduction
                Previous                                                   Next
                                                                                             The
                                                                                              FlowDocumentScrollViewer
                                                                                              control
                                                                                             The
          comments powered by Disqus                                                          FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
                                                                                              from Code-behind
                                                                                             Advanced FlowDocument
                                                                                              content
                                                                                             The RichTextBox control
                                                                                           Misc. controls
                                                                                             The Border control
                                                                                             The Slider control
                                                                                             The ProgressBar control
                                                                                             The WebBrowser control
                                                                                             The WindowsFormsHost
                                                                                             control
                                                                                           The TabControl
                                                                                             Using the TabControl
                                                                                             Tab positions
                                                                                             Styling the TabItems
                                                                                           List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
                                                                                             The ComboBox control
                                                                                Styles
                                                                                 Introduction
                                                                                 Using styles
                                                                                 Triggers
                                                                                 Multi triggers
                                                                                 Trigger animations
                                                                                Misc.
                                                                                 The DispatcherTimer
                                               
   
Download
                                               PDF!
                                                               
Back to Top
Home Contact Us
                                                                                      Download as PDF
        The Grid - Spanning
                                                                                             Download this entire
                                                                                             tutorial as PDF right
                                                                                      now!
          The default Grid behavior is that each control takes up one cell, but       About WPF
          sometimes you want a certain control to take up more rows or columns.
                                                                                       What is WPF?
          Fortunately the Grid makes this very easy, with the Attached properties
                                                                                       WPF vs. WinForms
          ColumnSpan and RowSpan. The default value for this property is obviously
          1, but you can specify a bigger number to make the control span more rows
          or columns.
                                                                                      Getting started
          Here's a very simple example, where we use the ColumnSpan property:          Visual Studio Express
                                                                                       Hello, WPF!
            <Window x:Class="WpfTutorialSamples.Panels.GridColRowSpan"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta              XAML
                                                                                       What is XAML?
                                                                                       Basic XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                       Events in XAML
                        Title="GridColRowSpan" Height="110" Width="300">
            	<Grid>
            		<Grid.ColumnDefinitions>		
                                                                                      A WPF application
            	
            			<ColumnDefinition Width="1*" />                                         Introduction
            			<ColumnDefinition Width="1*" />                                         The Window
            		</Grid.ColumnDefinitions>                                                Working with App.xaml
            		<Grid.RowDefinitions>                                                    Command-line parameters
            			<RowDefinition Height="*" />                                            Resources
            			<RowDefinition Height="*" />                                            Handling exceptions
            		</Grid.RowDefinitions>
            		<Button>Button 1</Button>
            		                     <Button Grid.Column="1">Button 2</Button>          Basic controls
            		<Button Grid.Row="1"                                                     The TextBlock control
            Grid.ColumnSpan="2">Button 3</Button>                                      The TextBlock control - Inline
            	</Grid>                                                                   formatting
            </Window>                                                                  The Label control
                                                                                       The TextBox control
                                                                                       The CheckBox control
                                                                                          Panels
                                                                                           Introduction to WPF Panels
          We just define two columns and two rows, all of them taking up their equal       The Canvas
          share of the place. The first two buttons just use the columns normally, but     The WrapPanel
          with the third button, we make it take up two columns of space on the second     The StackPanel
          row, using the ColumnSpan attribute.                                             The DockPanel
                                                                                           The Grid
          This is all so simple that we could have just used a combination of panels to    The Grid - Rows & Columns
          achieve the same effect, but for just slightly more advanced cases, this is      The Grid - Units
          really useful. Let's try something which better shows how powerful this is:      The Grid - Spanning
                                                                                           The Grid - GridSplitter
            <Window                                                                        Using the Grid: A contact
            x:Class="WpfTutorialSamples.Panels.GridColRowSpanAdvanced"                      form
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                          Data binding
                                                                                           Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                           Hello, bound world!
                        Title="GridColRowSpanAdvanced" Height="300"
                                                                                           Using the DataContext
            Width="300">
                                                                                           The UpdateSourceTrigger
                  <Grid>
                                                                                            property
            		<Grid.ColumnDefinitions>
                                                                                           Responding to changes
            			<ColumnDefinition Width="*" />
                                                                                           Value conversion with
            			<ColumnDefinition Width="*" />
                                                                                            IValueConverter
            			<ColumnDefinition Width="*" />
                                                                                           The StringFormat property
            		</Grid.ColumnDefinitions>
                                                                                           Debugging data bindings
            		<Grid.RowDefinitions>
            			<RowDefinition Height="*" />
            			<RowDefinition Height="*" />
                                                                                          Commands
            			<RowDefinition Height="*" />
            		</Grid.RowDefinitions>                                                       Introduction
            		<Button Grid.ColumnSpan="2">Button                                           Using commands
            1</Button>                                                                     Implementing custom
            		                     <Button Grid.Column="3">Button 2</Button>                commands
            		                     <Button Grid.Row="1">Button 3</Button>
            		                     <Button Grid.Column="1" Grid.Row="1"
            Grid.RowSpan="2" Grid.ColumnSpan="2">Button 4</Button>                        Common interface
            		<Button Grid.Column="0"                                                     controls
            Grid.Row="2">Button 5</Button>                                                 The Menu control
            	</Grid>                                                                       The ContextMenu
            </Window>                                                                      The ToolBar control
                                                                                           The StatusBar control
                                                                                           The Ribbon Control
                                                                                                Introduction
                                                                                                The
                                                                                                 FlowDocumentScrollViewer
                                                                                                 control
                                                                                                The
                                                                                                 FlowDocumentPageViewer
                                                                                                 control
                                                                                                The FlowDocumentReader
                                                                                                 control
                                                                                                Creating a FlowDocument
                                                                                                 from Code-behind
                                                                                                Advanced FlowDocument
                                                                                                 content
          With three columns and three rows we would normally have nine cells, but in           The RichTextBox control
          this example, we use a combination of row and column spanning to fill all the
          available space with just five buttons. As you can see, a control can span
          either extra columns, extra rows or in the case of button 4: both.                  Misc. controls
                                                                                                The Border control
          So as you can see, spanning multiple columns and/or rows in a Grid is very
                                                                                                The Slider control
          easy. In a later article, we will use the spanning, along with all the other Grid
                                                                                                The ProgressBar control
          techniques in a more practical example.
                                                                                                The WebBrowser control
                                                                                                The WindowsFormsHost
                Previous                                                      Next              control
                                                                                              The TabControl
          comments powered by Disqus                                                            Using the TabControl
                                                                                                Tab positions
                                                                                                Styling the TabItems
                                                                                              List controls
                                                                                                The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
                                                                                    ListView sorting
                                                                                    How-to: ListView with
                                                                                     column sorting
                                                                                    ListView filtering
                                                                                   Styles
                                                                                    Introduction
                                                                                    Using styles
                                                                                    Triggers
                                                                                    Multi triggers
                                                                                    Trigger animations
                                                                                   Misc.
                                                                                    The DispatcherTimer
                                                  
   
Download
                                                   PDF!
                                                                  
Back to Top
Home Contact Us
                                                                                                Download as PDF
        The GridSplitter
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          
As you saw in the previous articles, the Grid panel makes it very easy to            About WPF
           divide up the available space into individual cells. Using column and row
                                                                                                 What is WPF?
           definitions, you can easily decide how much space each row or column
                                                                                                 WPF vs. WinForms
           should take up, but what if you want to allow the user to change this? This is
           where
the GridSplitter control comes into play.
          
The GridSplitter is used simply by adding it to a column or a row in a Grid,         Getting started
           with the proper amount of space for it, e.g. 5 pixels. It will then allow the
user    Visual Studio Express
           to drag it from side to side or up and down, while changing the size of the           Hello, WPF!
           column or row on each of the sides of it. Here's an example:
             <Window                                                                            XAML
             x:Class="WpfTutorialSamples.Panels.GridSplitterSample"
                                                                                                 What is XAML?
                                                                                                 Basic XAML
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                 Events in XAML
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                A WPF application
                        Title="GridSplitterSample" Height="300"
             Width="300">                                                                        Introduction
                  <Grid>                                                                         The Window
                        <Grid.ColumnDefinitions>                                                 Working with App.xaml
                              <ColumnDefinition Width="*" />                                     Command-line parameters
                              <ColumnDefinition Width="5" />                                     Resources
                              <ColumnDefinition Width="*" />                                     Handling exceptions
                        </Grid.ColumnDefinitions>
                        <TextBlock FontSize="55"
             HorizontalAlignment="Center" VerticalAlignment="Center"                            Basic controls
             TextWrapping="Wrap">Left side</TextBlock>                                           The TextBlock control
                        <GridSplitter Grid.Column="1" Width="5"                                  The TextBlock control - Inline
             HorizontalAlignment="Stretch" />                                                    formatting
                        <TextBlock Grid.Column="2" FontSize="55"                                 The Label control
             HorizontalAlignment="Center" VerticalAlignment="Center"                             The TextBox control
             TextWrapping="Wrap">Right side</TextBlock>                                          The CheckBox control
                  </Grid>
                                                                                              Panels
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
                                                                                               The WrapPanel
                                                                                               The StackPanel
                                                                                               The DockPanel
                                                                                               The Grid
                                                                                               The Grid - Rows & Columns
                                                                                               The Grid - Units
                                                                                               The Grid - Spanning
                                                                                               The Grid - GridSplitter
                                                                                               Using the Grid: A contact
                                                                                                form
                                                                                              Data binding
                                                                                               Introduction
                                                                                               Hello, bound world!
                                                                                               Using the DataContext
                                                                                               The UpdateSourceTrigger
                                                                                                property
                                                                                               Responding to changes
                                                                                               Value conversion with
                                                                                                IValueConverter
                                                                                               The StringFormat property
                                                                                               Debugging data bindings
                                                                                              Commands
                                                                                               Introduction
                                                                                               Using commands
                                                                                               Implementing custom
          
As you can see, I've simply created a Grid with two equally wide columns,            commands
           with a 5 pixel column in the middle. Each of the sides are just a TextBlock
           control to illustrate the point. As you can see from the screenshots, the
           GridSplitter is rendered as a dividing line between the two columns and as         Common interface
           soon
as the mouse is over it, the cursor is changed to reflect that it can be      controls
           resized.
                                                                                               The Menu control
          
Horizontal GridSplitter                                                             The ContextMenu
                                                                                               The ToolBar control
          
The GridSplitter is very easy to use and of course it supports horizontal splits    The StatusBar control
           as well. In fact, you hardly have to change anything to make it work                The Ribbon Control
           horizontally instead of vertically, as the next example will show:
             x:Class="WpfTutorialSamples.Panels.GridSplitterHorizontalSam                        Introduction
                                                                                                 The
                                                                                                  FlowDocumentScrollViewer
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                         control
                                                                                                 The
                                                                                                  FlowDocumentPageViewer
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                               control
                        Title="GridSplitterHorizontalSample" Height="300"                        The FlowDocumentReader
             Width="300">                                                                         control
                  <Grid>                                                                         Creating a FlowDocument
                        <Grid.RowDefinitions>                                                     from Code-behind
                              <RowDefinition Height="*" />                                       Advanced FlowDocument
                              <RowDefinition Height="5" />                                        content
                              <RowDefinition Height="*" />                                       The RichTextBox control
                        </Grid.RowDefinitions>
                        <TextBlock FontSize="55"
             HorizontalAlignment="Center" VerticalAlignment="Center"
                                                                                               Misc. controls
             TextWrapping="Wrap">Top</TextBlock>
                                                                                                 The Border control
                        <GridSplitter Grid.Row="1" Height="5"
                                                                                                 The Slider control
             HorizontalAlignment="Stretch" />
                                                                                                 The ProgressBar control
                        <TextBlock Grid.Row="2" FontSize="55"
                                                                                                 The WebBrowser control
             HorizontalAlignment="Center" VerticalAlignment="Center"
                                                                                                 The WindowsFormsHost
             TextWrapping="Wrap">Bottom</TextBlock>
                                                                                                 control
                  </Grid>
             </Window>
                                                                                               The TabControl
                                                                                                 Using the TabControl
                                                                                                 Tab positions
                                                                                                 Styling the TabItems
                                                                                               List controls
                                                                                                 The ItemsControl
                                                                                                 The ListBox control
                                                                                                 The ComboBox control
          
As you can see, I simply changed the columns into rows and on the                   The ListView control
           GridSplitter, I defined a Height instead of a Width. The GridSplitter figures out
                                                                                                 Introduction
           the
rest on its own, but in case it doesn't, you can use the ResizeDirection
                                                                                                 A simple ListView
           property on it to force it into either Rows or Columns mode.
                                                                                                 ListView, data binding and
                                                                                                  ItemTemplate
                Previous                                                      Next               ListView with a GridView
                                                                                                 How-to: Left aligned column
                                                                                                  names
                                                                                                 ListView grouping
          comments powered by Disqus                                                             ListView sorting
                                                                                                 How-to: ListView with
                                                                                                  column sorting
ListView filtering
                                                                                Styles
                                                                                 Introduction
                                                                                 Using styles
                                                                                 Triggers
                                                                                 Multi triggers
                                                                                 Trigger animations
                                                                                Misc.
                                                                                 The DispatcherTimer
                                                     
         
Download
                                                      PDF!
                                               
Back to Top
Home Contact Us
                                                                                           Download as PDF
        Using the Grid: A contact form
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
          In the last couple of chapters we went through a lot of theoretic information,   About WPF
           each with some very theoretic examples. In this chapter we will combine
                                                                                            What is WPF?
           what we have learned about the Grid so far, into an example that can be
                                                                                            WPF vs. WinForms
           used in the real world: A simple contact form.
          The good thing about the contact form is that it's just an example of a
          commonly used dialog - you can take the techniques used and apply them to        Getting started
          almost any type of dialog that you need to create.                                Visual Studio Express
                                                                                            Hello, WPF!
          The first take on this task is very simple and will show you a very basic
          contact form. It uses three rows, two of them with Auto heights and the last
          one with star height, so it consumes the rest of the available space:
                                                                                           XAML
                                                                                            What is XAML?
             <Window
                                                                                            Basic XAML
             x:Class="WpfTutorialSamples.Panels.GridContactForm"
                                                                                            Events in XAML
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           A WPF application
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                         Introduction
                        Title="GridContactForm" Height="300" Width="300">                   The Window
                  <Grid>                                                                    Working with App.xaml
             		<Grid.RowDefinitions>                                                        Command-line parameters
             			<RowDefinition Height="Auto" />                                             Resources
             			<RowDefinition Height="Auto" />                                             Handling exceptions
             			<RowDefinition Height="*" />
             		</Grid.RowDefinitions>		
             		<TextBox>Name</TextBox>                                                     Basic controls
             		<TextBox Grid.Row="1">E-mail</TextBox>
                                                                                            The TextBlock control
             		<TextBox Grid.Row="2"
                                                                                            The TextBlock control - Inline
             AcceptsReturn="True">Comment</TextBox>		
                                                                                            formatting
             	</Grid>
                                                                                            The Label control
             </Window>
                                                                                            The TextBox control
                                                                                            The CheckBox control
                                                                                              Panels
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
                                                                                               The WrapPanel
                                                                                               The StackPanel
                                                                                               The DockPanel
                                                                                               The Grid
          As you can see, the last TextBox simply takes up the remaining space, while
                                                                                               The Grid - Rows & Columns
          the first two only takes up the space they require. Try resizing the window
                                                                                               The Grid - Units
          and you will see the comment TextBox resize with it.
                                                                                               The Grid - Spanning
          In this very simple example, there are no labels to designate what each of the       The Grid - GridSplitter
           fields are for. Instead, the explanatory text is inside the TextBox, but this is    Using the Grid: A contact
           not generally how a Windows dialog looks. Let's try improving the look and           form
           usability a bit:
                                                                                          Introduction
                                                                                          The
                                                                                           FlowDocumentScrollViewer
                                                                                           control
                                                                                          The
                                                                                           FlowDocumentPageViewer
                                                                                           control
                                                                                          The FlowDocumentReader
                                                                                           control
                                                                                          Creating a FlowDocument
                                                                                           from Code-behind
                                                                                          Advanced FlowDocument
                                                                                           content
                                                                                          The RichTextBox control
          But perhaps you're in a situation where the comment field is pretty self-
          explanatory? In that case, let's skip the label and use ColumnSpan to get
           even more space for the comment TextBox:
                                                                                        Misc. controls
                                                                                          The Border control
             <TextBox Grid.ColumnSpan="2" Grid.Row="2"                                    The Slider control
             AcceptsReturn="True" />                                                      The ProgressBar control
                                                                                          The WebBrowser control
                                                                                          The WindowsFormsHost
                                                                                          control
                                                                                        The TabControl
                                                                                          Using the TabControl
                                                                                          Tab positions
                                                                                          Styling the TabItems
                                                                                        List controls
                                                                                          The ItemsControl
                                                                                          The ListBox control
                                                                                          The ComboBox control
          So as you can see, the Grid is a very powerful panel. Hopefully you can use   The ListView control
          all of these techniques when designing your own dialogs.                        Introduction
                                                                                          A simple ListView
                Previous                                                   Next           ListView, data binding and
                                                                                           ItemTemplate
                                                                                          ListView with a GridView
                                                                                          How-to: Left aligned column
                                                                                           names
          comments powered by Disqus
                                                                                          ListView grouping
                                                                                          ListView sorting
                                                                                          How-to: ListView with
                                                                                           column sorting
ListView filtering
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                                   
         
Download
                                                                    PDF!
                                                             
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Introduction to WPF data binding
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          Wikipedia describes the concept of data binding very well:                         About WPF
          Data binding is general technique that binds two data/information sources           What is WPF?
          together and maintains synchronization of data.                                     WPF vs. WinForms
          
With WPF, Microsoft has put data binding in the front seat and once you start
           learning WPF, you will realize that it's an important aspect of pretty much       Getting started
           everything you do. If you come from the world of WinForms, then the huge
                                                                                              Visual Studio Express
           focus on data binding might scare you a bit, but once you get used to it, you
                                                                                              Hello, WPF!
           will
likely come to love it, as it makes a lot of things cleaner and easier to
           maintain.
          
Data binding in WPF is the preferred way to bring data from your code to the      XAML
           UI layer. Sure, you can set properties on a control manually or you can            What is XAML?
           populate a ListBox by adding items to it from a loop, but the cleanest and         Basic XAML
           purest WPF way is to add a binding between the source and the destination          Events in XAML
           UI
element.
          
Summary                                                                           A WPF application
          
In the next chapter, we'll look into a simple example where data binding is        Introduction
           used and after that, we'll talk some more about all the possibilities. The         The Window
           concept of data binding is included pretty early in this tutorial, because it's    Working with App.xaml
           such an integral part of using WPF, which you will see once you explore the        Command-line parameters
           rest of the chapters, where it's used almost all of the time.                      Resources
                                                                                              Handling exceptions
          
However, the more theoretical part of data binding might be too heavy if you
           just want to get started building a simple WPF application. In that case I
           suggest that you have a look at the "Hello, bound world!" article to get a        Basic controls
           glimpse of how data binding works, and then save the rest of the data binding
                                                                                              The TextBlock control
          
articles for later, when you're ready to get some more theory.
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                Previous                                                      Next            The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
                                                               Panels
                                                                Introduction to WPF Panels
                                                                The Canvas
                                                                The WrapPanel
                                                                The StackPanel
                                                                The DockPanel
                                                                The Grid
                                                                The Grid - Rows & Columns
                                                                The Grid - Units
                                                                The Grid - Spanning
                                                                The Grid - GridSplitter
                                                                Using the Grid: A contact
                                                                 form
                                                               Data binding
                                                                Introduction
                                                                Hello, bound world!
                                                                Using the DataContext
                                                                The UpdateSourceTrigger
                                                                 property
                                                                Responding to changes
                                                                Value conversion with
                                                                 IValueConverter
                                                                The StringFormat property
                                                                Debugging data bindings
                                                               Commands
                                                                Introduction
                                                                Using commands
                                                                Implementing custom
                                                                 commands
                                                               Common interface
                                                               controls
                                                                The Menu control
                                                                The ContextMenu
                                                                The ToolBar control
                                                                The StatusBar control
                                                                The Ribbon Control
                                                                 Introduction
                                                                 The
                                                                  FlowDocumentScrollViewer
                                                                  control
                                                                 The
                                                                  FlowDocumentPageViewer
                                                                  control
                                                                 The FlowDocumentReader
                                                                  control
                                                                 Creating a FlowDocument
                                                                  from Code-behind
                                                                 Advanced FlowDocument
                                                                  content
                                                                 The RichTextBox control
                                                               Misc. controls
                                                                 The Border control
                                                                 The Slider control
                                                                 The ProgressBar control
                                                                 The WebBrowser control
                                                                 The WindowsFormsHost
                                                                 control
                                                               The TabControl
                                                                 Using the TabControl
                                                                 Tab positions
                                                                 Styling the TabItems
                                                               List controls
                                                                 The ItemsControl
                                                                 The ListBox control
                                                                 The ComboBox control
ListView filtering
                                                                                                Styles
                                                                                                 Introduction
                                                                                                 Using styles
                                                                                                 Triggers
                                                                                                 Multi triggers
                                                                                                 Trigger animations
                                                                                                Misc.
                                                                                                 The DispatcherTimer
                                                                     
         
Download
                                                                      PDF!
                                                               
Back to Top
Home Contact Us
                                                                                                Download as PDF
        Hello, bound world!
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          
Just like we started this tutorial with the classic "Hello, world!" example, we'll   About WPF
           show you how easy it is to use data binding in WPF with a "Hello, bound
                                                                                                 What is WPF?
           world!" example. Let's jump straight into it and then I'll explain it afterwards:
                                                                                                 WPF vs. WinForms
            <Window
            x:Class="WpfTutorialSamples.DataBinding.HelloBoundWorldSampl
                                                                                                Getting started
                                                                                                 Visual Studio Express
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                         Hello, WPF!
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                              XAML
                        Title="HelloBoundWorldSample" Height="110"                               What is XAML?
            Width="280">                                                                         Basic XAML
                  <StackPanel Margin="10">                                                       Events in XAML
            		                     <TextBox Name="txtValue" />
            		<WrapPanel Margin="0,10">
            			<TextBlock Text="Value: "
                                                                                                A WPF application
            FontWeight="Bold" />
                                                                                                 Introduction
            			<TextBlock Text="{Binding
                                                                                                 The Window
            Path=Text, ElementName=txtValue}" />
                                                                                                 Working with App.xaml
            		</WrapPanel>
                                                                                                 Command-line parameters
            	</StackPanel>
                                                                                                 Resources
            </Window>
                                                                                                 Handling exceptions
                                                                                                Basic controls
                                                                                                 The TextBlock control
                                                                                                 The TextBlock control - Inline
                                                                                                 formatting
                                                                                                 The Label control
                                                                                                 The TextBox control
          
This simple example shows how we bind the value of the TextBlock to match             The CheckBox control
           the Text property of the TextBox. As you can see from the screenshot, the
          
{Binding Path=NameOfProperty}
                                                                                                Data binding
          
The Path notes the property that you want to bind to, however, since Path is
                                                                                                 Introduction
           the default property of a binding, you may leave it out if you want to, like
this:
                                                                                                 Hello, bound world!
                                                                                                 Using the DataContext
          
{Binding NameOfProperty}
                                                                                                 The UpdateSourceTrigger
          
You will see many different examples, some of them where Path is explicitly            property
           defined and some where it's left out. In the end it's really up to you though.        Responding to changes
                                                                                                 Value conversion with
          
A binding has many other properties though, one of them being the                      IValueConverter
           ElementName which we use in our example. This allows us to connect                    The StringFormat property
           directly to another UI
element as the source. Each property that we set in the        Debugging data bindings
           binding is separated by a comma:
          
{Binding Path=Text, ElementName=txtValue}
                                                                                                Commands
          
Summary                                                                               Introduction
                                                                                                 Using commands
          
This was just a glimpse of all the binding possibilities of WPF. In the next          Implementing custom
           chapters, we'll discover more of them, to show you just how powerful data              commands
           binding is.
                                                    Introduction
                                                    The
                                                     FlowDocumentScrollViewer
                                                     control
                                                    The
                                                     FlowDocumentPageViewer
                                                     control
                                                    The FlowDocumentReader
                                                     control
                                                    Creating a FlowDocument
                                                     from Code-behind
                                                    Advanced FlowDocument
                                                     content
                                                    The RichTextBox control
                                                  Misc. controls
                                                    The Border control
                                                    The Slider control
                                                    The ProgressBar control
                                                    The WebBrowser control
                                                    The WindowsFormsHost
                                                    control
                                                  The TabControl
                                                    Using the TabControl
                                                    Tab positions
                                                    Styling the TabItems
                                                  List controls
                                                    The ItemsControl
                                                    The ListBox control
                                                    The ComboBox control
ListView filtering
                                                                                   Styles
                                                                                    Introduction
                                                                                    Using styles
                                                                                    Triggers
                                                                                    Multi triggers
                                                                                    Trigger animations
                                                                                   Misc.
                                                                                    The DispatcherTimer
                                                        
         
Download
                                                         PDF!
                                                  
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Using the DataContext
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
The DataContext property is the default source of your bindings, unless you       About WPF
           specifically declare another source, like we did in the previous chapter with
                                                                                              What is WPF?
           the ElementName property. It's defined on the FrameworkElement class,
                                                                                              WPF vs. WinForms
           which most UI controls, including the WPF Window, inherits from. Simply put,
           it
allows you to specify a basis for your bindings
          
There's no default source for the DataContext property (it's simply null from     Getting started
           the start), but since a DataContext is inherited down through the control          Visual Studio Express
           hierarchy, you can set a DataContext for the Window itself and then use it         Hello, WPF!
           throughout all of the child controls. Let's try illustrating that with a simple
           example:
                                                                                             XAML
            <Window
                                                                                              What is XAML?
            x:Class="WpfTutorialSamples.DataBinding.DataContextSample"
                                                                                              Basic XAML
                                                                                              Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="DataContextSample" Height="130"                                Introduction
            Width="280">                                                                      The Window
            	           <StackPanel Margin="15">                                              Working with App.xaml
            		<WrapPanel>                                                                     Command-line parameters
            			                               <TextBlock Text="Window title:          "       Resources
            />                                                                                Handling exceptions
            			<TextBox Text="{Binding Title,
            UpdateSourceTrigger=PropertyChanged}" Width="150" />
            		</WrapPanel>                                                                   Basic controls
            		<WrapPanel Margin="0,10,0,0">                                                   The TextBlock control
            			<TextBlock Text="Window                                                        The TextBlock control - Inline
            dimensions: " />                                                                  formatting
            			<TextBox Text="{Binding Width}"                                                The Label control
            Width="50" />                                                                     The TextBox control
            			                               <TextBlock Text=" x " />                        The CheckBox control
            			<TextBox Text="{Binding Height}"
          
The Code-behind for this example only adds one line of interesting code:
           After the standard InitalizeComponent() call, we assign the "this" reference to
          
the DataContext, which basically just tells the Window that we want itself to       Commands
           be the data context.                                                                 Introduction
                                                                                                Using commands
          
In the XAML, we use this fact to bind to several of the Window properties,           Implementing custom
           including Title, Width and Height. Since the window has a DataContext,                commands
           which is
passed down to the child controls, we don't have to define a source
           on each of the bindings - we just use the values as if they were globally
           available.                                                                          Common interface
                                                                                               controls
          
Try running the example and resize the window - you will see that the
           dimension changes are immediately reflected in the textboxes. You can also           The Menu control
           try
writing a different title in the first textbox, but you might be surprised to    The ContextMenu
           see that this change is not reflected immediately. Instead, you have to move         The ToolBar control
           the focus to another control before the change is applied. Why? Well, that's         The StatusBar control
           the subject for the next chapter.                                                    The Ribbon Control
          
Summary
                                                                                               Rich Text controls
          
Using the DataContext property is like setting the basis of all bindings down
                                                                                              Introduction
           through the hierarchy of controls. This saves you the hassle of manually
                                                                                              The
           defining a source for each binding, and once you really start using data
                                                                                               FlowDocumentScrollViewer
           bindings, you will definitely appreciate the time and typing saved.
                                                                                               control
          
However, this doesn't mean that you have to use the same DataContext for           The
           all controls within a Window. Since each control has its own DataContext            FlowDocumentPageViewer
           property,
you can easily break the chain of inheritance and override the            control
           DataContext with a new value. This allows you to do stuff like having a global     The FlowDocumentReader
           DataContext
on the window and then a more local and specific DataContext            control
           on e.g. a panel holding a separate form or something along those lines.            Creating a FlowDocument
                                                                                               from Code-behind
                                                                                              Advanced FlowDocument
                Previous                                                    Next
                                                                                               content
                                                                                              The RichTextBox control
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
                                                                                            List controls
                                                                                              The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
ListView filtering
                                                                                     Styles
                                                                                      Introduction
                                                                                      Using styles
                                                                                      Triggers
                                                                                      Multi triggers
                                                                                      Trigger animations
                                                                                     Misc.
                                                                                      The DispatcherTimer
                                                          
         
Download
                                                           PDF!
                                                    
Back to Top
Home Contact Us
                                                                                           Download as PDF
        The UpdateSourceTrigger property
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
         
In the previous article we saw how changes in a TextBox was not                  About WPF
          immediately sent back to the source. Instead, the source was updated only
                                                                                            What is WPF?
          after focus was
lost on the TextBox. This behavior is controlled by a property
                                                                                            WPF vs. WinForms
          on the binding called UpdateSourceTrigger. It defaults to the value
          "Default", which basically means that the source is updated based on the
          property that you bind to. As of writing, all properties except for the Text
          property, is updated as soon as the property changes (PropertyChanged),          Getting started
          while the Text property is updated when focus on the destination element is       Visual Studio Express
          lost
(LostFocus).                                                                 Hello, WPF!
         
Default is, obviously, the default value of the UpdateSourceTrigger. The other
          options are PropertyChanged, LostFocus and Explicit. The first two has
                                                                                           XAML
          already been described, while the last one simply means that the update has
                                                                                            What is XAML?
          to be pushed manually through to
occur, using a call to UpdateSource on the
                                                                                            Basic XAML
          Binding.
                                                                                            Events in XAML
         
To see how all of these options work, I have updated the example from the
          previous chapter to show you all of them:
                                                                                           A WPF application
            <Window                                                                         Introduction
            x:Class="WpfTutorialSamples.DataBinding.DataContextSample"                      The Window
                                                                                            Working with App.xaml
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Command-line parameters
                                                                                            Resources
                                                                                            Handling exceptions
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="DataContextSample" Height="130"
            Width="310">                                                                   Basic controls
            	          <StackPanel Margin="15">
                                                                                            The TextBlock control
            		<WrapPanel>
                                                                                            The TextBlock control - Inline
            			                               <TextBlock Text="Window title:       "
                                                                                            formatting
            />
                                                                                            The Label control
            			<TextBox Name="txtWindowTitle"
                                                                                            The TextBox control
            Text="{Binding Title, UpdateSourceTrigger=Explicit}"
                                                                                            The CheckBox control
            Width="150" />
            using System;
            using System.Windows;
                                                                               Data binding
            using System.Windows.Controls;
            using System.Windows.Data;                                          Introduction
                                                                                Hello, bound world!
            namespace WpfTutorialSamples.DataBinding                            Using the DataContext
            {                                                                   The UpdateSourceTrigger
            	          public partial class DataContextSample : Window           property
            	{                                                                  Responding to changes
            		public DataContextSample()                                        Value conversion with
            		{                                                                  IValueConverter
            			InitializeComponent();                                           The StringFormat property
            			this.DataContext = this;                                         Debugging data bindings
            		}
                                                                                             Introduction
         
As you can see, each of the three textboxes now uses a different                   The
          UpdateSourceTrigger.                                                                FlowDocumentScrollViewer
                                                                                              control
         
The first one is set to Explicit, which basically means that the source won't      The
          be updated unless you manually do it. For that reason, I
have added a button        FlowDocumentPageViewer
          next to the TextBox, which will update the source value on demand. In the           control
          Code-behind, you will find the Click handler, where we use a
couple of lines       The FlowDocumentReader
          of code to get the binding from the destination control and then call the           control
          UpdateSource() method on it.                                                       Creating a FlowDocument
                                                                                              from Code-behind
         
The second TextBox uses the LostFocus value, which is actually the default
                                                                                             Advanced FlowDocument
          for a Text binding. It means that the source value will be
updated each time
                                                                                              content
          the destination control loses focus.
                                                                                             The RichTextBox control
         
The third and last TextBox uses the PropertyChanged value, which means
          that the source value will be updated each time the bound property
changes,
          which it does in this case as soon as the text changes.                          Misc. controls
                                                                                             The Border control
         
Try running the example on your own machine and see how the three                  The Slider control
          textboxes act completely different: The first value doesn't update before you      The ProgressBar control
          click the
button, the second value isn't updated until you leave the TextBox,      The WebBrowser control
          while the third value updates automatically on each keystroke, text change         The WindowsFormsHost
          etc.                                                                               control
         
Summary
         
The UpdateSourceTrigger property of a binding controls how and when a            The TabControl
          changed value is sent back to the source. However, since WPF is pretty             Using the TabControl
          good at
controlling this for you, the default value should suffice for most        Tab positions
          cases, where you will get the best mix of a constantly updated UI and good         Styling the TabItems
          performance.
         
For those situations where you need more control of the process, this
                                                                                           List controls
          property will definitely help though. Just make sure that you don't update the
          source
value more often than you actually need to. If you want the full            The ItemsControl
          control, you can use the Explicit value and then do the updates manually,          The ListBox control
          but this does take a bit of the fun out of working with data bindings.             The ComboBox control
                Previous                                                    Next
                                                                                           The ListView control
                                                                                             Introduction
                                                                                             A simple ListView
                                                                                             ListView, data binding and
         comments powered by Disqus
                                                                                              ItemTemplate
                                                                                             ListView with a GridView
                                                                                                Styles
                                                                                                 Introduction
                                                                                                 Using styles
                                                                                                 Triggers
                                                                                                 Multi triggers
                                                                                                 Trigger animations
                                                                                                Misc.
                                                                                                 The DispatcherTimer
                                                               
   
Download
                                                               PDF!
                                                                               
Back to Top
Home Contact Us
                                                                                                Download as PDF
        Responding to changes
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          
So far in this tutorial, we have mostly created bindings between UI elements         About WPF
           and existing classes, but in real life applications, you will obviously be
binding
                                                                                                 What is WPF?
           to your own data objects. This is just as easy, but once you start doing it, you
                                                                                                 WPF vs. WinForms
           might discover something that disappoints you: Changes are not
           automatically reflected, like they were in previous examples. As you will learn
           in this article, you need just a bit of extra work for this to happen, but
           fortunately, WPF makes this pretty easy.                                             Getting started
                                                                                                 Visual Studio Express
          
Responding to data source changes                                                     Hello, WPF!
          
There are two different scenarios that you may or may not want to handle
           when dealing with data source changes: Changes to the list of items and
                                                                                                XAML
           changes in
the bound properties in each of the data objects. How to handle
           them may vary, depending on what you're doing and what you're looking to              What is XAML?
           accomplish, but
WPF comes with two very easy solutions that you can use:              Basic XAML
           The ObservableCollection and the INotifyPropertyChanged
interface.                    Events in XAML
          The following example will show you why we need these two things:
                                                                                                A WPF application
            <Window                                                                              Introduction
            x:Class="WpfTutorialSamples.DataBinding.ChangeNotificationSa                         The Window
                                                                                                 Working with App.xaml
                                                                                                 Command-line parameters
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                         Resources
                                                                                                 Handling exceptions
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ChangeNotificationSample" Height="150"
                                                                                                Basic controls
            Width="300">
            	          <DockPanel Margin="10">                                                   The TextBlock control
            		<StackPanel DockPanel.Dock="Right"                                                 The TextBlock control - Inline
            Margin="10,0,0,0">                                                                   formatting
            			<Button Name="btnAddUser"                                                         The Label control
            Click="btnAddUser_Click">Add user</Button>                                           The TextBox control
            			<Button Name="btnChangeUser"                                                      The CheckBox control
                                                                                               Misc. controls
                                                                                                 The Border control
                                                                                                 The Slider control
                                                                                                 The ProgressBar control
                                                                                                 The WebBrowser control
                                                                                                 The WindowsFormsHost
                                                                                                 control
          
Try running it for yourself and watch how even though you add something to
           the list or change the name of one of the users, nothing in the UI is
           updated. The example is pretty simple, with a User class that will keep the
                                                                                               The TabControl
           name of the user, a ListBox to show them
in and some buttons to manipulate
           both the list and its contents. The ItemsSource of the list is assigned to a          Using the TabControl
           quick list of a couple of users that we
create in the window constructor. The         Tab positions
           problem is that none of the buttons seems to work. Let's fix that, in two easy        Styling the TabItems
           steps.
          
Reflecting changes in the list data source                                          List controls
                                                                                                 The ItemsControl
          
The first step is to get the UI to respond to changes in the list source
                                                                                                 The ListBox control
           (ItemsSource), like when we add or delete a user. What we need is a list that
                                                                                                 The ComboBox control
           notifies any destinations of changes to its content, and fortunately, WPF
           provides a type of list that will do just that. It's called ObservableCollection,
           and you use it much like a regular List<T>, with only a few differences.
                                                                                               The ListView control
          
In the final example, which you will find below, we have simply replaced the          Introduction
           List<User> with an ObservableCollection<User> - that's all it
takes! This will        A simple ListView
           make the Add and Delete button work, but it won't do anything for the                 ListView, data binding and
           "Change name" button, because the change will happen on the bound
data                 ItemTemplate
           object itself and not the source list - the second step will handle that scenario     ListView with a GridView
           though.                                                                               How-to: Left aligned column
                                                                                                  names
          
Reflecting changes in the data objects                                                ListView grouping
          
The second step is to let our custom User class implement the                         ListView sorting
           INotifyPropertyChanged interface. By doing that, our User objects are                 How-to: ListView with
           capable of alerting the
UI layer of changes to its properties. This is a bit more      column sorting
          cumbersome than just changing the list type, like we did above, but it's still    ListView filtering
          one of the
simplest way to accomplish these automatic updates.
          
The final and working example                                                   The TreeView control
                                                                                            Introduction
          
With the two changes described above, we now have an example that WILL
                                                                                            A simple TreeView
           reflect changes in the data source. It looks like this:
                                                                                            TreeView, data binding and
                                                                                             multiple templates
            <Window                                                                         Handling
            x:Class="WpfTutorialSamples.DataBinding.ChangeNotificationSa
                                                                                             Selection/Expansion state
                                                                                            Lazy loading TreeView items
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            namespace WpfTutorialSamples.DataBinding
            {
            	          public partial class ChangeNotificationSample :
            Window
            	{
            		                     private ObservableCollection<User> users =
                new ObservableCollection<User>();
public ChangeNotificationSample()
            		{
            			InitializeComponent();
            			lbUsers.ItemsSource = users;
            		}
          
Summary
          
As you can see, implementing INotifyPropertyChanged is pretty easy, but it
           does create a bit of extra code on your classes, and adds a bit of extra logic
           to your properties. This is the price you will have to pay if you want to bind to
           your own classes and have the changes reflected in the UI immediately.
           Obviously you only have to call NotifyPropertyChanged in the setter's of the
           properties that you bind to - the rest can remain the way they are.
          
The ObservableCollection on the other hand is very easy to deal with - it
           simply requires you to use this specific list type in those situations where you
           want changes to the source list reflected in a binding destination.
Previous Next
                                                                    
         
Download
                                                                     PDF!
                                                                                               
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Value conversion with IValueConverter
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
So far we have used some simple data bindings, where the sending and              About WPF
           receiving property was always compatible. However, you will soon run into
                                                                                              What is WPF?
           situations
where you want to use a bound value of one type and then present
                                                                                              WPF vs. WinForms
           it slightly differently.
          
When to use a value converter
                                                                                             Getting started
          
Value converters are very frequently used with data bindings. Here are some
                                                                                              Visual Studio Express
           basic examples:
                                                                                              Hello, WPF!
             You have a numeric value but you want to show zero values in one
             way and positive numbers in another way
             You want to check a CheckBox based on a value, but the value is a               XAML
             string like "yes" or "no" instead of a Boolean value                             What is XAML?
             You have a file size in bytes but you wish to show it as bytes, kilobytes,       Basic XAML
             megabytes or gigabytes based on how big it is                                    Events in XAML
          
These are some of the simple cases, but there are many more. For instance,
           you may want to check a checkbox based on a Boolean value, but you want
                                                                                             A WPF application
           it
reversed, so that the CheckBox is checked if the value is false and not
           checked if the value is true. You can even use a converter to generate an          Introduction
           image for
an ImageSource, based on the value, like a green sign for true or a      The Window
           red sign for false - the possibilities are pretty much endless!                    Working with App.xaml
                                                                                              Command-line parameters
          
For cases like this, you can use a value converter. These small classes,           Resources
           which implement the IValueConverter interface, will act like middlemen and         Handling exceptions
           translate a value between the source and the destination. So, in any situation
           where you need to transform a value before it reaches its destination or
back
           to its source again, you likely need a converter.                                 Basic controls
                                                                                              The TextBlock control
          
Implementing a simple value converter                                              The TextBlock control - Inline
          
As mentioned, a WPF value converter needs to implement the                         formatting
           IValueConverter interface, or alternatively, the IMultiValueConverter interface    The Label control
           (more about that
one later). Both interfaces just requires you to implement        The TextBox control
           two methods: Convert() and ConvertBack(). As the name implies, these               The CheckBox control
          
Let's implement a simple converter which takes a string as input and then
           returns a Boolean value, as well as the other way around. If you're new to        Panels
           WPF,
and you likely are since you're reading this tutorial, then you might not
                                                                                              Introduction to WPF Panels
           know all of the concepts used in the example, but don't worry, they will all be
                                                                                              The Canvas
           explained after the code listings:
                                                                                              The WrapPanel
                                                                                              The StackPanel
            <Window                                                                           The DockPanel
            x:Class="WpfTutorialSamples.DataBinding.ConverterSample"                          The Grid
                                                                                              The Grid - Rows & Columns
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The Grid - Units
                                                                                              The Grid - Spanning
                                                                                              The Grid - GridSplitter
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Using the Grid: A contact
            		xmlns:local="clr-                                                                form
            namespace:WpfTutorialSamples.DataBinding"
                        Title="ConverterSample" Height="140" Width="250">
            	<Window.Resources>
                                                                                             Data binding
            		<local:YesNoToBooleanConverter
                                                                                              Introduction
            x:Key="YesNoToBooleanConverter" />
                                                                                              Hello, bound world!
            	</Window.Resources>
                                                                                              Using the DataContext
            	           <StackPanel Margin="10">
                                                                                              The UpdateSourceTrigger
            		                     <TextBox Name="txtValue" />
                                                                                               property
            		<WrapPanel Margin="0,10">
                                                                                              Responding to changes
            			                               <TextBlock Text="Current value is:
                                                                                              Value conversion with
              " />
                                                                                               IValueConverter
            			<TextBlock Text="{Binding
                                                                                              The StringFormat property
            ElementName=txtValue, Path=Text, Converter={StaticResource
                                                                                              Debugging data bindings
              YesNoToBooleanConverter}}"></TextBlock>
            		</WrapPanel>
            		<CheckBox IsChecked="{Binding
            ElementName=txtValue, Path=Text, Converter={StaticResource                       Commands
              YesNoToBooleanConverter}}" Content="Yes" />                                     Introduction
            	</StackPanel>                                                                    Using commands
            </Window>                                                                         Implementing custom
                                                                                               commands
            using System;
                                                                                             Common interface
            using System.Windows;
                                                                                             controls
            using System.Windows.Data;
                                                                                              The Menu control
            namespace WpfTutorialSamples.DataBinding                                          The ContextMenu
            {                                                                                 The ToolBar control
            	           public partial class ConverterSample : Window                         The StatusBar control
            	{                                                                                The Ribbon Control
            		public ConverterSample()
            		{
            			InitializeComponent();                                                        Rich Text controls
            		}                                                                 Introduction
            	}                                                                  The
                                                                                 FlowDocumentScrollViewer
            	           public class YesNoToBooleanConverter :                   control
            IValueConverter                                                     The
            	{                                                                   FlowDocumentPageViewer
            		                     public object Convert(object value, Type      control
            targetType, object parameter,                                       The FlowDocumentReader
            System.Globalization.CultureInfo culture)                            control
            		{                                                                 Creating a FlowDocument
            			switch(value.ToString().ToLower())                                from Code-behind
            			{                                                                Advanced FlowDocument
            				case "yes":                                                      content
            				case "oui":                                                     The RichTextBox control
            					return true;
            				case "no":
            				case "non":
                                                                              Misc. controls
            					return false;
                                                                                The Border control
            			}
                                                                                The Slider control
            			return false;
                                                                                The ProgressBar control
            		}
                                                                                The WebBrowser control
                                                                                The WindowsFormsHost
            		                     public object ConvertBack(object value,
                                                                                control
            Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
            		{
            			if(value is bool)                                              The TabControl
            			{                                                                Using the TabControl
            				if((bool)value == true)                                         Tab positions
            					return "yes";                                                  Styling the TabItems
            				else
            					return "no";
            			}                                                              List controls
            			return "no";
                                                                                The ItemsControl
            		}
                                                                                The ListBox control
            	}
                                                                                The ComboBox control
            }
ListView filtering
          
Code-behind
                                                                                             The DataGrid control
          
So, let's start from the back and then work our way through the example. We
           have implemented a converter in the Code-behind file called                        Introduction
           YesNoToBooleanConverter. As advertised, it just implements the two                 Custom columns
           required methods, called Convert() and ConvertBack(). The Convert()                Details row
           methods assumes that
it receives a string as the input (the value parameter)
           and then converts it to a Boolean true or false value, with a fallback value of
           false. For
fun, I added the possibility to do this conversion from French words   Styles
           as well.                                                                           Introduction
                                                                                              Using styles
          
The ConvertBack() method obviously does the opposite: It assumes an input          Triggers
           value with a Boolean type and then returns the English word "yes" or "no" in       Multi triggers
           return, with a fallback value of "no".                                             Trigger animations
          
You may wonder about the additional parameters that these two methods
           take, but they're not needed in this example. We'll use them in one of the
           next
chapters, where they will be explained.                                      Misc.
                                                                                              The DispatcherTimer
          
XAML
          
In the XAML part of the program, we start off by declaring an instance of our
                                                                                             Audio & Video
           converter as a resource for the window. We then have a TextBox, a couple of
          
TextBlocks and a CheckBox control and this is where the interesting things         Playing audio
           are happening: We bind the value of the TextBox to the TextBlock and the           Playing video
           CheckBox control and using the Converter property and our own converter            How-to: Complete media
           reference, we juggle the values back and forth between a string and a              player
           Boolean
value, depending on what's needed.                                         Speech synthesis
                                                                                              Speech recognition
          
If you try to run this example, you will be able to change the value in two
           places: By writing "yes" in the TextBox (or any other value, if you want false)
           or by checking the CheckBox. No matter what you do, the change will be
           reflected in the other control as well as in the TextBlock.
          
Summary
          
This was an example of a simple value converter, made a bit longer than
           needed for illustrational purposes. In the next chapter we'll look into a more
           advanced example, but before you go out and write your own converter, you
           might want to check if WPF already includes one for the purpose. As of
           writing,
there are more than 20 built-in converters that you may take
           advantage of, but you need to know their name. I found the following list
           which might come in
handy for you:
           http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters
Previous Next
                                                                      
         
Download
                                                                       PDF!
                                                                                                 
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The StringFormat property
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
As we saw in the previous chapters, the way to manipulate the output of a         About WPF
           binding before is shown is typically through the use of a converter. The cool
                                                                                              What is WPF?
           thing about the converters is that they allow you to convert any data type into
                                                                                              WPF vs. WinForms
           a completely different data type. However, for more simple usage scenarios,
           where you just want to change the way a certain value is shown and not
           necessarily convert it into a different type, the StringFormat property might
           very
well be enough.                                                              Getting started
                                                                                              Visual Studio Express
          
Using the StringFormat property of a binding, you lose some of the flexibility     Hello, WPF!
           you get when using a converter, but in return, it's much simpler to use and
           doesn't involve the creation of a new class in a new file.
                                                                                             XAML
          
The StringFormat property does exactly what the name implies: It formats the
           output string, simply by calling the String.Format method. Sometimes an            What is XAML?
           example says more than a thousand words, so before I hit that word count,          Basic XAML
           let's jump straight into an example:                                               Events in XAML
            <Window
            x:Class="WpfTutorialSamples.DataBinding.StringFormatSample"                      A WPF application
                                                                                              Introduction
                                                                                              The Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Handling exceptions
            		xmlns:system="clr-
            namespace:System;assembly=mscorlib"
                        Title="StringFormatSample" Height="150"                              Basic controls
            Width="250"
                                                                                              The TextBlock control
            		Name="wnd">
                                                                                              The TextBlock control - Inline
            	           <StackPanel Margin="10">
                                                                                              formatting
            		                     <TextBlock Text="{Binding ElementName=wnd,
                                                                                              The Label control
              Path=ActualWidth, StringFormat=Window width: {0:#,#.0}}"
                                                                                              The TextBox control
            />
                                                                                              The CheckBox control
            		                     <TextBlock Text="{Binding ElementName=wnd,
                                                                                            Data binding
          
The first couple of TextBlock's gets their value by binding to the parent
                                                                                             Introduction
           Window and getting its width and height. Through the StringFormat property,
                                                                                             Hello, bound world!
           the
values are formatted. For the width, we specify a custom formatting string
                                                                                             Using the DataContext
           and for the height, we ask it to use the currency format, just for fun. The
                                                                                             The UpdateSourceTrigger
          
value is saved as a double type, so we can use all the same format specifiers
                                                                                              property
           as if we had called double.ToString(). You can find a list of them here:
                                                                                             Responding to changes
           http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
                                                                                             Value conversion with
                                                                                              IValueConverter
          
Also notice how I can include custom text in the StringFormat - this allows
                                                                                             The StringFormat property
           you to pre/post-fix the bound value with text as you please. When referencing
                                                                                             Debugging data bindings
          
the actual value inside the format string, we surround it by a set of curly
           braces, which includes two values: A reference to the value we want to
           format
(value number 0, which is the first possible value) and the format
           string, separated by a colon.                                                    Commands
                                                                                             Introduction
          
For the last two values, we simply bind to the current date (DateTime.Now)        Using commands
           and the output it first as a date, in a specific format, and then as the time     Implementing custom
          
(hours and minutes), again using our own, pre-defined format. You can read         commands
           more about DateTime formatting here: http://msdn.microsoft.com/en-
          us/library/az4se3k1.aspx
                                                                                            Common interface
          
Formatting without extra text                                                    controls
          
Please be aware that if you specify a format string that doesn't include any      The Menu control
           custom text, which all of the examples above does, then you need to add an        The ContextMenu
           extra set of curly braces, when defining it in XAML. The reason is that WPF       The ToolBar control
           may otherwise confuse the syntax with the one used for Markup Extensions.         The StatusBar control
           Here's an example:                                                                The Ribbon Control
            <Window
            x:Class="WpfTutorialSamples.DataBinding.StringFormatSample"                     Rich Text controls
                                                                                             Introduction
                                                                                             The
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      FlowDocumentScrollViewer
                                                                                              control
                                                                                             The
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                              FlowDocumentPageViewer
            		xmlns:system="clr-
                                                                                              control
            namespace:System;assembly=mscorlib"
                                                                                             The FlowDocumentReader
                        Title="StringFormatSample" Height="150"
                                                                                              control
            Width="250"
                                                                                             Creating a FlowDocument
            		Name="wnd">
                                                                                              from Code-behind
            	           <WrapPanel Margin="10">
                                                                                             Advanced FlowDocument
            		                     <TextBlock Text="Width: " />
                                                                                              content
            		                     <TextBlock Text="{Binding ElementName=wnd,
                                                                                             The RichTextBox control
              Path=ActualWidth, StringFormat={}{0:#,#.0}}" />
            	</WrapPanel>
            </Window>
                                                                                           Misc. controls
                                                                                             The Border control
                                                                                             The Slider control
          
Using a specific Culture                                                          The ProgressBar control
          
If you need to output a bound value in accordance with a specific culture,        The WebBrowser control
           that's no problem. The Binding will use the language specified for the parent     The WindowsFormsHost
           element, or you can specify it directly for the binding, using the                control
           ConverterCulture property. Here's an example:
                                                                                           List controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                             The ItemsControl
            		xmlns:system="clr-
                                                                                             The ListBox control
            namespace:System;assembly=mscorlib"
                                                                                             The ComboBox control
                        Title="StringFormatCultureSample" Height="120"
            Width="300">
            	           <StackPanel Margin="10">
                                                                                           The ListView control
            		                     <TextBlock Text="{Binding Source={x:Static
              system:DateTime.Now}, ConverterCulture='de-DE',                                Introduction
            StringFormat=German date: {0:D}}" />                                             A simple ListView
            		                     <TextBlock Text="{Binding Source={x:Static                ListView, data binding and
              system:DateTime.Now}, ConverterCulture='en-US',                                 ItemTemplate
            StringFormat=American date: {0:D}}" />                                           ListView with a GridView
            		                     <TextBlock Text="{Binding Source={x:Static                How-to: Left aligned column
              system:DateTime.Now}, ConverterCulture='ja-JP',                                 names
            StringFormat=Japanese date: {0:D}}" />                                           ListView grouping
            	</StackPanel>                                                                   ListView sorting
            </Window>                                                                        How-to: ListView with
                                                                                              column sorting
ListView filtering
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
                                                                                            Misc.
                                                                                             The DispatcherTimer
                                                                 
         
Download
                                                                  PDF!
                                                        
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Debugging data bindings
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
Since data bindings are evaluated at runtime, and no exceptions are thrown        About WPF
           when they fail, a bad binding can sometimes be very hard to track down.
                                                                                              What is WPF?
           These
problems can occur in several different situations, but a common issue
                                                                                              WPF vs. WinForms
           is when you try to bind to a property that doesn't exist, either because you
           remembered its name wrong or because you simply misspelled it. Here's an
           example:
                                                                                             Getting started
            <Window                                                                           Visual Studio Express
            x:Class="WpfTutorialSamples.DataBinding.DataBindingDebugging                      Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     XAML
                                                                                              What is XAML?
                                                                                              Basic XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Events in XAML
                        Title="DataBindingDebuggingSample" Height="100"
            Width="200">
                  <Grid Margin="10" Name="pnlMain">
                                                                                             A WPF application
            		<TextBlock Text="{Binding
                                                                                              Introduction
            NonExistingProperty, ElementName=pnlMain}" />
                                                                                              The Window
            	</Grid>
                                                                                              Working with App.xaml
            </Window>
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
          
The Output window
          
The first place you will want to look is the Visual Studio Output window. It
           should be at the bottom of your Visual Studio window, or you can activate it      Basic controls
           by using the [Ctrl+Alt+O] shortcut. There will be loads of output from the         The TextBlock control
           debugger, but somewhere you should find a line like this, when running the         The TextBlock control - Inline
           above
example:                                                                     formatting
                                                                                              The Label control
          
System.Windows.Data Error: 40 : BindingExpression path error:                      The TextBox control
           'NonExistingProperty' property not found on 'object' ''Grid' (Name='pnlMain')'.    The CheckBox control
           BindingExpression:Path=NonExistingProperty; DataItem='Grid'
          
This might seem a bit overwhelming, mainly because no linebreaks are used
           in this long message, but the important part is this:
                                                                                               Panels
                                                                                                Introduction to WPF Panels
          'NonExistingProperty' property not found on 'object' ''Grid' (Name='pnlMain')'.       The Canvas
                                                                                                The WrapPanel
          
It tells you that you have tried to use a property called "NonExistingProperty"      The StackPanel
           on an object of the type Grid, with the name pnlMain. That's actually
pretty         The DockPanel
           concise and should help you correct the name of the property or bind to the          The Grid
           real object, if that's the problem.                                                  The Grid - Rows & Columns
                                                                                                The Grid - Units
          
Adjusting the trace level                                                            The Grid - Spanning
          
The above example was easy to fix, because it was clear to WPF what we               The Grid - GridSplitter
           were trying to do and why it didn't work. Consider this next example though:         Using the Grid: A contact
                                                                                                 form
            <Window
            x:Class="WpfTutorialSamples.DataBinding.DataBindingDebugging
                                                                                               Data binding
                                                                                                Introduction
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                        Hello, bound world!
                                                                                                Using the DataContext
                                                                                                The UpdateSourceTrigger
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                               property
                        Title="DataBindingDebuggingSample" Height="100"                         Responding to changes
            Width="200">                                                                        Value conversion with
                  <Grid Margin="10">                                                             IValueConverter
            		                     <TextBlock Text="{Binding Title}" />                         The StringFormat property
            	</Grid>                                                                            Debugging data bindings
            </Window>
                                                                                               Commands
          
I'm trying to bind to the property "Title", but on which object? As stated in the    Introduction
           article on data contexts, WPF will use the DataContext property on the               Using commands
           TextBlock here, which may be inherited down the control hierarchy, but in            Implementing custom
           this example, I forgot to assign a data context. This basically means that I'm        commands
           trying to get a property on a NULL object. WPF will gather that this might be
           a perfectly valid binding, but that the object just hasn't been initialized
yet,
           and therefore it won't complain about it. If you run this example and look in       Common interface
           the Output window, you won't see any binding errors.                                controls
          
However, for the cases where this is not the behavior that you're expecting,         The Menu control
           there is a way to force WPF into telling you about all the binding problems it       The ContextMenu
           runs into. It can be done by setting the TraceLevel on the                           The ToolBar control
           PresentationTraceSources object, which can be found in the                           The StatusBar control
           System.Diagnostics namespace:                                                        The Ribbon Control
            <Window
            x:Class="WpfTutorialSamples.DataBinding.DataBindingDebugging                       Rich Text controls
                                                                                            Introduction
                                                                                            The
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     FlowDocumentScrollViewer
                                                                                             control
                                                                                            The
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           FlowDocumentPageViewer
                        xmlns:diag="clr-                                                     control
            namespace:System.Diagnostics;assembly=WindowsBase"                              The FlowDocumentReader
                        Title="DataBindingDebuggingSample" Height="100"                      control
            Width="200">                                                                    Creating a FlowDocument
                  <Grid Margin="10">                                                         from Code-behind
            		                     <TextBlock Text="{Binding Title,                         Advanced FlowDocument
            diag:PresentationTraceSources.TraceLevel=High}" />                               content
            	</Grid>                                                                        The RichTextBox control
            </Window>
                                                                                          Misc. controls
          
Notice that I have added a reference to the System.Diagnostics namespace         The Border control
           in the top, and then used the property on the binding. WPF will now give you     The Slider control
           loads
of information about this specific binding in the Output window:           The ProgressBar control
                                                                                            The WebBrowser control
            System.Windows.Data Warning: 55 : Created                                       The WindowsFormsHost
            BindingExpression (hash=2902278) for Binding                                    control
            (hash=52760599)
            System.Windows.Data Warning: 57 :            Path: 'Title'
            System.Windows.Data Warning: 59 : BindingExpression                           The TabControl
            (hash=2902278): Default mode resolved to OneWay
                                                                                            Using the TabControl
            System.Windows.Data Warning: 60 : BindingExpression
                                                                                            Tab positions
            (hash=2902278): Default update trigger resolved to
                                                                                            Styling the TabItems
            PropertyChanged
            System.Windows.Data Warning: 61 : BindingExpression
            (hash=2902278): Attach to
                                                                                          List controls
            System.Windows.Controls.TextBlock.Text (hash=18876224)
            System.Windows.Data Warning: 66 : BindingExpression                             The ItemsControl
            (hash=2902278): Resolving source                                                The ListBox control
            System.Windows.Data Warning: 69 : BindingExpression                             The ComboBox control
            (hash=2902278): Found data context element: TextBlock
            (hash=18876224) (OK)
            System.Windows.Data Warning: 70 : BindingExpression                           The ListView control
            (hash=2902278): DataContext is null                                             Introduction
            System.Windows.Data Warning: 64 : BindingExpression                             A simple ListView
            (hash=2902278): Resolve source deferred                                         ListView, data binding and
            System.Windows.Data Warning: 66 : BindingExpression                              ItemTemplate
            (hash=2902278): Resolving source                                                ListView with a GridView
            System.Windows.Data Warning: 69 : BindingExpression                             How-to: Left aligned column
            (hash=2902278): Found data context element: TextBlock                            names
            (hash=18876224) (OK)                                                            ListView grouping
            System.Windows.Data Warning: 70 : BindingExpression                             ListView sorting
            (hash=2902278): DataContext is null                                             How-to: ListView with
            System.Windows.Data Warning: 66 : BindingExpression                              column sorting
            (hash=2902278): Resolving source
                                                                                             ListView filtering
            System.Windows.Data Warning: 69 : BindingExpression
            (hash=2902278): Found data context element: TextBlock
            (hash=18876224) (OK)
                                                                                            The TreeView control
            System.Windows.Data Warning: 70 : BindingExpression
            (hash=2902278): DataContext is null                                              Introduction
            System.Windows.Data Warning: 66 : BindingExpression                              A simple TreeView
            (hash=2902278): Resolving source                                                 TreeView, data binding and
            System.Windows.Data Warning: 69 : BindingExpression                               multiple templates
            (hash=2902278): Found data context element: TextBlock                            Handling
            (hash=18876224) (OK)                                                              Selection/Expansion state
            System.Windows.Data Warning: 70 : BindingExpression                              Lazy loading TreeView items
            (hash=2902278): DataContext is null
            System.Windows.Data Warning: 66 : BindingExpression
            (hash=2902278): Resolving source            (last chance)                       The DataGrid control
            System.Windows.Data Warning: 69 : BindingExpression                              Introduction
            (hash=2902278): Found data context element: TextBlock                            Custom columns
            (hash=18876224) (OK)                                                             Details row
            System.Windows.Data Warning: 77 : BindingExpression
            (hash=2902278): Activate with root item <null>
            System.Windows.Data Warning: 105 : BindingExpression                            Styles
            (hash=2902278):           Item at level 0 is null - no accessor
                                                                                             Introduction
            System.Windows.Data Warning: 79 : BindingExpression
                                                                                             Using styles
            (hash=2902278): TransferValue - got raw value
                                                                                             Triggers
            {DependencyProperty.UnsetValue}
                                                                                             Multi triggers
            System.Windows.Data Warning: 87 : BindingExpression
                                                                                             Trigger animations
            (hash=2902278): TransferValue - using fallback/default
            value ''
            System.Windows.Data Warning: 88 : BindingExpression
            (hash=2902278): TransferValue - using final value ''                            Misc.
                                                                                             The DispatcherTimer
          
By reading through the list, you can actually see the entire process that WPF
           goes through to try to find a proper value for your TextBlock control.
Several
           times you will see it being unable to find a proper DataContext, and in the      Audio & Video
           end, it uses the default {DependencyProperty.UnsetValue} which
translates         Playing audio
           into an empty string.                                                             Playing video
                                                                                             How-to: Complete media
          
Using the real debugger                                                           player
                                                                                             Speech synthesis
          
The above trick can be great for diagnosing a bad binding, but for some
                                                                                             Speech recognition
           cases, it's easier and more pleasant to work with the real debugger. Bindings
          
doesn't natively support this, since they are being handled deep inside of
           WPF, but using a Converter, like shown in a previous article, you can actually
          
jump into this process and step through it. You don't really need a Converter
           that does anything useful, you just need a way into the binding process, and
           a dummy converter will get you there:
            <Window
            x:Class="WpfTutorialSamples.DataBinding.DataBindingDebugging
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:self="clr-
            namespace:WpfTutorialSamples.DataBinding"
                        Title="DataBindingDebuggingSample" Name="wnd"
            Height="100" Width="200">
            	<Window.Resources>
            		<self:DebugDummyConverter
            x:Key="DebugDummyConverter" />
            	</Window.Resources>
                  <Grid Margin="10">
            		                     <TextBlock Text="{Binding Title,
            ElementName=wnd, Converter={StaticResource
            DebugDummyConverter}}" />
            	</Grid>
            </Window>
            using System;
            using System.Windows;
            using System.Windows.Data;
            using System.Diagnostics;
            namespace WpfTutorialSamples.DataBinding
            {
            	           public partial class DataBindingDebuggingSample :
            Window
            	{
            		public DataBindingDebuggingSample()
            		{
            			InitializeComponent();
            		}
            	}
            			return value;
            		}
            	}
            }
          
In the Code-behind file, we define a DebugDummyConverter. In the
           Convert() and ConvertBack() methods, we call Debugger.Break(), which has
           the same effect
as setting a breakpoint in Visual Studio, and then return the
           value that was given to us untouched.
          
In the markup, we add a reference to our converter in the window resources
           and then we use it in our binding. In a real world application, you should
           define the converter in a file of its own and then add the reference to it in
           App.xaml, so that you may use it all over the application without having to
           create a new reference to it in each window, but for this example, the above
           should do just fine.
          
If you run the example, you will see that the debugger breaks as soon as
           WPF tries to fetch the value for the title of the window. You can now inspect
           the
values given to the Convert() method, or even change them before
           proceeding, using the standard debugging capabilities of Visual Studio.
          
If the debugger never breaks, it means that the converter is not used. This
           usually indicates that you have an invalid binding expression, which can be
           diagnosed and fixed using the methods described in the start of this article.
           The dummy-converter trick is only for testing valid binding expressions.
Previous Next
                                                                  
         
Download
                                                                   PDF!
                                                                                             
Back to Top
Home Contact Us
                                                                                          Download as PDF
       Introduction to WPF Commands
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
In a previous chapter of this tutorial, we talked about how to handle events,   About WPF
          e.g. when the user clicks on a button or a menu item. In a modern user
                                                                                           What is WPF?
          interface, it's typical for a function to be reachable from several places
                                                                                           WPF vs. WinForms
          though, invoked by different user actions.
         
For instance, if you have a typical interface with a main menu and a set of
          toolbars, an action like New or Open might be available in the menu, on the     Getting started
          toolbar, in a context menu (e.g. when right clicking in the main application     Visual Studio Express
          area) and from a keyboard shortcut like Ctrl+N and Ctrl+O.                       Hello, WPF!
         
Each of these actions needs to perform what is typically the exact same
          piece of code, so in a WinForms application, you would have to define an
                                                                                          XAML
          event for
each of them and then call a common function. With the above
          example, that would lead to at least three event handlers and some code to       What is XAML?
          handle the keyboard
shortcut. Not an ideal situation.                            Basic XAML
                                                                                           Events in XAML
         
Commands
         
With WPF, Microsoft is trying to remedy that with a concept called
                                                                                          A WPF application
          commands. It allows you to define actions in one place and then refer to
          them from all
your user interface controls like menu items, toolbar buttons      Introduction
          and so on. WPF will also listen for keyboard shortcuts and pass them along       The Window
          to the proper
command, if any, making it the ideal way to offer keyboard         Working with App.xaml
          shortcuts in an application.                                                     Command-line parameters
                                                                                           Resources
         
Commands also solve another hassle when dealing with multiple entrances          Handling exceptions
          to the same function. In a WinForms application, you would be responsible
          for
writing code that could disable user interface elements when the action
          was not available. For instance, if your application was able to use a          Basic controls
          clipboard
command like Cut, but only when text was selected, you would           The TextBlock control
          have to manually enable and disable the main menu item, the toolbar button       The TextBlock control - Inline
          and the context
menu item each time text selection changed.                      formatting
                                                                                           The Label control
         
With WPF commands, this is centralized. With one method you decide
                                                                                           The TextBox control
          whether or not a given command can be executed, and then WPF toggles all
                                                                                           The CheckBox control
          the subscribing
interface elements on or off automatically. This makes it so
         
Command bindings
         
Commands don't actually do anything by them self. At the root, they consist      Panels
          of the ICommand interface, which only defines an event and two methods:
                                                                                            Introduction to WPF Panels
          Execute() and CanExecute(). The first one is for performing the actual action,
                                                                                            The Canvas
          while the second one is for determining whether the action is currently
                                                                                            The WrapPanel
          available. To perform the actual action of the command, you need a link
                                                                                            The StackPanel
          between the command and your code and this is where the
                                                                                            The DockPanel
          CommandBinding comes into
play.
                                                                                            The Grid
                                                                                            The Grid - Rows & Columns
         
A CommandBinding is usually defined on a Window or a UserControl, and
                                                                                            The Grid - Units
          holds a references to the Command that it handles, as well as the actual
                                                                                            The Grid - Spanning
          event
handlers for dealing with the Execute() and CanExecute() events of the
                                                                                            The Grid - GridSplitter
          Command.
                                                                                            Using the Grid: A contact
         
Pre-defined commands                                                               form
         
You can of course implement your own commands, which we'll look into in
          one of the next chapters, but to make it easier for you, the WPF team has        Data binding
          defined
over 100 commonly used commands that you can use. They have
                                                                                            Introduction
          been divided into 5 categories, called ApplicationCommands,
                                                                                            Hello, bound world!
          NavigationCommands, MediaCommands,
EditingCommands and
                                                                                            Using the DataContext
          ComponentCommands. Especially ApplicationCommands contains
                                                                                            The UpdateSourceTrigger
          commands for a lot of very frequently used actions like New, Open, Save and
                                                                                             property
         
Cut, Copy and Paste.
                                                                                            Responding to changes
                                                                                            Value conversion with
         
Summary                                                                            IValueConverter
         
Commands help you to respond to a common action from several different            The StringFormat property
          sources, using a single event handler. It also makes it a lot easier to enable    Debugging data bindings
          and
disable user interface elements based on the current availability and
          state. This was all theory, but in the next chapters we'll discuss how
          commands are
used and how you define your own custom commands.                   Commands
                                                                                            Introduction
               Previous                                                     Next            Using commands
                                                                                            Implementing custom
                                                                                             commands
                                                             Introduction
                                                             The
                                                              FlowDocumentScrollViewer
                                                              control
                                                             The
                                                              FlowDocumentPageViewer
                                                              control
                                                             The FlowDocumentReader
                                                              control
                                                             Creating a FlowDocument
                                                              from Code-behind
                                                             Advanced FlowDocument
                                                              content
                                                             The RichTextBox control
                                                           Misc. controls
                                                             The Border control
                                                             The Slider control
                                                             The ProgressBar control
                                                             The WebBrowser control
                                                             The WindowsFormsHost
                                                             control
                                                           The TabControl
                                                             Using the TabControl
                                                             Tab positions
                                                             Styling the TabItems
                                                           List controls
                                                             The ItemsControl
                                                             The ListBox control
                                                             The ComboBox control
ListView filtering
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
                                                                                            Misc.
                                                                                             The DispatcherTimer
                                                                 
         
Download
                                                                  PDF!
                                                           
Back to Top
Home Contact Us
                                                                                         Download as PDF
       Using WPF commands
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         
In the previous article, we discussed a lot of theory about what commands      About WPF
          are and how they work. In this chapter, we'll look into how you actually use
                                                                                          What is WPF?
          commands, by assigning them to user interface elements and creating
                                                                                          WPF vs. WinForms
          command bindings that links it all together.
         
We'll start off with a very simple example:
                                                                                         Getting started
            <Window                                                                       Visual Studio Express
            x:Class="WpfTutorialSamples.Commands.UsingCommandsSample"                     Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                         XAML
                                                                                          What is XAML?
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                          Basic XAML
                       Title="UsingCommandsSample" Height="100"
                                                                                          Events in XAML
            Width="200">
                 <Window.CommandBindings>
                       <CommandBinding Command="ApplicationCommands.New"
                                                                                         A WPF application
            Executed="NewCommand_Executed"
            CanExecute="NewCommand_CanExecute" />                                         Introduction
                 </Window.CommandBindings>                                                The Window
                                                                                          Working with App.xaml
                 <StackPanel HorizontalAlignment="Center"                                 Command-line parameters
            VerticalAlignment="Center">                                                   Resources
                       <Button                                                            Handling exceptions
            Command="ApplicationCommands.New">New</Button>
                 </StackPanel>
            </Window>                                                                    Basic controls
                                                                                          The TextBlock control
                                                                                          The TextBlock control - Inline
                                                                                          formatting
            using System;
                                                                                          The Label control
            using System.Collections.Generic;
                                                                                          The TextBox control
            using System.Windows;
                                                                                          The CheckBox control
            using System.Windows.Input;
         
We define a command binding on the Window, by adding it to its
          CommandBindings collection. We specify that Command that we wish to use            Commands
          (the New command
from the ApplicationCommands), as well as two event
                                                                                              Introduction
          handlers. The visual interface consists of a single button, which we attach the
                                                                                              Using commands
          command to using the Command property.
                                                                                              Implementing custom
         
In Code-behind, we handle the two events. The CanExecute handler, which              commands
          WPF will call when the application is idle to see if the specific
command is
          currently available, is very simple for this example, as we want this particular
          command to be available all the time. This is done by setting
the                  Common interface
          CanExecute property of the event arguments to true.                                controls
                                                                                              The Menu control
         
The Executed handler simply shows a message box when the command is
                                                                                              The ContextMenu
          invoked. If you run the sample and press the button, you will see this
                                                                                              The ToolBar control
          message. A thing to notice is that this command has a default keyboard
                                                                                              The StatusBar control
          shortcut defined, which you get as an added bonus. Instead of clicking the
                                                                                              The Ribbon Control
          button,
you can try to press Ctrl+N on your keyboard - the result is the same.
         
Using the CanExecute method
                                                                                             Rich Text controls
         
In the first example, we implemented a CanExecute event that simply                  Introduction
          returned true, so that the button would be available all the time. However, this     The
          is of
course not true for all buttons - in many cases, you want the button to be      FlowDocumentScrollViewer
          enabled or disabled depending on some sort of state in your application.              control
                                                                                               The
         
A very common example of this is the toggling of buttons for using the
                                                                                                FlowDocumentPageViewer
          Windows Clipboard, where you want the Cut and Copy buttons to be enabled
                                                                                                control
          only when
text is selected, and the Paste button to only be enabled when text
                                                                                               The FlowDocumentReader
          is present in the clipboard. This is exactly what we'll accomplish in this
                                                                                                control
          example:
                                                                                               Creating a FlowDocument
                                                                                                from Code-behind
            <Window                                                                            Advanced FlowDocument
            x:Class="WpfTutorialSamples.Commands.CommandCanExecuteSample                        content
                                                                                               The RichTextBox control
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             Misc. controls
                                                                                               The Border control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                               The Slider control
                       Title="CommandCanExecuteSample" Height="200"
                                                                                               The ProgressBar control
            Width="250">
                                                                                               The WebBrowser control
                 <Window.CommandBindings>
                                                                                               The WindowsFormsHost
                       <CommandBinding Command="ApplicationCommands.Cut"
                                                                                               control
            CanExecute="CutCommand_CanExecute"
            Executed="CutCommand_Executed" />
                       <CommandBinding
            Command="ApplicationCommands.Paste"                                              The TabControl
            CanExecute="PasteCommand_CanExecute"                                               Using the TabControl
            Executed="PasteCommand_Executed" />                                                Tab positions
                 </Window.CommandBindings>                                                     Styling the TabItems
                 <DockPanel>
                       <WrapPanel DockPanel.Dock="Top" Margin="3">
                            <Button Command="ApplicationCommands.Cut"                        List controls
            Width="60">_Cut</Button>
                                                                                               The ItemsControl
                            <Button Command="ApplicationCommands.Paste"
                                                                                               The ListBox control
            Width="60" Margin="3,0">_Paste</Button>
                                                                                               The ComboBox control
                       </WrapPanel>
                       <TextBox AcceptsReturn="True" Name="txtEditor" />
                 </DockPanel>
            </Window>
                                                                                             The ListView control
                                                                                               Introduction
                                                                                               A simple ListView
                                                                                               ListView, data binding and
            using System;                                                                       ItemTemplate
            using System.Collections.Generic;                                                  ListView with a GridView
            using System.Windows;                                                              How-to: Left aligned column
            using System.Windows.Input;                                                         names
                                                                                               ListView grouping
            namespace WpfTutorialSamples.Commands                                              ListView sorting
            {                                                                                  How-to: ListView with
            	          public partial class CommandCanExecuteSample :                           column sorting
         
So, we have this very simple interface with a couple of buttons and a
          TextBox control. The first button will cut to the clipboard and the second one
          will
paste from it.
         
In Code-behind, we have two events for each button: One that performs the
          actual action, which name ends with _Executed, and then the CanExecute
          events. In
each of them, you will see that I apply some logic to decide
          whether or not the action can be executed and then assign it to the return
          value CanExecute on the EventArgs.
         
The cool thing about this is that you don't have to call these methods to have
          your buttons updated - WPF does it automatically when the application has
          an
idle moment, making sure that you interface remains updated all the time.
         
Default command behavior and
          CommandTarget
         
As we saw in the previous example, handling a set of commands can lead to
          quite a bit of code, with a lot of being method declarations and very standard
          logic. That's probably why the WPF team decided to handle some it for you.
          In fact, we could have avoided all of the Code-behind in the previous
          example,
because a WPF TextBox can automatically handle common
          commands like Cut, Copy, Paste, Undo and Redo.
         
WPF does this by handling the Executed and CanExecute events for you,
          when a text input control like the TextBox has focus. You are free to override
          these
events, which is basically what we did in the previous example, but if
          you just want the basic behavior, you can let WPF connect the commands
          and the
TextBox control and do the work for you. Just see how much simpler
          this example is:
            <Window
            x:Class="WpfTutorialSamples.Commands.CommandsWithCommandTarg
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="CommandsWithCommandTargetSample"
            Height="200" Width="250">
                 <DockPanel>
                       <WrapPanel DockPanel.Dock="Top" Margin="3">
                            <Button Command="ApplicationCommands.Cut"
            CommandTarget="{Binding ElementName=txtEditor}"
            Width="60">_Cut</Button>
                            <Button Command="ApplicationCommands.Paste"
            CommandTarget="{Binding ElementName=txtEditor}" Width="60"
             Margin="3,0">_Paste</Button>
                       </WrapPanel>
                       <TextBox AcceptsReturn="True" Name="txtEditor" />
                 </DockPanel>
            </Window>
         
No Code-behind code needed for this example - WPF deals with all of it for
          us, but only because we want to use these specific commands for this
          specific
control. The TextBox does the work for us.
         
Notice how I use the CommandTarget properties on the buttons, to bind the
          commands to our TextBox control. This is required in this
particular example,
          because the WrapPanel doesn't handle focus the same way e.g. a Toolbar or
          a Menu would, but it also makes pretty good sense to give the
commands a
          target.
         
Summary
         
Dealing with commands is pretty straight forward, but does involve a bit extra
          markup and code. The reward is especially obvious when you need to invoke
         
the same action from multiple places though, or when you use built-in
          commands that WPF can handle completely for you, as we saw in the last
          example.
Previous Next
                                                                
         
Download
                                                                 PDF!
                                                                                           
Back to Top
Home Contact Us
                                                                                           Download as PDF
       Implementing a custom WPF
        Command                                                                                   Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
                                                                                           About WPF
         
In the previous chapter, we looked at various ways of using commands
                                                                                            What is WPF?
          already defined in WPF, but of course you can implement your own
                                                                                            WPF vs. WinForms
          commands as well.
It's pretty simply, and once you've done it, you can use
          your own commands just like the ones defined in WPF.
         
The easiest way to start implementing your own commands is to have a             Getting started
          static class that will contain them. Each command is then added to this class     Visual Studio Express
          as static fields, allowing you to use them in your application. Since WPF, for    Hello, WPF!
          some strange reason, doesn't implement an Exit/Quit command, I decided to
          implement one for our custom commands example. It looks like this:
                                                                                           XAML
            <Window
                                                                                            What is XAML?
            x:Class="WpfTutorialSamples.Commands.CustomCommandSample"
                                                                                            Basic XAML
                                                                                            Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:self="clr-                                                     Introduction
            namespace:WpfTutorialSamples.Commands"                                          The Window
                       Title="CustomCommandSample" Height="150"                             Working with App.xaml
            Width="200">                                                                    Command-line parameters
                 <Window.CommandBindings>                                                   Resources
                       <CommandBinding Command="self:CustomCommands.Exit"                   Handling exceptions
             CanExecute="ExitCommand_CanExecute"
            Executed="ExitCommand_Executed" />
                 </Window.CommandBindings>                                                 Basic controls
                 <Grid>                                                                     The TextBlock control
                       <Grid.RowDefinitions>                                                The TextBlock control - Inline
                            <RowDefinition Height="Auto" />                                 formatting
                            <RowDefinition Height="*" />                                    The Label control
                       </Grid.RowDefinitions>                                               The TextBox control
                       <Menu>                                                               The CheckBox control
                            <MenuItem Header="File">
            				{                                                                                Introduction
            					new                                                                             The
            KeyGesture(Key.F4, ModifierKeys.Alt)                                                  FlowDocumentScrollViewer
            				}                                                                                 control
            			);                                                                                The
                                                                                                  FlowDocumentPageViewer
            		                     //Define more commands here, just like the                     control
             one above                                                                           The FlowDocumentReader
            	}                                                                                    control
            }                                                                                    Creating a FlowDocument
                                                                                                  from Code-behind
                                                                                                 Advanced FlowDocument
                                                                                                  content
                                                                                                 The RichTextBox control
                                                                                               Misc. controls
                                                                                                 The Border control
                                                                                                 The Slider control
                                                                                                 The ProgressBar control
         
In the markup, I've defined a very simple interface with a menu and a button,          The WebBrowser control
          both of them using our new, custom Exit command. This command is defined               The WindowsFormsHost
          in
Code-behind, in our own CustomCommands class, and then referenced                   control
          in the CommandBindings collection of the window, where we assign the
          events that it should use to execute/check if it's allowed to execute.
                                                                                               The TabControl
         
All of this is just like the examples in the previous chapter, except for the fact
          that we're referencing the command from our own code (using the "self"                 Using the TabControl
          namespace defined in the top) instead of a built-in command.                           Tab positions
                                                                                                 Styling the TabItems
         
In Code-behind, we respond to the two events for our command: One event
          just allows the command to execute all the time, since that's usually true for
          an
exit/quit command, and the other one calls the Shutdown method that will          List controls
          terminate our application. All very simple.
                                                                                                 The ItemsControl
                                                                                                 The ListBox control
         
As already explained, we implement our Exit command as a field on a static
                                                                                                 The ComboBox control
          CustomCommands class. There are several ways of defining and assigning
          properties on the commands, but I've chosen the more compact approach (it
          would be even more compact if placed on the same line, but I've added line
          breaks
here for readability) where I assign all of it through the constructor.       The ListView control
          The parameters are the text/label of the command, the name of the                      Introduction
          command, the
owner type and then an InputGestureCollection, allowing me                A simple ListView
          to define a default shortcut for the command (Alt+F4).                                 ListView, data binding and
                                                                                                  ItemTemplate
         
Summary                                                                                ListView with a GridView
                                                                                                 How-to: Left aligned column
         
Implementing custom WPF commands is almost as easy as consuming the
                                                                                                  names
          built-in commands, and it allows you to use commands for every purpose in
                                                                                                 ListView grouping
          your
application. This makes it very easy to re-use actions in several places,
                                                                                                 ListView sorting
          as shown in the example of this chapter.
                                                                                                 How-to: ListView with
                                                                                                  column sorting
                                                                                             Styles
                                                                                              Introduction
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
                                                                                              Trigger animations
                                                                                             Misc.
                                                                                              The DispatcherTimer
                                                                  
         
Download
                                                                PDF!
                                                                       
Back to Top
Home Contact Us
                                                                                             Download as PDF
       The WPF Menu control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         
One of the most common parts of a Windows application is the menu,                 About WPF
          sometimes referred to as the main menu because only one usually exists in
                                                                                              What is WPF?
          the
application. The menu is practical because it offers a lot of options, using
                                                                                              WPF vs. WinForms
          only very little space, and even though Microsoft is pushing the Ribbon as a
          replacement for the good, old menu and toolbars, they definitely still have
          their place in every good developer's toolbox.
                                                                                             Getting started
         
WPF comes with a fine control for creating menus called... Menu. Adding             Visual Studio Express
          items to it is very simple - you simply add MenuItem elements to it, and each       Hello, WPF!
          MenuItem can have a range of sub-items, allowing you to create hierarchical
          menus as you know them from a lot of Windows applications. Let's jump
          straight
to an example where we use the Menu:
                                                                                             XAML
                                                                                              What is XAML?
            <Window
                                                                                              Basic XAML
            x:Class="WpfTutorialSamples.Common_interface_controls.MenuSa
                                                                                              Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             A WPF application
                                                                                              Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            The Window
                       Title="MenuSample" Height="200" Width="200">                           Working with App.xaml
                 <DockPanel>                                                                  Command-line parameters
                       <Menu DockPanel.Dock="Top">                                            Resources
                            <MenuItem Header="_File">                                         Handling exceptions
                                   <MenuItem Header="_New" />
                                   <MenuItem Header="_Open" />
                                   <MenuItem Header="_Save" />                               Basic controls
                                   <Separator />                                              The TextBlock control
                                   <MenuItem Header="_Exit" />                                The TextBlock control - Inline
                            </MenuItem>                                                       formatting
                       </Menu>                                                                The Label control
                       <TextBox AcceptsReturn="True" />                                       The TextBox control
                 </DockPanel>                                                                 The CheckBox control
            </Window>
                                                                                            Panels
                                                                                             Introduction to WPF Panels
                                                                                             The Canvas
                                                                                             The WrapPanel
                                                                                             The StackPanel
                                                                                             The DockPanel
                                                                                             The Grid
                                                                                             The Grid - Rows & Columns
                                                                                             The Grid - Units
                                                                                             The Grid - Spanning
         
As in most Windows applications, my menu is placed in the top of the               The Grid - GridSplitter
          window, but in keeping with the enormous flexibility of WPF, you can actually      Using the Grid: A contact
          place a
Menu control wherever you like, and in any width or height that you         form
          may desire.
         
I have defined a single top-level item, with 4 child items and a separator. I
                                                                                            Data binding
          use the Header property to define the label of the item, and
you should
          notice the underscore before the first character of each label. It tells WPF to    Introduction
          use that character as the accelerator key, which means that the
user can           Hello, bound world!
          press the Alt key followed by the given character, to activate the menu item.      Using the DataContext
          This works all the way from the top-level item and down the
hierarchy,             The UpdateSourceTrigger
          meaning that in this example I could press Alt, then F and then N, to activate      property
          the New item.                                                                      Responding to changes
                                                                                             Value conversion with
         
Icons and checkboxes                                                                IValueConverter
                                                                                             The StringFormat property
         
Two common features of a menu item is the icon, used to more easily identify       Debugging data bindings
          the menu item and what it does, and the ability to have checkable menu
          items,
which can toggle a specific feature on and off. The WPF MenuItem
          supports both, and it's very easy to use:
                                                                                            Commands
                                                                                             Introduction
            <Window
                                                                                             Using commands
            x:Class="WpfTutorialSamples.Common_interface_controls.MenuIc
                                                                                             Implementing custom
                                                                                              commands
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            Common interface
                                                                                            controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="MenuIconCheckableSample" Height="150"                          The Menu control
            Width="300">                                                                     The ContextMenu
                 <DockPanel>                                                                 The ToolBar control
                       <Menu DockPanel.Dock="Top">                                           The StatusBar control
                            <MenuItem Header="_File">                                        The Ribbon Control
                                   <MenuItem Header="_Exit" />
                            </MenuItem>
                            <MenuItem Header="_Tools">                                      Rich Text controls
                                                                                         Misc. controls
                                                                                           The Border control
                                                                                           The Slider control
                                                                                           The ProgressBar control
                                                                                           The WebBrowser control
                                                                                           The WindowsFormsHost
                                                                                           control
         
For this example I've created a secondary top-level item, where I've added
          two items: One with an icon defined, using the Icon property
with a standard
          Image control inside of it, and one where we use the IsCheckable property      The TabControl
          to allow the user to check and uncheck the item.
I even used the IsChecked       Using the TabControl
          property to have it checked by default. From Code-behind, this is the same       Tab positions
          property that you can read to know
whether a given menu item is checked or       Styling the TabItems
          not.
         
Handling clicks                                                                List controls
         
When the user clicks on a menu item, you will usually want something to          The ItemsControl
          happen. The easiest way is to simply add a click event handler to the            The ListBox control
          MenuItem,
like this:                                                             The ComboBox control
ListView filtering
         
Keyboard shortcuts and Commands
         
You can easily handle the Click event of a menu item like we did above, but         The TreeView control
          the more common approach is to use WPF commands. There's a lot of                    Introduction
          theory on
using and creating commands, so they have their own category of            A simple TreeView
          articles here on the site, but for now, I can tell you that they have a couple of    TreeView, data binding and
          advantages when used in WPF, especially in combination with a Menu or a               multiple templates
          Toolbar.                                                                             Handling
                                                                                                Selection/Expansion state
         
First of all, they ensure that you can have the same action on a toolbar, a
                                                                                               Lazy loading TreeView items
          menu and even a context menu, without having to implement the same code
          in
multiple places. They also make the handling of keyboard shortcuts a
          whole lot easier, because unlike with WinForms, WPF is not listening for
          keyboard
shortcuts automatically if you assign them to e.g. a menu item - you
                                                                                              The DataGrid control
          will have to do that manually.                                                       Introduction
                                                                                               Custom columns
         
However, when using commands, WPF is all ears and will respond to                    Details row
          keyboard shortcuts automatically. The text (Header) of the menu item is also
          set
automatically (although you can overwrite it if needed), and so is the
          InputGestureText, which shows the user which keyboard shortcut can be               Styles
          used to invoke
the specific menu item. Let's jump straight to an example of
                                                                                               Introduction
          combining the Menu with WPF commands:
                                                                                               Using styles
                                                                                               Triggers
            <Window                                                                            Multi triggers
            x:Class="WpfTutorialSamples.Common_interface_controls.MenuWi
                                                                                               Trigger animations
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Misc.
                                                                                               The DispatcherTimer
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="MenuWithCommandsSample" Height="200"
            Width="300">                                                                      Audio & Video
                 <Window.CommandBindings>                                                      Playing audio
                       <CommandBinding Command="New"                                           Playing video
            CanExecute="NewCommand_CanExecute"                                                 How-to: Complete media
            Executed="NewCommand_Executed" />                                                  player
                 </Window.CommandBindings>                                                     Speech synthesis
                 <DockPanel>                                                                   Speech recognition
                       <Menu DockPanel.Dock="Top">
                            <MenuItem Header="_File">
                                   <MenuItem Command="New" />
                                   <Separator />
                                   <MenuItem Header="_Exit" />
                            </MenuItem>
                            <MenuItem Header="_Edit">
                                   <MenuItem Command="Cut" />
                                   <MenuItem Command="Copy" />
                                   <MenuItem Command="Paste" />
                            </MenuItem>
</Menu>
            using System;
            using System.Windows;
            using System.Windows.Input;
            namespace WpfTutorialSamples.Common_interface_controls
            {
            	          public partial class MenuWithCommandsSample :
            Window
            	{
            		public MenuWithCommandsSample()
            		{
            			InitializeComponent();
            		}
         
It might not be completely obvious, but by using commands, we just got a
          whole bunch of things for free: Keyboard shortcuts, text and
          InputGestureText on the items and WPF automatically enables/disables the
         
And because WPF knows how to handle certain commands in combination
          with certain controls, in this case the Cut/Copy/Paste commands in
          combination with a
text input control, we don't even have to handle their
          Execute events - they work right out of the box! We do have to handle it for
          theNew command though, since WPF has no way of guessing what we want
          it to do when the user activates it. This is done with the CommandBindings
          of the Window, all explained in detail in the chapter on commands.
         
Summary
         
Working with the WPF Menu control is both easy and fast, making it simple to
          create even complex menu hierarchies, and when combining it with WPF
          commands,
you get so much functionality for free.
Previous Next
                                                                 
         
Download
                                                                  PDF!
                                                                                            
Back to Top
Home Contact Us
                                                                                                Download as PDF
       The WPF ContextMenu
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
         
A context menu, often referred to as a popup or pop-up menu, is a menu                About WPF
          which is shown upon certain user actions, usually a right-click with the mouse
                                                                                                 What is WPF?
          on a
specific control or window. Contextual menus are often used to offer
                                                                                                 WPF vs. WinForms
          functionality that's relevant within a single control.
         
WPF comes with a ContextMenu control and because it's almost always tied
          to a specific control, that's also usually how you add it to the interface. This
is   Getting started
          done through the ContextProperty, which all controls exposes (it comes from            Visual Studio Express
          the FrameworkElement which most WPF controls inherits from). Consider the              Hello, WPF!
         
next example to see how it's done:
            <Window                                                                             XAML
            x:Class="WpfTutorialSamples.Common_interface_controls.Contex
                                                                                                 What is XAML?
                                                                                                 Basic XAML
                                                                                                 Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ContextMenuSample" Height="250"                                    Introduction
            Width="250">                                                                         The Window
                 <Grid>                                                                          Working with App.xaml
                       <Button Content="Right-click me!"                                         Command-line parameters
            VerticalAlignment="Center" HorizontalAlignment="Center">                             Resources
                            <Button.ContextMenu>                                                 Handling exceptions
                                   <ContextMenu>
                                       <MenuItem Header="Menu item 1" />
                                       <MenuItem Header="Menu item 2" />                        Basic controls
                                       <Separator />                                             The TextBlock control
                                       <MenuItem Header="Menu item 3" />                         The TextBlock control - Inline
                                   </ContextMenu>                                                formatting
                            </Button.ContextMenu>                                                The Label control
                       </Button>                                                                 The TextBox control
                 </Grid>                                                                         The CheckBox control
            </Window>
                                                                                          Panels
                                                                                           Introduction to WPF Panels
                                                                                           The Canvas
                                                                                           The WrapPanel
                                                                                           The StackPanel
                                                                                           The DockPanel
                                                                                           The Grid
                                                                                           The Grid - Rows & Columns
                                                                                           The Grid - Units
                                                                                           The Grid - Spanning
                                                                                           The Grid - GridSplitter
                                                                                           Using the Grid: A contact
                                                                                            form
         
If you've already read the chapter on the regular menu, you will soon realize
          that the ContextMenu works exactly the same way, and no wonder, since
          they
both inherit the MenuBase class. Just like we saw in the examples on
          using the regular Menu, you can of course add Click events to these items to    Data binding
          handle
when the user clicks on them, but a more WPF-suitable way is to use       Introduction
          Commands.                                                                        Hello, bound world!
                                                                                           Using the DataContext
         
ContextMenu with Commands and icons                                              The UpdateSourceTrigger
                                                                                            property
         
In this next example, I'm going to show you two key concepts when using the
                                                                                           Responding to changes
          ContextMenu: The usage of WPF Commands, which will provide us with lots
                                                                                           Value conversion with
          of
functionality including a Click event handler, a text and a shortcut text,
                                                                                            IValueConverter
          simply by assigning something to the Command property. I will also show
                                                                                           The StringFormat property
          you to
use icons on your ContextMenu items. Have a look:
                                                                                           Debugging data bindings
            <Window
            x:Class="WpfTutorialSamples.Common_interface_controls.Contex
                                                                                          Commands
                                                                                           Introduction
                                                                                           Using commands
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Implementing custom
                                                                                            commands
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ContextMenuWithCommandsSample" Height="200"
             Width="250">                                                                 Common interface
                 <StackPanel Margin="10">                                                 controls
                       <TextBox Text="Right-click here for context                         The Menu control
            menu!">                                                                        The ContextMenu
                            <TextBox.ContextMenu>                                          The ToolBar control
                                   <ContextMenu>                                           The StatusBar control
                                       <MenuItem Command="Cut">                            The Ribbon Control
                                           <MenuItem.Icon>
                                                  <Image
            Source="/WpfTutorialSamples;component/Images/cut.png" />                      Rich Text controls
                                           </MenuItem.Icon>
                                                                                              Introduction
                                       </MenuItem>
                                                                                              The
                                       <MenuItem Command="Copy">
                                                                                               FlowDocumentScrollViewer
                                           <MenuItem.Icon>
                                                                                               control
                                                  <Image
                                                                                              The
            Source="/WpfTutorialSamples;component/Images/copy.png" />
                                                                                               FlowDocumentPageViewer
                                           </MenuItem.Icon>
                                                                                               control
                                       </MenuItem>
                                                                                              The FlowDocumentReader
                                       <MenuItem Command="Paste">
                                                                                               control
                                           <MenuItem.Icon>
                                                                                              Creating a FlowDocument
                                                  <Image
                                                                                               from Code-behind
            Source="/WpfTutorialSamples;component/Images/paste.png" />
                                                                                              Advanced FlowDocument
                                           </MenuItem.Icon>
                                                                                               content
                                       </MenuItem>
                                                                                              The RichTextBox control
                                   </ContextMenu>
                            </TextBox.ContextMenu>
                       </TextBox>
                                                                                            Misc. controls
                 </StackPanel>
            </Window>                                                                         The Border control
                                                                                              The Slider control
                                                                                              The ProgressBar control
                                                                                              The WebBrowser control
                                                                                              The WindowsFormsHost
                                                                                              control
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
         
Try running the example and see for yourself how much functionality we get        List controls
          for free by assigning commands to the items. Also notice how fairly simple it       The ItemsControl
          is
to use icons on the menu items of the ContextMenu.                               The ListBox control
                                                                                              The ComboBox control
         
Invoke ContextMenu from Code-behind
         
So far, the ContextMenu has been invoked when right-clicking on the control
          to which it belongs. WPF does this for us automatically, when we assign it to     The ListView control
          the ContextMenu property. However, in some situations, you might very well          Introduction
          want to invoke it manually from code. This is pretty easy as
well, so let's re-     A simple ListView
         use the first example to demonstrate it with:                                        ListView, data binding and
                                                                                               ItemTemplate
            <Window                                                                           ListView with a GridView
            x:Class="WpfTutorialSamples.Common_interface_controls.Contex                      How-to: Left aligned column
                                                                                               names
                                                                                              ListView grouping
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      ListView sorting
                                                                                              How-to: ListView with
                                                                                               column sorting
         
The first thing you should notice is that I've moved the ContextMenu away
          from the button. Instead, I've added it as a resource of the Window, to make
          it
available from all everywhere within the Window. This also makes it a lot
          easier to find when we need to show it.
         
The Button now has a Click event handler, which I handle in Code-behind.
          From there, I simply find the ContextMenu instance within the window
          resources and
then I do two things: I set it's PlacementTarget property, which
          tells WPF which element it should calculate the position based on, and then I
          set the
IsOpen to true, to open the menu. That's all you need!
Previous Next
                                                                
         
Download
                                                                 PDF!
                                                                                           
Back to Top
Home Contact Us
                                                                                            Download as PDF
       The WPF ToolBar control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
The toolbar is a row of commands, usually sitting right below the main menu       About WPF
          of a standard Windows application. This could in fact be a simple panel with
                                                                                             What is WPF?
          buttons on it, but by using the WPF ToolBar control, you get some extra
                                                                                             WPF vs. WinForms
          goodies like automatic overflow handling and the possibility for the end-user
          to
re-position your toolbars.
         
A WPF ToolBar is usually placed inside of a ToolBarTray control. The              Getting started
          ToolBarTray will handle stuff like placement and sizing, and you can have          Visual Studio Express
          multiple
ToolBar controls inside of the ToolBarTray element. Let's try a pretty    Hello, WPF!
          basic example, to see what it all looks like:
            <Window                                                                         XAML
            x:Class="WpfTutorialSamples.Common_interface_controls.Toolba
                                                                                             What is XAML?
                                                                                             Basic XAML
                                                                                             Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ToolbarSample" Height="200" Width="300">                       Introduction
                  <Window.CommandBindings>                                                   The Window
                       <CommandBinding Command="New"                                         Working with App.xaml
            CanExecute="CommonCommandBinding_CanExecute" />                                  Command-line parameters
                       <CommandBinding Command="Open"                                        Resources
            CanExecute="CommonCommandBinding_CanExecute" />                                  Handling exceptions
                       <CommandBinding Command="Save"
            CanExecute="CommonCommandBinding_CanExecute" />
                  </Window.CommandBindings>                                                 Basic controls
                  <DockPanel>                                                                The TextBlock control
                       <ToolBarTray DockPanel.Dock="Top">                                    The TextBlock control - Inline
                             <ToolBar>                                                       formatting
                                   <Button Command="New" Content="New" />                    The Label control
                                   <Button Command="Open" Content="Open" />                  The TextBox control
                                   <Button Command="Save" Content="Save" />                  The CheckBox control
                             </ToolBar>
                                                                                     Common interface
                                                                                     controls
                                                                                      The Menu control
                                                                                      The ContextMenu
                                                                                      The ToolBar control
         
Notice how I use commands for all the buttons. We discussed this in the     The StatusBar control
          previous chapter and using commands definitely gives us some advantages.    The Ribbon Control
          Take a
look at the Menu chapter, or the articles on commands, for more
          information.
                                                                                     Rich Text controls
         
In this example, I add a ToolBarTray to the top of the screen, and inside of it,     Introduction
          two ToolBar controls. Each contains some buttons and we use commands to              The
          give them their behavior. In Code-behind, I make sure to handle the                   FlowDocumentScrollViewer
          CanExecute event of the first three buttons, since that's not done                    control
          automatically by
WPF, contrary to the Cut, Copy and Paste commands,                  The
          which WPF is capable of fully handling for us.                                        FlowDocumentPageViewer
                                                                                                control
         
Try running the example and place the cursor over the left part of one of the
                                                                                               The FlowDocumentReader
          toolbars (the dotted area). If you click and hold your left mouse button, you
                                                                                                control
          can now re-position the toolbar, e.g. below the other or even make them
                                                                                               Creating a FlowDocument
          switch place.
                                                                                                from Code-behind
         
Images                                                                               Advanced FlowDocument
                                                                                                content
         
While text on the toolbar buttons is perfectly okay, the normal approach is to       The RichTextBox control
          have icons or at least a combination of an icon and a piece of text. Because
          WPF uses regular Button controls, adding icons to the toolbar items is very
          easy. Just have a look at this next example, where we do both:                     Misc. controls
                                                                                               The Border control
            <Window                                                                            The Slider control
            x:Class="WpfTutorialSamples.Common_interface_controls.Toolba                       The ProgressBar control
                                                                                               The WebBrowser control
                                                                                               The WindowsFormsHost
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                             The TabControl
                       Title="ToolbarIconSample" Height="200"
                                                                                               Using the TabControl
            Width="300">
                                                                                               Tab positions
                  <DockPanel>
                                                                                               Styling the TabItems
                       <ToolBarTray DockPanel.Dock="Top">
                             <ToolBar>
                                   <Button Command="Cut" ToolTip="Cut
            selection to Windows Clipboard.">                                                List controls
                                        <Image                                                 The ItemsControl
            Source="/WpfTutorialSamples;component/Images/cut.png" />                           The ListBox control
                                   </Button>                                                   The ComboBox control
                                   <Button Command="Copy" ToolTip="Copy
            selection to Windows Clipboard.">
                                        <Image                                               The ListView control
            Source="/WpfTutorialSamples;component/Images/copy.png" />
                                                                                               Introduction
                                   </Button>
                                                                                               A simple ListView
                                   <Button Command="Paste" ToolTip="Paste
                                                                                               ListView, data binding and
            from Windows Clipboard.">
                                                                                                ItemTemplate
                                        <StackPanel Orientation="Horizontal">
                                                                                               ListView with a GridView
                                             <Image
                                                                                               How-to: Left aligned column
            Source="/WpfTutorialSamples;component/Images/paste.png" />
                                                                                                names
                                             <TextBlock
                                                                                               ListView grouping
            Margin="3,0,0,0">Paste</TextBlock>
                                                                                               ListView sorting
                                        </StackPanel>
                                                                                               How-to: ListView with
                                   </Button>
                                                                                                column sorting
                             </ToolBar>
                                                                                           ListView filtering
                       </ToolBarTray>
                       <TextBox AcceptsReturn="True" />
                  </DockPanel>
                                                                                          The TreeView control
            </Window>
                                                                                           Introduction
                                                                                           A simple TreeView
                                                                                           TreeView, data binding and
                                                                                            multiple templates
                                                                                           Handling
                                                                                            Selection/Expansion state
                                                                                           Lazy loading TreeView items
         
WPF even allows you to decide which items are suitable for overflow hiding
          and which should always be visible. Usually, when designing a toolbar, some
         
items are less important than the others and some of them you might even
          want to have in the overflow menu all the time, no matter if there's space
          enough
or not.
         
This is where the attached property ToolBar.OverflowMode comes into
          play. The default value is IfNeeded, which simply means that a toolbar
item is
          put in the overflow menu if there's not enough room for it. You may use
          Always or Never instead, which does
exactly what the names imply: Puts
          the item in the overflow menu all the time or prevents the item from ever
          being moved to the overflow menu. Here's an
example on how to assign this
          property:
            <ToolBar>
                  <Button Command="Cut" Content="Cut"
            ToolBar.OverflowMode="Always" />
                  <Button Command="Copy" Content="Copy"
            ToolBar.OverflowMode="AsNeeded" />
                  <Button Command="Paste" Content="Paste"
            ToolBar.OverflowMode="Never" />
            </ToolBar>
         
Position
         
While the most common position for the toolbar is indeed in the top of the
          screen, toolbars can also be found in the bottom of the application window or
          even on the sides. The WPF ToolBar of course supports all of this, and while
          the bottom placed toolbar is merely a matter of docking to the bottom of the
          panel instead of the top, a vertical toolbar requires the use of the Orientation
          property of the ToolBar tray. Allow me to demonstrate
with an example:
            <Window
            x:Class="WpfTutorialSamples.Common_interface_controls.Toolba
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ToolbarPositionSample" Height="200"
            Width="300">
            	<DockPanel>
            		<ToolBarTray DockPanel.Dock="Top">
            			<ToolBar>
            				<Button Command="Cut"
            ToolTip="Cut selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/cut.png" />
            				</Button>
            				<Button Command="Copy"
            ToolTip="Copy selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/copy.png" />
            				</Button>
            				<Button Command="Paste"
            ToolTip="Paste from Windows Clipboard.">
            					<StackPanel
            Orientation="Horizontal">
            						<Image
            Source="/WpfTutorialSamples;component/Images/paste.png" />
            						<TextBlock
             Margin="3,0,0,0">Paste</TextBlock>
            					</StackPanel>
            				</Button>
            			</ToolBar>
            		</ToolBarTray>
            		<ToolBarTray DockPanel.Dock="Right"
            Orientation="Vertical">
            			<ToolBar>
            				<Button Command="Cut"
            ToolTip="Cut selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/cut.png" />
            				</Button>
            				<Button Command="Copy"
            ToolTip="Copy selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/copy.png" />
            				</Button>
            				<Button Command="Paste"
            ToolTip="Paste from Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/paste.png" />
            				</Button>
            			</ToolBar>
            		</ToolBarTray>
            		                     <TextBox AcceptsReturn="True" />
            	</DockPanel>
            </Window>
         
The trick here lies in the combination of the DockPanel.Dock property, that
          puts the ToolBarTray to the right of the application, and the Orientation
          property, that changes the orientation from horizontal to vertical. This makes
          it possible to place toolbars in pretty much
any location that you might think
          of.
         
Custom controls on the ToolBar
         
As you have seen on all of the previous examples, we use regular WPF
          Button controls on the toolbars. This also means that you can place pretty
          much any
other WPF control on the toolbars, with no extra effort. Of course,
          some controls works better on a toolbar than others, but controls like the
          ComboBox and
TextBox are commonly used on the toolbars in e.g. older
          versions of Microsoft Office, and you can do the same on your own WPF
          toolbars.
         
Another thing introduced in this example is the Separator element, which
          simply creates a separator between two sets of toolbar items. As you can see
          from
the example, it's very easy to use!
            <Window
            x:Class="WpfTutorialSamples.Common_interface_controls.Toolba
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ToolbarCustomControlsSample" Height="200"
            Width="300">
            	<DockPanel>
            		<ToolBarTray DockPanel.Dock="Top">
            			<ToolBar>
            				<Button Command="Cut"
            ToolTip="Cut selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/cut.png" />
            				</Button>
            				<Button Command="Copy"
            ToolTip="Copy selection to Windows Clipboard.">
            					<Image
            Source="/WpfTutorialSamples;component/Images/copy.png" />
            				</Button>
            				<Button Command="Paste"
            ToolTip="Paste from Windows Clipboard.">
            					<StackPanel
            Orientation="Horizontal">
            						<Image
            Source="/WpfTutorialSamples;component/Images/paste.png" />
            						<TextBlock
             Margin="3,0,0,0">Paste</TextBlock>
            					</StackPanel>
            				</Button>
            				<Separator />
            				<Label>Font size:</Label>
            				<ComboBox>
            					
            <ComboBoxItem>10</ComboBoxItem>
            					<ComboBoxItem
            IsSelected="True">12</ComboBoxItem>
            					
            <ComboBoxItem>14</ComboBoxItem>
            					
            <ComboBoxItem>16</ComboBoxItem>
            				</ComboBox>
            			</ToolBar>
            		</ToolBarTray>
            		                     <TextBox AcceptsReturn="True" />
            	</DockPanel>
            </Window>
         
Summary
         
Creating interfaces with toolbars is very easy in WPF, with the flexible
          ToolBar control. You can do things that previously required 3rd party toolbar
          controls and you can even do it without much extra effort.
Previous Next
                                                            
         
Download
                                                             PDF!
                                                                                       
Back to Top
Home Contact Us
                                                                                         Download as PDF
        The WPF StatusBar control
                                                                                                Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
         
With the top of the application window usually occupied by the main menu       About WPF
          and/or toolbars, described in previous chapters, the bottom part of the
                                                                                          What is WPF?
          window is
usually the home of the status bar. The status bar is used to show
                                                                                          WPF vs. WinForms
          various information about the current state of the application, like cursor
          position,
word count, progress of tasks and so on. Fortunately for us, WPF
          comes with a nice StatusBar control, making it very easy to add status bar
          functionality
to your applications.                                            Getting started
                                                                                          Visual Studio Express
         
Let's start off with a very basic example:                                      Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Common_interface_controls.Status                 XAML
                                                                                          What is XAML?
                                                                                          Basic XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                          Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                         A WPF application
                       Title="StatusBarSample" Height="150" Width="300">
            	<DockPanel>                                                                  Introduction
            		<StatusBar DockPanel.Dock="Bottom">                                         The Window
            			<StatusBarItem>                                                            Working with App.xaml
            				<TextBlock                                                                Command-line parameters
            Name="lblCursorPosition" />                                                   Resources
            			</StatusBarItem>                                                           Handling exceptions
            		</StatusBar>
            		<TextBox AcceptsReturn="True"
            Name="txtEditor"                                                             Basic controls
            SelectionChanged="txtEditor_SelectionChanged" />                              The TextBlock control
            	</DockPanel>                                                                 The TextBlock control - Inline
            </Window>                                                                     formatting
                                                                                          The Label control
                                                                                          The TextBox control
                                                                                          The CheckBox control
            using System;
            namespace WpfTutorialSamples.Common_interface_controls
            {
            	          public partial class StatusBarSample : Window                         Panels
            	{                                                                                Introduction to WPF Panels
            		public StatusBarSample()                                                        The Canvas
            		{                                                                               The WrapPanel
            			InitializeComponent();                                                         The StackPanel
            		}                                                                               The DockPanel
                                                                                              The Grid
            		private void                                                                    The Grid - Rows & Columns
            txtEditor_SelectionChanged(object sender, RoutedEventArgs                         The Grid - Units
            e)                                                                                The Grid - Spanning
            		{                                                                               The Grid - GridSplitter
                                                                                              Using the Grid: A contact
            			int row =                                                                       form
            txtEditor.GetLineIndexFromCharacterIndex(txtEditor.CaretInde
                                                                                             Commands
                                                                                              Introduction
                                                                                              Using commands
                                                                                              Implementing custom
         
It's all very simple - a TextBlock control that shows the current cursor             commands
          position, just like in pretty much any other application that allows you to edit
          text. In this very basic form, the StatusBar could just as easily have been a
          panel with a set of controls on it, but the real advantage of the StatusBar        Common interface
          comes when we need to divide it into several areas of information.                 controls
                                                                                              The Menu control
         
Advanced StatusBar example                                                          The ContextMenu
         
Let's try a more advanced example of using the StatusBar. The first thing we        The ToolBar control
          want to do is to make the StatusBar use another panel for the layout. By            The StatusBar control
          default, it uses the DockPanel, but when we want a more complex layout,             The Ribbon Control
          with columns that adjusts its width in a certain way and aligned
content, the
          Grid is a much better choice.
                                                                                             Rich Text controls
         
We'll divide the Grid into three areas, with the left and right one having a
                                                                                           Introduction
          fixed width and the middle column automatically taking up the
remaining
                                                                                           The
          space. We'll also add columns in between for Separator controls. Here's how
                                                                                            FlowDocumentScrollViewer
          it looks now:
                                                                                            control
                                                                                           The
            <Window                                                                         FlowDocumentPageViewer
            x:Class="WpfTutorialSamples.Common_interface_controls.Status                    control
                                                                                           The FlowDocumentReader
                                                                                            control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                   Creating a FlowDocument
                                                                                            from Code-behind
                                                                                           Advanced FlowDocument
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          content
                       Title="StatusBarAdvancedSample" Height="150"                        The RichTextBox control
            Width="400">
                   <DockPanel>
                       <StatusBar DockPanel.Dock="Bottom">
                                                                                         Misc. controls
                             <StatusBar.ItemsPanel>
                                   <ItemsPanelTemplate>                                    The Border control
                                        <Grid>                                             The Slider control
                                              <Grid.ColumnDefinitions>                     The ProgressBar control
                                                   <ColumnDefinition Width="100"           The WebBrowser control
            />                                                                             The WindowsFormsHost
                                                   <ColumnDefinition Width="Auto"          control
              />
                                                   <ColumnDefinition Width="*" />
                                                   <ColumnDefinition Width="Auto"        The TabControl
              />                                                                           Using the TabControl
                                                   <ColumnDefinition Width="100"           Tab positions
            />                                                                             Styling the TabItems
                                              </Grid.ColumnDefinitions>
                                        </Grid>
                                   </ItemsPanelTemplate>                                 List controls
                             </StatusBar.ItemsPanel>
                                                                                           The ItemsControl
                             <StatusBarItem>
                                                                                           The ListBox control
                                   <TextBlock Name="lblCursorPosition" />
                                                                                           The ComboBox control
                             </StatusBarItem>
                             <Separator Grid.Column="1" />
                             <StatusBarItem Grid.Column="2">
                                   <TextBlock                                            The ListView control
            Text="c:\path\of\current\file.txt" />                                          Introduction
                             </StatusBarItem>                                              A simple ListView
                             <Separator Grid.Column="3" />                                 ListView, data binding and
                             <StatusBarItem Grid.Column="4">                                ItemTemplate
                                   <ProgressBar Value="50" Width="90"                      ListView with a GridView
            Height="16" />                                                                 How-to: Left aligned column
                             </StatusBarItem>                                               names
                       </StatusBar>                                                        ListView grouping
                       <TextBox AcceptsReturn="True" Name="txtEditor"                      ListView sorting
            SelectionChanged="txtEditor_SelectionChanged" />                               How-to: ListView with
                   </DockPanel>                                                             column sorting
         
As you can see, I've added a bit of sample information, like the fake filename
          in the middle column and the progress bar to the right, showing a static
value
          for now. You could easily make this work for real though, and it gives a pretty
          good idea on what you can do with the StatusBar control.
         
Summary
         
Once again, WPF makes it easy to get standard Windows functionality, in
          this case the StatusBar, integrated into your applications.
         
You can even place other controls than the ones used in these examples,
          like buttons, combo boxes and so on, but please be aware that since the
          StatusBar
doesn't apply any special rendering to these controls when hosting
          them, it might not look as you would expect it to for controls in a status bar.
          This can
be handled with custom styling if you need it though, a subject
          discussed elsewhere in this tutorial.
Previous Next
                                                                 
         
Download
                                                                  PDF!
                                                                                            
Back to Top
Home Contact Us
                                                                                                 Download as PDF
        The Ribbon control
                                                                                                        Download this entire
                                                                                                        tutorial as PDF right
                                                                                                 now!
          
The Ribbon interface was invented by Microsoft and first used in Office 2007.         About WPF
           It combines the original menu and toolbar(s) into one control, with various
                                                                                                  What is WPF?
           functions grouped into tabs and groups. The most important purpose was to
                                                                                                  WPF vs. WinForms
           make it easier for the user to discover all the functionality, instead of hiding
it
           in long menus. The Ribbon also allows for prioritization of functionality, with
           the ability to use different sizes of buttons.
                                                                                                 Getting started
                                                                                                  Visual Studio Express
                                                                                                  Hello, WPF!
                                                                                                 XAML
                                                                                                  What is XAML?
                                                                                                  Basic XAML
          
WPF doesn't come with a built-in Ribbon control, but Microsoft has released            Events in XAML
           one that you can download and use for free, as long as you promise to follow
          
their implementation guide when using it. You can read much more about it
           at MSDN,
where you'll also find a download link for the Ribbon control.               A WPF application
                                                                                                  Introduction
          
Summary                                                                                The Window
                                                                                                  Working with App.xaml
          
You can download and use a Microsoft created Ribbon control, but it's not
                                                                                                  Command-line parameters
           yet a part of the .NET framework by default. Once it becomes an integrated
                                                                                                  Resources
           part
of the framework, we'll dig into it here at this tutorial. In the meantime, if
                                                                                                  Handling exceptions
           you're looking for a more complete Ribbon implementation, you might want to
          
look at some 3rd party alternatives - there are plenty of them, from some of
           the big WPF control vendors.
                                                                                                 Basic controls
                Previous                                                        Next              The TextBlock control
                                                                                                  The TextBlock control - Inline
                                                                                                  formatting
                                                                                                  The Label control
          comments powered by Disqus
                                                                                                  The TextBox control
                                                                                                  The CheckBox control
                                                 Panels
                                                  Introduction to WPF Panels
                                                  The Canvas
                                                  The WrapPanel
                                                  The StackPanel
                                                  The DockPanel
                                                  The Grid
                                                  The Grid - Rows & Columns
                                                  The Grid - Units
                                                  The Grid - Spanning
                                                  The Grid - GridSplitter
                                                  Using the Grid: A contact
                                                   form
                                                 Data binding
                                                  Introduction
                                                  Hello, bound world!
                                                  Using the DataContext
                                                  The UpdateSourceTrigger
                                                   property
                                                  Responding to changes
                                                  Value conversion with
                                                   IValueConverter
                                                  The StringFormat property
                                                  Debugging data bindings
                                                 Commands
                                                  Introduction
                                                  Using commands
                                                  Implementing custom
                                                   commands
                                                 Common interface
                                                 controls
                                                  The Menu control
                                                  The ContextMenu
                                                  The ToolBar control
                                                  The StatusBar control
                                                  The Ribbon Control
                                                   Introduction
                                                   The
                                                    FlowDocumentScrollViewer
                                                    control
                                                   The
                                                    FlowDocumentPageViewer
                                                    control
                                                   The FlowDocumentReader
                                                    control
                                                   Creating a FlowDocument
                                                    from Code-behind
                                                   Advanced FlowDocument
                                                    content
                                                   The RichTextBox control
                                                 Misc. controls
                                                   The Border control
                                                   The Slider control
                                                   The ProgressBar control
                                                   The WebBrowser control
                                                   The WindowsFormsHost
                                                   control
                                                 The TabControl
                                                   Using the TabControl
                                                   Tab positions
                                                   Styling the TabItems
                                                 List controls
                                                   The ItemsControl
                                                   The ListBox control
                                                   The ComboBox control
ListView filtering
                                                                                  Styles
                                                                                   Introduction
                                                                                   Using styles
                                                                                   Triggers
                                                                                   Multi triggers
                                                                                   Trigger animations
                                                                                  Misc.
                                                                                   The DispatcherTimer
                                                       
         
Download
                                                        PDF!
                                                 
Back to Top
Home Contact Us
                                                                                            Download as PDF
        Introduction to WPF Rich Text controls
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          
In other UI frameworks like WinForms, displaying large amounts of richly         About WPF
           formatted text has been somewhat of a problem. Sure, you could load a file
                                                                                             What is WPF?
           into a
RichTextBox or you could create a WebBrowser object and load a local
                                                                                             WPF vs. WinForms
           or remote web page, but specifying larger amounts of rich text in design-time
           wasn't
really possible. It seems that Microsoft wanted to remedy that in WPF
           and even go beyond just simple viewing of the text.
                                                                                            Getting started
          
The FlowDocument does indeed render rich text, and that even includes             Visual Studio Express
           images, lists and tables, and elements can be floated, adjusted and so on,        Hello, WPF!
           and using
a FlowDocument, you can specify rich text in design-time as if it
           were HTML (thanks to XAML) and have it rendered directly in your WPF
           application.
                                                                                            XAML
          
The FlowDocument doesn't stand alone. Instead, it uses one of several built-      What is XAML?
          in wrappers, which controls how the FlowDocument is laid out and whether           Basic XAML
           the
content can be edited by the user or not. WPF includes three controls for     Events in XAML
           rendering a FlowDocument in read-only mode, which all has easy support for
          
zooming and printing:
                                                                                            A WPF application
          FlowDocumentScrollViewer
- the simplest wrapper around a
                                                                                             Introduction
          FlowDocument, which simply displays the document as one long document
                                                                                             The Window
          of text which you can scroll in.
                                                                                             Working with App.xaml
          FlowDocumentPageViewer
- this wrapper will automatically split your                Command-line parameters
          document into pages, which the user can navigate back and forth between.           Resources
                                                                                             Handling exceptions
          FlowDocumentReader
- a combination of the FlowDocumentScrollViewer
          and the FlowDocumentPageViewer, which will let the user decide between
          the two rendering
modes. It also offers the ability AND the interface to search   Basic controls
          in the document.                                                                   The TextBlock control
                                                                                             The TextBlock control - Inline
          
The FlowDocument is normally read-only, but put it inside of a RichTextBox
                                                                                             formatting
           control (described later in this tutorial) and you can now edit
the text, much
                                                                                             The Label control
           like in real word processors like Microsoft Word.
                                                                                             The TextBox control
          
Read on through the next chapters, where we'll discuss all the wrappers that      The CheckBox control
          you can use with a FlowDocument, both read-only and editable. After that,         The RadioButton control
          we'll look into all of the possibilities you have when creating rich documents    The PasswordBox control
          using the FlowDocument, including tables, lists, images and much more.
                                                                                           Data binding
                                                                                            Introduction
                                                                                            Hello, bound world!
                                                                                            Using the DataContext
                                                                                            The UpdateSourceTrigger
                                                                                             property
                                                                                            Responding to changes
                                                                                            Value conversion with
                                                                                             IValueConverter
                                                                                            The StringFormat property
                                                                                            Debugging data bindings
                                                                                           Commands
                                                                                            Introduction
                                                                                            Using commands
                                                                                            Implementing custom
                                                                                             commands
                                                                                           Common interface
                                                                                           controls
                                                                                            The Menu control
                                                                                            The ContextMenu
                                                                                            The ToolBar control
                                                                                            The StatusBar control
                                                                                            The Ribbon Control
                                                                       Introduction
                                                                       The
                                                                        FlowDocumentScrollViewer
                                                                        control
                                                                       The
                                                                        FlowDocumentPageViewer
                                                                        control
                                                                       The FlowDocumentReader
                                                                        control
                                                                       Creating a FlowDocument
                                                                        from Code-behind
                                                                       Advanced FlowDocument
                                                                        content
                                                                       The RichTextBox control
                                                                     Misc. controls
                                                                       The Border control
                                                                       The Slider control
                                                                       The ProgressBar control
                                                                       The WebBrowser control
                                                                       The WindowsFormsHost
                                                                       control
                                                                     The TabControl
                                                                       Using the TabControl
                                                                       Tab positions
                                                                       Styling the TabItems
                                                                     List controls
                                                                       The ItemsControl
                                                                       The ListBox control
                                                                       The ComboBox control
ListView filtering
                                                                                                      Styles
                                                                                                       Introduction
                                                                                                       Using styles
                                                                                                       Triggers
                                                                                                       Multi triggers
                                                                                                       Trigger animations
                                                                                                      Misc.
                                                                                                       The DispatcherTimer
                                                                           
         
Download
                                                                            PDF!
                                                                     
Back to Top
Home Contact Us
                                                                                         Download as PDF
       The FlowDocumentScrollViewer
       control                                                                                  Download this entire
                                                                                                tutorial as PDF right
                                                                                         now!
                                                                                         About WPF
         
In the range of FlowDocument wrappers, discussed in the introduction, the
                                                                                          What is WPF?
          FlowDocumentScrollViewer is the simplest one. It simply allows the users to
                                                                                          WPF vs. WinForms
          scroll to long documents, using regular scrollbars. Since this is our first
          meeting with the FlowDocument used in any form, we'll start off with a basic
          "Hello World!" example, and besides the use of FlowDocumentScrollViewer,
          this article will also cover several concepts common between all of the        Getting started
          wrappers.
Here's the first example:                                             Visual Studio Express
                                                                                          Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentS
                                                                                         XAML
                                                                                          What is XAML?
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                  Basic XAML
                                                                                          Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="FlowDocumentScrollViewerSample"
                                                                                         A WPF application
            Height="200" Width="300">
                                                                                          Introduction
                 <Grid>
                                                                                          The Window
                       <FlowDocumentScrollViewer>
                                                                                          Working with App.xaml
                            <FlowDocument>
                                                                                          Command-line parameters
                                   <Paragraph FontSize="36">Hello, world!
                                                                                          Resources
            </Paragraph>
                                                                                          Handling exceptions
                                   <Paragraph FontStyle="Italic"
            TextAlignment="Left" FontSize="14" Foreground="Gray">The
            ultimate programming greeting!</Paragraph>
                            </FlowDocument>                                              Basic controls
                       </FlowDocumentScrollViewer>                                        The TextBlock control
                 </Grid>                                                                  The TextBlock control - Inline
            </Window>                                                                     formatting
                                                                                          The Label control
                                                                                          The TextBox control
                                                                                          The CheckBox control
                                                                                           Panels
                                                                                            Introduction to WPF Panels
                                                                                            The Canvas
                                                                                            The WrapPanel
                                                                                            The StackPanel
                                                                                            The DockPanel
         
Notice how easy it was to specify the text, using simple markup tags, in this     The Grid
          case the Paragraph tag. Now you might argue that this could
have been             The Grid - Rows & Columns
          achieved with a couple of TextBlock controls, and you would be absolutely         The Grid - Units
          right, but even with an extremely basic example like this, you get a
bit of       The Grid - Spanning
          added functionality for free: You can select the text and copy it to the          The Grid - GridSplitter
          clipboard. It'll look like this:                                                  Using the Grid: A contact
                                                                                             form
                                                                                           Data binding
                                                                                            Introduction
                                                                                            Hello, bound world!
                                                                                            Using the DataContext
                                                                                            The UpdateSourceTrigger
                                                                                             property
                                                                                            Responding to changes
                                                                                            Value conversion with
                                                                                             IValueConverter
         
Zooming and scrollbar visibility                                                  The StringFormat property
                                                                                            Debugging data bindings
         
As previously mentioned, all of the FlowDocument wrappers support zooming
          out of the box. With the example above, you can simply hold down the Ctrl
          key
while using the mouse wheel to zoom in and out. This might not be
          obvious to your end users though, so you can help them by displaying the
                                                                                           Commands
          built-in toolbar
of the FlowDocumentScrollViewer, which has controls that will    Introduction
          allow you to change the zoom level. Just set the IsToolBarVisible property        Using commands
          to true on the FlowDocumentScrollViewer, and you're good to go, as you can        Implementing custom
          see in the next example:                                                           commands
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentS                   Common interface
                                                                                           controls
                                                                                            The Menu control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    The ContextMenu
                                                                                            The ToolBar control
                                                                                            The StatusBar control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          The Ribbon Control
                       Title="FlowDocumentScrollViewerZoomSample"
            Height="180" Width="300">
                                                                                                Misc. controls
                                                                                                  The Border control
                                                                                                  The Slider control
                                                                                                  The ProgressBar control
                                                                                                  The WebBrowser control
                                                                                                  The WindowsFormsHost
                                                                                                  control
         
Now the user can control the zoom level using the slider and the buttons in
          the toolbar below the document. Notice also that we changed the default
          zoom
level, using the Zoom property - it defines the zoom level in
                                                                                                The TabControl
          percentages, so in this case, the text is zoomed out to 80% by default.                 Using the TabControl
                                                                                                  Tab positions
         
The last thing I changed in this example, in comparison to the first one, is the        Styling the TabItems
          use of the ScrollViewer.VerticalScrollBarVisibility
property. By setting it to
          Auto, the scrollbars will be invisible until the content actually goes beyond
          the available space, which is
usually what you want.                                  List controls
         
Text alignment                                                                          The ItemsControl
                                                                                                  The ListBox control
         
You may have noticed that I specifically used the TextAlignment property in             The ComboBox control
          the above examples. That's because the text is rendered
justified by default,
          in a WPF FlowDocument, meaning that each line of text is stretched to cover
          the entire available width, if needed. As you can see,
this can be changed,           The ListView control
          either on a single paragraph or globally for the entire document by setting the
                                                                                                  Introduction
          same property on the FlowDocument element.
                                                                                                  A simple ListView
                                                                                                  ListView, data binding and
         
However, in many situations, justified text makes sense, but it can result in
                                                                                                   ItemTemplate
          some very bad layout, with very excessive amounts of whitespace on lines
                                                                                                  ListView with a GridView
          where a linebreak is inserted right before a very long word.
                                                                                                  How-to: Left aligned column
         
The following example will illustrate that, as well as provide a solution that will      names
          help remedy the problem. By using the IsOptimalParagraphEnabled                         ListView grouping
          property in combination with the IsHyphenationEnabled property, you will                ListView sorting
          give WPF a better
chance of laying out the text in the best possible way.               How-to: ListView with
                                                                                                column sorting
         IsOptimalParagraphEnabled
allows WPF to look ahead in your text, to see if            ListView filtering
          it would make more sense to break the text in a different position than right at
          the moment where it runs
out of space. IsHyphenationEnabled allows WPF
          to split your words with a hyphen, if it would allow for a more natural layout of   The TreeView control
          the text.
                                                                                               Introduction
                                                                                               A simple TreeView
         
In the next example, I've rendered the same text twice - one without these
                                                                                               TreeView, data binding and
          properties, and one with. The difference is quite obvious:
                                                                                                multiple templates
                                                                                               Handling
            <Window
                                                                                                Selection/Expansion state
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentT
                                                                                               Lazy loading TreeView items
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              The DataGrid control
                                                                                               Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             Custom columns
                       Title="FlowDocumentTextAlignmentSample"                                 Details row
            Height="400" Width="330">
                 <StackPanel>
                       <FlowDocumentScrollViewer                                              Styles
            ScrollViewer.VerticalScrollBarVisibility="Auto">                                   Introduction
                            <FlowDocument>                                                     Using styles
                                   <Paragraph FontStyle="Italic"                               Triggers
            FontSize="14" Foreground="Gray">                                                   Multi triggers
                                       By setting the                                          Trigger animations
                                       <Bold>IsOptimalParagraphEnabled</Bold>
             property to true,
                                       you will allow WPF to look ahead on
                                                                                              Misc.
            the lines to come, before deciding
                                       where to break. This will usually                       The DispatcherTimer
            result in a more pleasant reading
                                       experience. It works especially well
            in combination with the                                                           Audio & Video
                                       <Bold>IsHyphenationEnabled</Bold>                       Playing audio
            property.                                                                          Playing video
                                   </Paragraph>                                                How-to: Complete media
                            </FlowDocument>                                                    player
                       </FlowDocumentScrollViewer>                                             Speech synthesis
                       <FlowDocumentScrollViewer                                               Speech recognition
            ScrollViewer.VerticalScrollBarVisibility="Auto">
                            <FlowDocument IsOptimalParagraphEnabled="True"
             IsHyphenationEnabled="True">
                                   <Paragraph FontStyle="Italic"
            FontSize="14" Foreground="Gray">
                                       By setting the
            <Bold>IsOptimalParagraphEnabled</Bold> property to true,
                                       you will allow WPF to look ahead on
            the lines to come, before deciding
                                       where to break. This will usually
         
IsOptimalParagraphEnabled is not enabled by default because it does
          require a bit more CPU power when rendering the text, especially if the
          window is
frequently resized. For most situations this shouldn't be a problem
          though.
         
If you have a lot of FlowDocument instances in your application and you
          prefer this optimal rendering method, you can enable it on all of your
          FlowDocument
instances by specifying a global style that enables it, in your
          App.xaml. Here's an example:
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                              xmlns:sys="clr-
            namespace:System;assembly=mscorlib"
                              StartupUri="Rich text
            controls/FlowDocumentTextAlignmentSample.xaml">
                 <Application.Resources>
                       <Style TargetType="FlowDocument">
                            <Setter Property="IsOptimalParagraphEnabled"
            Value="True" />
                            <Setter Property="IsHyphenationEnabled"
            Value="True" />
                       </Style>
                 </Application.Resources>
            </Application>
Previous Next
                                                                    
         
Download
                                                                     PDF!
                                                                                               
Back to Top
Home Contact Us
                                                                                          Download as PDF
       The FlowDocumentPageViewer control
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
In the previous article, we discussed the FlowDocumentScrollViewer, along       About WPF
          with some more general FlowDocument related techniques. In this article,
                                                                                           What is WPF?
          we'll
focus on the FlowDocumentPageViewer which, instead of just offering
                                                                                           WPF vs. WinForms
          a scroll text when the text gets longer than the available space,
divides the
          entire document up into pages. This allows you to navigate from page to
          page, giving a more book-like reading experience.
                                                                                          Getting started
         
We'll start off with a simple example, where we can see how the                  Visual Studio Express
          FlowDocumentPageViewer control handles our Lorem Ipsum test text:                Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentP                  XAML
                                                                                           What is XAML?
                                                                                           Basic XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                          A WPF application
                       Title="FlowDocumentPageViewerSample" Height="300"
            Width="300">                                                                   Introduction
                 <Grid>                                                                    The Window
                       <FlowDocumentPageViewer>                                            Working with App.xaml
                            <FlowDocument>                                                 Command-line parameters
                                   <Paragraph>Lorem ipsum dolor sit amet,                  Resources
            consectetur adipiscing elit. Fusce faucibus odio arcu,                         Handling exceptions
            luctus vestibulum tortor congue in. Lorem ipsum dolor sit
            amet, consectetur adipiscing elit. Fusce nec lacinia
            neque. Donec malesuada, ligula non vestibulum cursus, urna                    Basic controls
             purus pellentesque orci, aliquet accumsan dui velit ac                        The TextBlock control
            justo. Phasellus sagittis ligula in leo dapibus, vel                           The TextBlock control - Inline
            vestibulum felis mattis. Fusce vitae auctor nibh. Ut sit                       formatting
            amet fringilla turpis. Aenean tincidunt feugiat sapien,                        The Label control
            quis scelerisque enim pretium commodo. Mauris fermentum                        The TextBox control
            posuere nulla, vitae fermentum quam malesuada in. Cras                         The CheckBox control
            ultrices bibendum nulla eu mollis. Sed accumsan pretium
                                                                                       Commands
                                                                                        Introduction
                                                                                        Using commands
                                                                                        Implementing custom
                                                                                         commands
                                                                                       Common interface
         
Notice how the long text is cut off, and in the bottom, you can navigate     controls
          between pages. This is not all that the FlowDocumentPageViewer will do for    The Menu control
          you
though - just look what happens when we make the window wider:            The ContextMenu
                                                                                        The ToolBar control
                                                                                        The StatusBar control
                                                                                        The Ribbon Control
                                                                                              Introduction
                                                                                              The
                                                                                               FlowDocumentScrollViewer
                                                                                               control
                                                                                              The
         
Instead of just stretching the text indefinitely, the FlowDocumentPageViewer         FlowDocumentPageViewer
          now divides your text up into columns, to prevent lines from becoming too            control
          long. Besides looking good, this also increases the readability, as texts with      The FlowDocumentReader
          very long lines are harder to read. The page count is of course
automatically        control
          adjusted, bringing the amount of pages down from 5 to 2.                            Creating a FlowDocument
                                                                                               from Code-behind
         
The FlowDocument class has a range of properties that will allow you to
                                                                                              Advanced FlowDocument
          control how and when they are used. Using them is simple, but a complete
                                                                                               content
          example
goes beyond the scope of this tutorial. Instead, have a look at this
                                                                                              The RichTextBox control
          MSDN article, where several properties are used in a nice example: How to:
          Use FlowDocument Column-Separating Attributes.
                                                                                            Misc. controls
         
Searching
                                                                                              The Border control
         
As you're about to see in the next chapter, the FlowDocumentReader                  The Slider control
          wrapper supports searching right out of the box, with search controls in the        The ProgressBar control
          toolbar and
everything. However, all of the three read-only FlowDocument            The WebBrowser control
          wrappers which will be discussed in this tutorial does in fact support              The WindowsFormsHost
          searching, it just has
to be manually invoked for the first two                     control
          (FlowDocumentScrollViewer and FlowDocumentPageViewer).
         
All three viewers support the Ctrl+F keyboard shortcut for initiating a search,
                                                                                            The TabControl
          but if you want this to be accessible from e.g. a button
as well, you just have
          to call the Find() method. Here's an example:                                       Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentS
                                                                                            List controls
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="FlowDocumentSearchSample" Height="300"
            Width="580">                                                                    The ListView control
                 <DockPanel>
                                                                                              Introduction
                       <WrapPanel DockPanel.Dock="Top">
                                                                                              A simple ListView
                            <Button Name="btnSearch"
                                                                                              ListView, data binding and
            Click="btnSearch_Click">Search</Button>
                                                                                               ItemTemplate
                       </WrapPanel>
                                                                                              ListView with a GridView
                       <FlowDocumentPageViewer Name="fdViewer">
            using System;
            using System.Windows;                                            Audio & Video
                                                                              Playing audio
            namespace WpfTutorialSamples.Rich_text_controls                   Playing video
            {                                                                 How-to: Complete media
            	          public partial class FlowDocumentSearchSample :        player
            Window                                                            Speech synthesis
            	{                                                                Speech recognition
            		public FlowDocumentSearchSample()
            		{
            			InitializeComponent();
            		}
         
Simply press our dedicated Search button or the keyboard shortcut (Ctrl+F)
          and you have search functionality in the
FlowDocumentPageViewer. As
          mentioned, this works for both FlowDocumentScrollViewer and
          FlowDocumentPageViewer (FlowDocumentPageReader has a search button
         
by default), but make sure that the search box has enough horizontal
          room on the toolbar - otherwise you won't see it when you invoke the
Find()
          command!
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                              
Back to Top
Home Contact Us
                                                                                           Download as PDF
       The FlowDocumentReader control
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
         
The FlowDocumentReader is definitely the most advanced read-only                 About WPF
          wrapper that you can place around a FlowDocument. It offers buttons that
                                                                                            What is WPF?
          allows the end user to toggle between the rendering modes offered by the
                                                                                            WPF vs. WinForms
          FlowDocumentScrollViewer and the FlowDocumentPageViewer, as well as
          out-of-the-box
document searching and of course controls for zooming in and
          out.
                                                                                           Getting started
         
All of this functionality also makes the FlowDocumentReader the heaviest of       Visual Studio Express
          the three read-only wrappers, but this should hardly be an issue with most        Hello, WPF!
          regularly sized documents. Here's an example of how the
          FlowDocumentReader might look:
                                                                                           XAML
                                                                                            What is XAML?
                                                                                            Basic XAML
                                                                                            Events in XAML
                                                                                           A WPF application
                                                                                            Introduction
                                                                                            The Window
                                                                                            Working with App.xaml
         
This screenshot is taken in the page-based view, which is the default. You        Command-line parameters
          can switch between the view modes using the buttons to the left of the zoom       Resources
          controls. In the left part of the toolbar, you have the controls for searching    Handling exceptions
          through the document, as I have done here on the screenshot.
         
Here's the code that will give you the above result:                             Basic controls
                                                                                            The TextBlock control
            <Window                                                                         The TextBlock control - Inline
            x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentR                    formatting
                                                                                            The Label control
                                                                                            The TextBox control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    The CheckBox control
                                                                                            Introduction
                                                                                            The
                                                                                             FlowDocumentScrollViewer
                                                                                             control
                                                                                            The
                                                                                             FlowDocumentPageViewer
                                                                                             control
                                                                                            The FlowDocumentReader
                                                                                             control
                                                                                            Creating a FlowDocument
                                                                                             from Code-behind
         
The FlowDocumentReader has a range of properties that can help you in
                                                                                            Advanced FlowDocument
          controlling how it works. Here's an incomplete list of some of the most
                                                                                             content
          important
ones:
                                                                                            The RichTextBox control
         ViewingMode
- controls the initial viewing mode. The default is Page, but you
         can change that into Scroll or TwoPage
, if you want another default view.
         This can still be changed by the user, unless specifically disabled.             Misc. controls
                                                                                            The Border control
         IsFindEnabled
- gives you the ability to disable searching in the document. If     The Slider control
          disabled, the search button will be removed from the toolbar.                     The ProgressBar control
                                                                                            The WebBrowser control
         IsTwoPageViewEnabled
, IsPageViewEnabled and IsScrollViewEnabled -
                                                                                            The WindowsFormsHost
          allows you to turn off a specific viewing mode for the reader. When set to
                                                                                            control
          false, this mode is no longer available for the reader and the button is
          removed from the toolbar.
         Zoom
- allows you to set the default zoom level. The standard is 100%, but       The TabControl
         you can change this by using the Zoom property.                                    Using the TabControl
                                                                                            Tab positions
         
Summary                                                                           Styling the TabItems
         
We've now been through all the choices for a read-only FlowDocument
          wrapper, and as you can probably see, which one to choose really depends
          on the task at
hand.                                                            List controls
                                                                                            The ItemsControl
         
If you just want simple FlowDocument rendering with a scrollbar you should        The ListBox control
          go with the FlowDocumentScrollViewer - it's simple and is the least space         The ComboBox control
          and
resource consuming of the three. If you want a paged view, go with the
          FlowDocumentPageViewer, unless you want your user to be able to switch
          between the
modes and be able to quickly search, in which case you should       The ListView control
          use the FlowDocumentReader.
                                                                                            Introduction
                                                                                            A simple ListView
               Previous                                                   Next              ListView, data binding and
                                                                                             ItemTemplate
                                                                                            ListView with a GridView
                                                                                            How-to: Left aligned column
         comments powered by Disqus                                                          names
                                                                                            ListView grouping
                                                                                               ListView sorting
                                                                                               How-to: ListView with
                                                                                                column sorting
                                                                                               ListView filtering
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                             
   
Download
                                                              PDF!
                                                                             
Back to Top
Home Contact Us
                                                                                           Download as PDF
       Creating a FlowDocument from Code-
       behind                                                                                     Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
                                                                                           About WPF
         
So far, we've been creating our FlowDocument's directly in XAML.
                                                                                            What is WPF?
          Representing a document in XAML makes sense, because XAML is so much
                                                                                            WPF vs. WinForms
          like HTML, which is
used all over the Internet to create pages of information.
          However, this obviously doesn't mean that you can't create FlowDocument's
          from Code-behind - you
absolutely can, since every element is represented
          by a class that you can instantiate and add with good, old C# code.              Getting started
                                                                                            Visual Studio Express
         
As a bare minimum example, here's our "Hello, world!" example from one of         Hello, WPF!
          the first articles, created from Code-behind instead of XAML:
            <Window                                                                        XAML
            x:Class="WpfTutorialSamples.Rich_text_controls.CodeBehindFlo
                                                                                            What is XAML?
                                                                                            Basic XAML
                                                                                            Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="CodeBehindFlowDocumentSample" Height="200"                    Introduction
            Width="300">                                                                    The Window
                 <Grid>                                                                     Working with App.xaml
                       <FlowDocumentScrollViewer Name="fdViewer" />                         Command-line parameters
                 </Grid>                                                                    Resources
            </Window>                                                                       Handling exceptions
                                                                                           Basic controls
            using System;
                                                                                            The TextBlock control
            using System.Windows;
                                                                                            The TextBlock control - Inline
            using System.Windows.Documents;
                                                                                            formatting
            using System.Windows.Media;
                                                                                            The Label control
                                                                                            The TextBox control
            namespace WpfTutorialSamples.Rich_text_controls
                                                                                            The CheckBox control
            {
                                                                                    Commands
                                                                                     Introduction
                                                                                     Using commands
                                                                                     Implementing custom
                                                                                      commands
                                                                                    Common interface
         
When compared to the small amount of XAML required to achieve the exact
                                                                                    controls
          same thing, this is hardly impressive:
                                                                                     The Menu control
                                                                                     The ContextMenu
            <FlowDocument>
                                                                                     The ToolBar control
                 <Paragraph FontSize="36">Hello, world!</Paragraph>
                                                                                     The StatusBar control
                 <Paragraph FontStyle="Italic" TextAlignment="Left"
                                                                                     The Ribbon Control
            FontSize="14" Foreground="Gray">The ultimate programming
            greeting!</Paragraph>
            </FlowDocument>
                                                                                    Rich Text controls
                                                                                           Introduction
         
That's beside the point here though - sometimes it just makes more sense to
                                                                                           The
          handle stuff from Code-behind, and as you can see, it's definitely possible.
                                                                                            FlowDocumentScrollViewer
                                                                                            control
               Previous                                                   Next             The
                                                                                            FlowDocumentPageViewer
                                                                                            control
                                                                                           The FlowDocumentReader
         comments powered by Disqus                                                         control
                                                                                           Creating a FlowDocument
                                                                                            from Code-behind
                                                                                           Advanced FlowDocument
                                                                                            content
                                                                                           The RichTextBox control
                                                                                         Misc. controls
                                                                                           The Border control
                                                                                           The Slider control
                                                                                           The ProgressBar control
                                                                                           The WebBrowser control
                                                                                           The WindowsFormsHost
                                                                                           control
                                                                                         The TabControl
                                                                                           Using the TabControl
                                                                                           Tab positions
                                                                                           Styling the TabItems
                                                                                         List controls
                                                                                           The ItemsControl
                                                                                           The ListBox control
                                                                                           The ComboBox control
ListView filtering
                                                                                               Styles
                                                                                                Introduction
                                                                                                Using styles
                                                                                                Triggers
                                                                                                Multi triggers
                                                                                                Trigger animations
                                                                                               Misc.
                                                                                                The DispatcherTimer
                                                                       
      
Download
                                                                       PDF!
                                                                       
Back to Top
Home Contact Us
                                                                                             Download as PDF
       Advanced FlowDocument content
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
         
As I already mentioned, the text presentation capabilities of WPF and the          About WPF
          FlowDocument is very rich - you can do almost anything, and this includes
                                                                                              What is WPF?
          stuff
like lists, images and even tables. So far, we've used very basic
                                                                                              WPF vs. WinForms
          examples of FlowDocument content, but in this article, we'll finally do a more
          comprehensive example.
         
The XAML code for the next example might look a bit overwhelming, but              Getting started
          notice how simple it actually is - just like HTML, you can format text simply by    Visual Studio Express
         
placing them in styled paragraphs. Now have a look at the XAML. A                   Hello, WPF!
          screenshot of the result will follow directly after it:
            <Window                                                                          XAML
            x:Class="WpfTutorialSamples.Rich_text_controls.ExtendedFlowD
                                                                                              What is XAML?
                                                                                              Basic XAML
                                                                                              Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ExtendedFlowDocumentSample" Height="550"                        Introduction
            Width="500">                                                                      The Window
                 <Grid>                                                                       Working with App.xaml
                       <FlowDocumentScrollViewer>                                             Command-line parameters
                            <FlowDocument>                                                    Resources
                                   <Paragraph>                                                Handling exceptions
                                       <Image Source="http://www.wpf-
            tutorial.com/images/logo.png" Width="90" Height="90"
            Margin="0,0,30,0" />                                                             Basic controls
                                       <Run FontSize="120">WPF</Run>                          The TextBlock control
                                   </Paragraph>                                               The TextBlock control - Inline
                                                                                              formatting
                                   <Paragraph>                                                The Label control
                                       WPF, which stands for                                  The TextBox control
                                       <Bold>Windows Presentation                             The CheckBox control
            Foundation</Bold>,
                                                 <TableCell>
                                                                      Introduction
                                                       <Paragraph
                                                                      The
            TextAlignment="Right">1.718.000</Paragraph>
                                                                       FlowDocumentScrollViewer
                                                 </TableCell>
                                                                       control
                                                 <TableCell>
                                                                      The
                                                       <Paragraph
                                                                       FlowDocumentPageViewer
            TextAlignment="Right">1.542.000</Paragraph>
                                                                       control
                                                 </TableCell>
                                                                      The FlowDocumentReader
                                            </TableRow>
                                                                       control
                                       </TableRowGroup>
                                                                      Creating a FlowDocument
                                       <TableRowGroup>
                                                                       from Code-behind
                                            <TableRow>
                                                                      Advanced FlowDocument
                                                 <TableCell
                                                                       content
            Background="Gainsboro" FontWeight="Bold">
                                                                      The RichTextBox control
            <Paragraph>Developers</Paragraph>
                                                 </TableCell>
                                                                    Misc. controls
                                                 <TableCell>
                                                       <Paragraph     The Border control
            TextAlignment="Right">633.000</Paragraph>                 The Slider control
                                                 </TableCell>         The ProgressBar control
                                                 <TableCell>          The WebBrowser control
                                                       <Paragraph     The WindowsFormsHost
            TextAlignment="Right">981.000</Paragraph>                 control
                                                 </TableCell>
                                            </TableRow>
                                       </TableRowGroup>             The TabControl
                                   </Table>                           Using the TabControl
                                   <Paragraph Foreground="Silver"     Tab positions
            FontStyle="Italic">A table of made up WinForms/WPF        Styling the TabItems
            numbers</Paragraph>
                            </FlowDocument>
                       </FlowDocumentScrollViewer>
                                                                    List controls
                 </Grid>
                                                                      The ItemsControl
            </Window>
                                                                      The ListBox control
                                                                      The ComboBox control
ListView filtering
         
I'm not going to go too much into details about each of the tags - hopefully
          they should make sense as they are.                                                The DataGrid control
                                                                                              Introduction
         
As you can see, including lists, images and tables are pretty easy, but in fact,    Custom columns
          you can include any WPF control inside of your FlowDocument. Using the              Details row
          BlockUIContainer element you get access to all controls that would otherwise
          only be available inside of a window. Here's an example:
                                                                                             Styles
            <Window
                                                                                              Introduction
            x:Class="WpfTutorialSamples.Rich_text_controls.BlockUIContai
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Trigger animations
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                             Misc.
                       xmlns:self="clr-
            namespace:WpfTutorialSamples.Rich_text_controls"                                  The DispatcherTimer
                       Title="BlockUIContainerSample" Height="275"
            Width="300">
                 <Window.Resources>                                                          Audio & Video
                       <x:Array x:Key="UserArray" Type="{x:Type                               Playing audio
            self:User}">                                                                      Playing video
                            <self:User Name="John Doe" Age="42"/>                             How-to: Complete media
         
Now we have a FlowDocument with a ListView inside of it, and as you can
          see from the screenshot, the ListView works just like it normally would,
          including
selections etc. Pretty cool!
         
Summary
         
By using the techniques described in the two examples of this article, pretty
          much anything is possible, when creating FlowDocument documents. It's
          excellent for presenting visual information to the end-user, as seen in many
          of the expensive reporting suites.
Previous Next
                                                                  
         
Download
                                                                   PDF!
                                                                                             
Back to Top
Home Contact Us
                                                                                          Download as PDF
        The RichTextBox control
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
So far, we've only looked at the read-only wrappers for the FlowDocument,       About WPF
          but WPF also includes a control which makes a FlowDocument editable: The
                                                                                           What is WPF?
          RichTextBox control.
                                                                                           WPF vs. WinForms
         
You can add a RichTextBox directly to the window, without any content - in
          that case, it will automatically create a FlowDocument instance that you will
          be
editing. Alternatively, you can wrap a FlowDocument instance with the        Getting started
          RichTextBox and thereby control the initial content. It could look like this:    Visual Studio Express
                                                                                           Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxSa
                                                                                          XAML
                                                                                           What is XAML?
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Basic XAML
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="RichTextBoxSample" Height="200"
                                                                                          A WPF application
            Width="300">
                  <Grid>                                                                   Introduction
                       <RichTextBox Margin="10">                                           The Window
                             <FlowDocument>                                                Working with App.xaml
                                   <Paragraph FontSize="36">Hello, world!                  Command-line parameters
            </Paragraph>                                                                   Resources
                                   <Paragraph FontStyle="Italic"                           Handling exceptions
            TextAlignment="Left" FontSize="14"
            Foreground="Gray">Thanks to the RichTextBox control, this
            FlowDocument is completely editable!</Paragraph>                              Basic controls
                             </FlowDocument>                                               The TextBlock control
                       </RichTextBox>                                                      The TextBlock control - Inline
                  </Grid>                                                                  formatting
            </Window>                                                                      The Label control
                                                                                           The TextBox control
                                                                                           The CheckBox control
                                                                                           Panels
                                                                                            Introduction to WPF Panels
                                                                                            The Canvas
                                                                                            The WrapPanel
                                                                                            The StackPanel
                                                                                            The DockPanel
                                                                                            The Grid
         
With this example, you can start editing your rich text content straight away.    The Grid - Rows & Columns
          However, now that the content is no longer read-only, it's obviously              The Grid - Units
          interesting how you can manipulate the text, as well as work with the             The Grid - Spanning
          selection. We'll look into that right now.                                        The Grid - GridSplitter
                                                                                            Using the Grid: A contact
         
Another interesting aspect is of course working with the various formatting
                                                                                             form
          possibilities - we'll look into that in the next article, where we actually
          implement a small, but fully functional rich text editor.
                                                                                           Data binding
         
Working with text and selection
                                                                                            Introduction
         
Because the RichTextBox uses a FlowDocument internally, and because the           Hello, bound world!
          rich text format is obviously more complicated than plain text, working with      Using the DataContext
          text
and selections are not quite as easy as for the WPF TextBox control.         The UpdateSourceTrigger
                                                                                             property
         
The next example will provide show off a range of functionality that works
                                                                                            Responding to changes
          with the text and/or selection in the RichTextBox control:
                                                                                            Value conversion with
                                                                                             IValueConverter
            <Window                                                                         The StringFormat property
            x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxTe                    Debugging data bindings
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Commands
                                                                                            Introduction
                                                                                            Using commands
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                            Implementing custom
                       Title="RichTextBoxTextSelectionSample"
                                                                                             commands
            Height="300" Width="400">
                  <DockPanel>
                       <WrapPanel DockPanel.Dock="Top">
                             <Button Name="btnGetText"                                     Common interface
            Click="btnGetText_Click">Get text</Button>                                     controls
                             <Button Name="btnSetText"                                      The Menu control
            Click="btnSetText_Click">Set text</Button>                                      The ContextMenu
                             <Button Name="btnGetSelectedText"                              The ToolBar control
            Click="btnGetSelectedText_Click">Get sel. text</Button>                         The StatusBar control
                             <Button Name="btnSetSelectedText"                              The Ribbon Control
            Click="btnSetSelectedText_Click">Replace sel.
            text</Button>
                       </WrapPanel>                                                        Rich Text controls
                                                                                 Misc. controls
            using System;                                                          The Border control
            using System.Windows;                                                  The Slider control
            using System.Windows.Controls;                                         The ProgressBar control
            using System.Windows.Documents;                                        The WebBrowser control
                                                                                   The WindowsFormsHost
            namespace WpfTutorialSamples.Rich_text_controls                        control
            {
            	          public partial class
            RichTextBoxTextSelectionSample : Window
                                                                                 The TabControl
            	{
            		public RichTextBoxTextSelectionSample()                              Using the TabControl
            		{                                                                    Tab positions
            			InitializeComponent();                                              Styling the TabItems
            		}
                                                                                        ListView filtering
            		private void
            btnGetSelectedText_Click(object sender, RoutedEventArgs e)
            		{
            			                                                                        The TreeView control
            MessageBox.Show(rtbEditor.Selection.Text);                                  Introduction
            		}                                                                         A simple TreeView
                                                                                        TreeView, data binding and
            		private void                                                               multiple templates
            btnSetSelectedText_Click(object sender, RoutedEventArgs e)                  Handling
            		{                                                                          Selection/Expansion state
            			rtbEditor.Selection.Text = "                                             Lazy loading TreeView items
            [Replaced text]";
            		}
                                                                                       The DataGrid control
            		private void
                                                                                        Introduction
            rtbEditor_SelectionChanged(object sender, RoutedEventArgs
                                                                                        Custom columns
            e)
                                                                                        Details row
            		{
            			                               TextRange tempRange = new
            TextRange(rtbEditor.Document.ContentStart,
                                                                                       Styles
            rtbEditor.Selection.Start);
            			                               txtStatus.Text = "Selection starts        Introduction
                at character #" + tempRange.Text.Length +                               Using styles
            Environment.NewLine;                                                        Triggers
            			                               txtStatus.Text += "Selection is "         Multi triggers
            + rtbEditor.Selection.Text.Length + " character(s) long" +                  Trigger animations
                Environment.NewLine;
            			                               txtStatus.Text += "Selected text:
            '" + rtbEditor.Selection.Text + "'";                                       Misc.
            		}                                                                         The DispatcherTimer
            	}
            }
         
As you can see, the markup consists of a panel of buttons, a RichTextBox
          and a TextBox in the bottom, to show the current selection status. Each of
          the
four available buttons will work with the RichTextBox by either getting or
          setting/replacing text, to show you how that's done.
         
In Code-behind, we handle the four buttons click events, as well as the
          SelectionChanged event for the RichTextBox, which allows us to show
          statistics
about the current selection.
         
Pay special attention to the fact that instead of accessing a text property
          directly on the RichTextBox, as we would do with a regular TextBox, we're
          using
TextRange objects with TextPointer's from the RichTextBox to obtain
          text from the control or the selection in the control. This is simply how it works
          with
RichTextBox, which, as already mentioned, doesn’t work like a regular
          TextBox in several aspects.
         
Paragraph spacing
         
Another thing you may have noticed when working with the RichTextBox, is
          the fact that when you press Enter to start a new paragraph, this paragraph
          will
leave an empty line between the old and the new paragraph. Allow me to
          illustrate with a screenshot, where I've entered three lines of text, each just
          separated by a single Enter key press:
         
This is normal behavior for a text editor working in paragraphs, but
          depending on how and where you use the RichTextBox, it might be confusing
          for your
users that a single Enter press results in such a large amount of
          space between the lines.
         
Fortunately, it's very easy to fix. The extra spaces comes from the fact that
          paragraphs have a default margin bigger than zero, so fixing it is as simple
          as changing this property, which we can do with a style, like this:
            <Window
            x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxPa
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="RichTextBoxParagraphSpacingSample"
            Height="150" Width="300">
                  <Grid>
                       <RichTextBox Margin="10">
                             <RichTextBox.Resources>
                                   <Style TargetType="{x:Type Paragraph}">
                                        <Setter Property="Margin" Value="0" />
                                   </Style>
                             </RichTextBox.Resources>
                       </RichTextBox>
                  </Grid>
            </Window>
         
Now the lines don't have extra space around them, and if you want, you can
          place the style in the window or even in App.xaml, if you want it to work for
          more than just a single RichTextBox.
         
Summary
         
The RichTextBox is easy to use, has lots of features straight out of the box,
          and can easily be used if you wish to create a fully featured rich text
editor. In
          the next article, we'll have a look at doing just that! This will also get us
          around important subjects such as loading and saving text from a
          RichTextBox and how to affect formatting of text in the control.
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                               
Back to Top
Home Contact Us
                                                                                          Download as PDF
        The Border control
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
          
The Border control is a Decorator control that you may use to draw a border,   About WPF
           a background, or even both, around another element. Since the WPF panels
                                                                                           What is WPF?
           don't
support drawing a border around its edges, the Border control can help
                                                                                           WPF vs. WinForms
           you achieve just that, simply by surrounding e.g. a Panel with the Border
           control.
          
A simple example on using the Border as described above could look like        Getting started
           this:                                                                           Visual Studio Express
                                                                                           Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.BorderSample"
                                                                                          XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           What is XAML?
                                                                                           Basic XAML
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="BorderSample" Height="170" Width="200">
                  <Grid Margin="10">
                                                                                          A WPF application
            		<Border Background="GhostWhite"
            BorderBrush="Gainsboro" BorderThickness="1">                                   Introduction
            			<StackPanel Margin="10">                                                    The Window
            				<Button>Button 1</Button>                                                  Working with App.xaml
            				<Button                                                                    Command-line parameters
            Margin="0,10">Button 2</Button>                                                Resources
            				<Button>Button 3</Button>                                                  Handling exceptions
            			</StackPanel>
            		</Border>
            	</Grid>                                                                      Basic controls
            </Window>                                                                      The TextBlock control
                                                                                           The TextBlock control - Inline
                                                                                           formatting
                                                                                           The Label control
                                                                                           The TextBox control
                                                                                           The CheckBox control
                                                                                               Panels
                                                                                                Introduction to WPF Panels
          
The Border is completely lookless until you define either a background or a          The Canvas
           border brush and thickness, so that's what I've done here, using the                 The WrapPanel
           Background, BorderBrush and BorderThickness properties.                              The StackPanel
                                                                                                The DockPanel
          
Border with round corners                                                            The Grid
                                                                                                The Grid - Rows & Columns
          
One of the features I really appreciate about the Border is the fact that it's so    The Grid - Units
           easy to get round corners. Just look at this slightly modified example,
where        The Grid - Spanning
           the corners are now rounded:                                                         The Grid - GridSplitter
                                                                                                Using the Grid: A contact
            <Window                                                                              form
            x:Class="WpfTutorialSamples.Misc_controls.BorderSample"
                                                                                               Common interface
                                                                                               controls
                                                                                                The Menu control
                                                                                                The ContextMenu
                                                                                                The ToolBar control
                                                                                                The StatusBar control
                                                                                                The Ribbon Control
          
All I've done is adding the CornerRadius property. It can be specified with a      Rich Text controls
           single value, which will be used for all four corners, or
like I did in the
                                                                                                Introduction
           example here, where I specify separate values for the top right and left
                                                                                                The
           followed by the bottom right and left.
                                                                                                 FlowDocumentScrollViewer
                                                                                                 control
          
Border color/thickness                                                               The
          
The above border is very discrete, but this can easily be changed by                  FlowDocumentPageViewer
           regulating the color and/or thickness. Because the BorderThickness property           control
           is of the Thickness type, you can even manipulate each of the border widths          The FlowDocumentReader
           individually or by giving a value for the left and right and one for the
top and      control
           bottom borders.                                                                      Creating a FlowDocument
                                                                                                 from Code-behind
                                                                                                Advanced FlowDocument
            <Window
                                                                                                 content
            x:Class="WpfTutorialSamples.Misc_controls.BorderSample"
                                                                                                The RichTextBox control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Misc. controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                              The Border control
                        Title="BorderSample" Height="175" Width="200">                          The Slider control
                  <Grid Margin="10">                                                            The ProgressBar control
            		<Border Background="GhostWhite"                                                   The WebBrowser control
            BorderBrush="DodgerBlue" BorderThickness="1,3,1,5">                                 The WindowsFormsHost
            			<StackPanel Margin="10">                                                         control
            				<Button>Button 1</Button>
            				<Button
            Margin="0,10">Button 2</Button>                                                   The TabControl
            				<Button>Button 3</Button>
                                                                                                Using the TabControl
            			</StackPanel>
                                                                                                Tab positions
            		</Border>
                                                                                                Styling the TabItems
            	</Grid>
            </Window>
                                                                                              List controls
                                                                                                The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
                                                                                           Introduction
                                                                                           A simple ListView
                                                                                           ListView, data binding and
                                                                                            ItemTemplate
          
Border background                                                               ListView with a GridView
                                                                                           How-to: Left aligned column
          
The Background property is of the type Brush, which opens up a lot of cool       names
           possibilities. As seen in the initial examples, it's very easy to just use a    ListView grouping
           simple color as the background, but you can actually use gradients as well,     ListView sorting
           and it's not even that hard to do:                                              How-to: ListView with
                                                                                            column sorting
            <Window                                                                        ListView filtering
            x:Class="WpfTutorialSamples.Misc_controls.BorderSample"
                                                                                              Playing audio
                                                                                              Playing video
                                                                                              How-to: Complete media
                                                                                              player
                                                                                              Speech synthesis
                                                                                              Speech recognition
          
In this case, I've specified a LinearGradientBrush to be used for the
           background of the Border and then a more fitting border color. The
           LinearGradientBrush might not have the most obvious syntax, so I will
           explain that in a later chapter, including other brush types, but for now, you
           can
try my example and change the values to see the result.
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                                    
Back to Top
Home Contact Us
                                                                                                 Download as PDF
        The Slider control
                                                                                                        Download this entire
                                                                                                        tutorial as PDF right
                                                                                                 now!
          
The Slider control allows you to pick a numeric value by dragging a thumb             About WPF
           along a horizontal or vertical line. You see it in a lot of user interfaces, but
it
                                                                                                  What is WPF?
           can still be a bit hard to recognize from the description alone, so here's a
                                                                                                  WPF vs. WinForms
           very basic example:
             <Window
                                                                                                 Getting started
             x:Class="WpfTutorialSamples.Misc_controls.SliderSample"
                                                                                                  Visual Studio Express
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                         Hello, WPF!
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                              XAML
                        Title="SliderSample" Height="100" Width="300">                            What is XAML?
                   <StackPanel VerticalAlignment="Center" Margin="10">                            Basic XAML
                        <Slider Maximum="100" />                                                  Events in XAML
                   </StackPanel>
             </Window>
                                                                                                 A WPF application
                                                                                                  Introduction
                                                                                                  The Window
                                                                                                  Working with App.xaml
                                                                                                  Command-line parameters
                                                                                                  Resources
                                                                                                  Handling exceptions
          
This will allow the end-user to select a value between 0 and 100 by dragging
           the button (referred to as the thumb) along the line.
                                                                                                 Basic controls
          
Ticks                                                                                  The TextBlock control
                                                                                                  The TextBlock control - Inline
          
In the example, I have dragged the thumb beyond the middle, but it's                   formatting
           obviously hard to see the exact value. One way to remedy this is to turn on            The Label control
           ticks,
which are small markers shown on the line to give a better indication on        The TextBox control
           how far the thumb is. Here's an example:                                               The CheckBox control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Panels
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                               The WrapPanel
                        Title="SliderSample" Height="100" Width="300">
                                                                                               The StackPanel
                   <StackPanel VerticalAlignment="Center" Margin="10">
                                                                                               The DockPanel
                        <Slider Maximum="100" TickPlacement="BottomRight"
                                                                                               The Grid
             TickFrequency="5" />
                                                                                               The Grid - Rows & Columns
                   </StackPanel>
                                                                                               The Grid - Units
             </Window>
                                                                                               The Grid - Spanning
                                                                                               The Grid - GridSplitter
                                                                                               Using the Grid: A contact
                                                                                                form
                                                                                              Data binding
                                                                                               Introduction
                                                                                               Hello, bound world!
          
I turn on the tick markers by giving the TickPlacement property another
                                                                                               Using the DataContext
           value than None, which is the default. In my example, I want the
ticks placed
                                                                                               The UpdateSourceTrigger
           below the line, but you can use TopLeft or even Both as possible values, to
                                                                                                property
           change this.
                                                                                               Responding to changes
          
Also notice my use of the TickFrequency property. It defaults to 1, but in an       Value conversion with
           example where the range of possible values goes from 0 to
100, this will             IValueConverter
           result in 100 tick markers, which will have to be fitted into the limited space.    The StringFormat property
           In a case like this, it makes sense to raise the
TickFrequency to something         Debugging data bindings
           that will make it look less crowded.
          
Snapping to ticks                                                                  Commands
                                                                                               Introduction
          
If you have a look at the screenshot above, you will see that the thumb is
                                                                                               Using commands
           between ticks. This makes sense, since there are five values between each
                                                                                               Implementing custom
           tick,
as specified by the TickFrequency property. Also, the value of the Slider
                                                                                                commands
           control is in fact by default a double, meaning that the value can (and will
           likely) be a non-integer. We can change this by using the
           IsSnapToTickEnabled property, like in the below example:
                                                                                              Common interface
                                                                                              controls
             <Window
             x:Class="WpfTutorialSamples.Misc_controls.SliderSnapToTickSa                      The Menu control
                                                                                               The ContextMenu
                                                                                               The ToolBar control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The StatusBar control
                                                                                               The Ribbon Control
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="SliderSnapToTickSample" Height="100"                           Rich Text controls
             Width="300">                                                                      Introduction
                   <StackPanel VerticalAlignment="Center" Margin="10">                         The
                        <Slider Maximum="100" TickPlacement="BottomRight"                       FlowDocumentScrollViewer
             TickFrequency="10" IsSnapToTickEnabled="True" />                                   control
                   </StackPanel>                                                               The
             </Window>                                                                          FlowDocumentPageViewer
                                                                                                control
                                                                                               The FlowDocumentReader
                                                                                                control
                                                                                               Creating a FlowDocument
                                                                                                from Code-behind
                                                                                               Advanced FlowDocument
                                                                                                content
                                                                                               The RichTextBox control
          
Notice that I've changed the TickFrequency to 10, and then enabled the
           IsSnapToTickEnabled property. This ensures that the thumb can only be
           placed
directly on a tick value, so for this example, it can only be 0, 10, 20,   Misc. controls
           30, 40 and so on.
                                                                                               The Border control
                                                                                               The Slider control
          
Slider value                                                                        The ProgressBar control
          
So far, we've just used the Slider illustratively, but of course, the actual        The WebBrowser control
           purpose is to read its current value and use it for something. The Slider has
a     The WindowsFormsHost
           Value property for that, which you can of course read from Code-behind, or          control
           even bind to.
          
A common scenario in using the Slider is to combine it with a TextBox, which      The TabControl
           will allow the user to see the currently selected value, as well as changing
it
                                                                                               Using the TabControl
           by entering a number instead of dragging the Slider thumb. Normally, you
                                                                                               Tab positions
           would have to subscribe to change events on both the Slider and the
                                                                                               Styling the TabItems
           TextBox and
then update accordingly, but a simple binding can do all of that
           for us:
                                                                                             List controls
             <Window
             x:Class="WpfTutorialSamples.Misc_controls.SliderBoundValueSa                      The ItemsControl
                                                                                               The ListBox control
                                                                                               The ComboBox control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
          
Responding to changed values                                                       Styles
                                                                                               Introduction
          
Of course, while bindings are very cool for a lot of purposes, you still may
                                                                                               Using styles
           want to respond to changes in the Slider value from your Code-behind.
                                                                                               Triggers
           Fortunately for us, the Slider comes with a ValueChanged event which will
                                                                                               Multi triggers
           help us with that. To illustrate this, I've created a more complex sample with
                                                                                               Trigger animations
           three sliders, where we change the Red, Green and Blue (RGB) values of a
           color:
                                                                                              Misc.
             <Window
             x:Class="WpfTutorialSamples.Misc_controls.SliderValueChanged                      The DispatcherTimer
             using System;
             using System.Windows;
             using System.Windows.Media;
             namespace WpfTutorialSamples.Misc_controls
             {
             	          public partial class SliderValueChangedSample :
             Window
             	{
             		public SliderValueChangedSample()
             		{
             			InitializeComponent();
             		}
             		private void
             ColorSlider_ValueChanged(object sender,
             RoutedPropertyChangedEventArgs<double> e)
             		{
             			Color color =
             Color.FromRgb((byte)slColorR.Value, (byte)slColorG.Value,
             (byte)slColorB.Value);
             			this.Background = new
             SolidColorBrush(color);
             		}
             	}
             }
          
In the XAML part of the code, we have three DockPanels, each with a Label,
           a Slider and a TextBox control. Just like before, the Text property of the
           TextBox controls have been bound to the Value of the Slider.
          
Each slider subscribes to the same ValueChanged event, in which we create
           a new Color instance, based on the currently selected values and
then uses
           this color to create a new SolidColorBrush for the Background property of the
           Window.
          
All in all, this is a pretty good example of what the Slider control can be used
           for.
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                              
Back to Top
Home Contact Us
                                                                                            Download as PDF
        The ProgressBar control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          
WPF comes with a handy control for displaying progress, called the               About WPF
           ProgressBar. It works by setting a minimum and maximum value and then
                                                                                             What is WPF?
           incrementing a value, which will give a visual indication on how far in the
                                                                                             WPF vs. WinForms
           process you currently are. Here's a very basic example to demonstrate it
           with:
                                                                                            Getting started
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.ProgressBarSample"                     Visual Studio Express
                                                                                             Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            XAML
                                                                                             What is XAML?
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           Basic XAML
                        Title="ProgressBarSample" Height="100"                               Events in XAML
            Width="300">
                  <Grid Margin="20">
                        <ProgressBar Minimum="0" Maximum="100" Value="75"
                                                                                            A WPF application
            />
                                                                                             Introduction
                  </Grid>
                                                                                             The Window
            </Window>
                                                                                             Working with App.xaml
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
                                                                                            Basic controls
                                                                                             The TextBlock control
          
In this case, I've used a pretty standard approach of showing progress as a       The TextBlock control - Inline
           percentage (between 0 and 100%), giving it an initial value of 75. Another        formatting
           approach is to use actual minimum and maximum values from a list of tasks         The Label control
           you're performing. For instance, if you loop through a collected list of files    The TextBox control
           while checking each of them, you can set the Minimum property to 0, the           The CheckBox control
          Maximum to the amount of files in your list, and then just increment as you       The RadioButton control
          loop
through it.                                                                  The PasswordBox control
          
The ProgressBar is, just like other standard WPF controls, rendered to match
           the visual style of the operating system. Here on Windows 7, it has a nice      Panels
           animated gradient, as seen on the screenshot.
                                                                                            Introduction to WPF Panels
                                                                                            The Canvas
          
Showing progress while performing a                                              The WrapPanel
           lengthy task                                                                     The StackPanel
          
The above example illustrates how simple it is to use a ProgressBar, but         The DockPanel
           normally you would of course want to show the progress of some actual work       The Grid
           and not
just a static value.                                                     The Grid - Rows & Columns
                                                                                            The Grid - Units
          
In most situations you will use the ProgressBar to show progress for some        The Grid - Spanning
           heavy/lengthy task, and this this is where most new programmers run into a       The Grid - GridSplitter
           very
common problem: If you do a piece of heavy work on the UI thread,           Using the Grid: A contact
           while trying to simultaneously update e.g. a ProgressBar control, you will        form
           soon realize
that you can't do both, at the same time, on the same thread. Or
           to be more clear, you can, but the ProgressBar won't actually show each
           update to the
progress before the task is completed, which pretty much          Data binding
           renders it useless.
                                                                                            Introduction
          
To illustrate, you can try the following example:                                Hello, bound world!
                                                                                            Using the DataContext
                                                                                            The UpdateSourceTrigger
            <Window
                                                                                             property
            x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTaskOnU
                                                                                            Responding to changes
                                                                                            Value conversion with
                                                                                             IValueConverter
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            The StringFormat property
                                                                                            Debugging data bindings
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ProgressBarTaskOnUiThread" Height="100"
            Width="300"
                                                                                           Commands
                        ContentRendered="Window_ContentRendered">                           Introduction
                  <Grid Margin="20">                                                        Using commands
                        <ProgressBar Minimum="0" Maximum="100"                              Implementing custom
            Name="pbStatus" />                                                               commands
                  </Grid>
            </Window>
                                                                                           Common interface
                                                                                           controls
            using System;                                                                   The Menu control
            using System.Threading;                                                         The ContextMenu
            using System.Windows;                                                           The ToolBar control
                                                                                            The StatusBar control
            namespace WpfTutorialSamples.Misc_controls                                      The Ribbon Control
            {
            	           public partial class ProgressBarTaskOnUiThread :
            Window                                                                         Rich Text controls
            	{                                                                                  Introduction
            		public ProgressBarTaskOnUiThread()                                                The
            		{                                                                                  FlowDocumentScrollViewer
            			InitializeComponent();                                                            control
            		}                                                                                 The
                                                                                                 FlowDocumentPageViewer
            		                     private void Window_ContentRendered(object                    control
              sender, EventArgs e)                                                              The FlowDocumentReader
            		{                                                                                  control
            			                                for(int i = 0; i < 100; i++)                     Creating a FlowDocument
            			{                                                                                 from Code-behind
            				pbStatus.Value++;                                                               Advanced FlowDocument
            				Thread.Sleep(100);                                                               content
            			}                                                                                The RichTextBox control
            		}
            	}
            }                                                                                 Misc. controls
                                                                                                The Border control
          
A very basic example, where, as soon as the window is ready, we do a loop            The Slider control
           from 0 to 100 and in each iteration, we increment the value of the                   The ProgressBar control
           ProgressBar.
Any modern computer can do this faster than you can blink               The WebBrowser control
           your eyes, so I've added a delay to each iteration of 100 milliseconds.              The WindowsFormsHost
           Unfortunately, as I
already described, nothing will happen. This is how it           control
           looks in the middle of the process:
                                                                                              The TabControl
                                                                                                Using the TabControl
                                                                                                Tab positions
                                                                                                Styling the TabItems
          
Notice that the cursor indicates that something is happening, yet the
           ProgressBar still looks like it did at the start (empty). As soon as the loop,     List controls
           which
represents our lengthy task, is done, the ProgressBar will look like this:     The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
ListView filtering
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            			worker.RunWorkerAsync();
            		}
            BackgroundWorker).ReportProgress(i);
            				Thread.Sleep(100);
            			}
            		}
          
As you can see on the screenshot, the progress is now updated all the way
           through the task, and as the cursor indicates, no hard work is being
           performed on
the UI thread, which means that you can still interact with the
           rest of the interface.
          
Please be aware that while the BackgroundWorker does help a lot with
           multithreading related problems, there are still some things you should be
           aware of,
so please have a look at the BackgroundWorker articles in this
           tutorial before doing anything more advanced than a scenario like the one
           above.
          
Indeterminate
          
For some tasks, expressing the progress as a percentage is not possible or
           you simply don't know how long it will take. For those situations, the
           indeterminate progress bar has been invented, where an animation lets the
           user know that something is happening, while indicating that the running time
          
can't be determined.
          
The WPF ProgressBar supports this mode through the use of the
           IsIndeterminate property, which we'll show you in the next example:
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.ProgressBarIndeter
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ProgressBarIndeterminateSample"
            Height="100" Width="300">
                  <Grid Margin="20">
                        <ProgressBar Minimum="0" Maximum="100"
            Name="pbStatus" IsIndeterminate="True" />
                  </Grid>
            </Window>
          
Notice that the green progress indicator is not anchored to either of the sides
           - instead it floats freely from start to finish and then it starts all over
again.
          
ProgressBar with text
          
One thing that I really missed from the standard WPF ProgressBar is the
           ability to show a text representation of the progress as well as the progress
           bar.
Fortunately for us, the flexibility of WPF makes this really easy for us to
           accomplish. Here's an example:
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTextSam
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ProgressBarTextSample" Height="100"
            Width="300">
                  <Grid Margin="20">
                        <ProgressBar Minimum="0" Maximum="100" Value="75"
            Name="pbStatus" />
                        <TextBlock Text="{Binding ElementName=pbStatus,
            Path=Value, StringFormat={}{0:0}%}"
            HorizontalAlignment="Center" VerticalAlignment="Center" />
                  </Grid>
            </Window>
          
We accomplish the above by putting the ProgressBar and the TextBlock
          showing the percentage inside of the same Grid, without specifying any rows
          or
columns. This will render the TextBlock on top of the ProgressBar, which
          is exactly what we want here, because the TextBlock has a transparent
          background
by default.
          
We use a binding to make sure that the TextBlock show the same value as
           the ProgressBar. Notice the special StringFormat syntax, which
allows us to
           show the value with a percentage sign postfix - it might look a bit strange, but
           please see the StringFormat article of this
tutorial for more information on it.
Previous Next
                                                                  
         
Download
                                                                   PDF!
                                                                                              
Back to Top
Home Contact Us
                                                                                               Download as PDF
       The WebBrowser control
                                                                                                      Download this entire
                                                                                                      tutorial as PDF right
                                                                                               now!
         
WPF comes with a ready to use WebBrowser control, which allows you to                About WPF
          host a complete web browser within your application. The WebBrowser
                                                                                                What is WPF?
          control is really
just a shell around an ActiveX version of Internet Explorer,
                                                                                                WPF vs. WinForms
          but since this is an integrated part of Windows, your application should work
          on all Windows
machines without requiring the installation of additional
          components.
                                                                                               Getting started
         
I've done things a bit differently in this article: Instead of starting off with a    Visual Studio Express
          very limited example and then adding to it, I've create just one but
more             Hello, WPF!
          complex example. It illustrates how easy you can get a small web browser up
          and running. It's very basic in its functionality, but you can easily
extend it if
          you want to. Here's how it looks:
                                                                                               XAML
                                                                                                What is XAML?
                                                                                                Basic XAML
                                                                                                Events in XAML
                                                                                               A WPF application
                                                                                                Introduction
                                                                                                The Window
                                                                                                Working with App.xaml
                                                                                                Command-line parameters
                                                                                                Resources
                                                                                                Handling exceptions
                                                                                               Basic controls
                                                                                                The TextBlock control
                                                                                                The TextBlock control - Inline
                                                                                                formatting
                                                                                                The Label control
                                                                                                The TextBox control
                                                                                                The CheckBox control
         
So let's have a look at the code:                                   The RadioButton control
                                                                              The PasswordBox control
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.WebBrowserControlS
                                                                             Panels
                                                                              Introduction to WPF Panels
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta      The Canvas
                                                                              The WrapPanel
                                                                              The StackPanel
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"            The DockPanel
                       Title="WebBrowserControlSample" Height="300"           The Grid
            Width="450">                                                      The Grid - Rows & Columns
                 <Window.CommandBindings>                                     The Grid - Units
                       <CommandBinding                                        The Grid - Spanning
            Command="NavigationCommands.BrowseBack"                           The Grid - GridSplitter
            CanExecute="BrowseBack_CanExecute"                                Using the Grid: A contact
            Executed="BrowseBack_Executed" />                                  form
                       <CommandBinding
            Command="NavigationCommands.BrowseForward"
            CanExecute="BrowseForward_CanExecute"                            Data binding
            Executed="BrowseForward_Executed" />
                                                                              Introduction
                       <CommandBinding
                                                                              Hello, bound world!
            Command="NavigationCommands.GoToPage"
                                                                              Using the DataContext
            CanExecute="GoToPage_CanExecute"
                                                                              The UpdateSourceTrigger
            Executed="GoToPage_Executed" />
                                                                               property
                 </Window.CommandBindings>
                                                                              Responding to changes
                 <DockPanel>
                                                                              Value conversion with
                       <ToolBar DockPanel.Dock="Top">
                                                                               IValueConverter
                            <Button
                                                                              The StringFormat property
            Command="NavigationCommands.BrowseBack">
                                                                              Debugging data bindings
                                   <Image
            Source="/WpfTutorialSamples;component/Images/arrow_left.png"
             Width="16" Height="16" />
                            </Button>                                        Commands
                            <Button                                           Introduction
            Command="NavigationCommands.BrowseForward">                       Using commands
                                   <Image                                     Implementing custom
            Source="/WpfTutorialSamples;component/Images/arrow_right.png       commands
             Width="16" Height="16" />
                            </Button>
                            <Separator />                                    Common interface
                            <TextBox Name="txtUrl" Width="300"               controls
            KeyUp="txtUrl_KeyUp" />
                                                                              The Menu control
                            <Button Command="NavigationCommands.GoToPage">
                                                                              The ContextMenu
                                   <Image
                                                                              The ToolBar control
            Source="/WpfTutorialSamples;component/Images/world_go.png"
                                                                              The StatusBar control
             Width="16" Height="16" />
                                                                              The Ribbon Control
                            </Button>
                       </ToolBar>
                       <WebBrowser Name="wbSample"
                                                                             Rich Text controls
            Navigating="wbSample_Navigating"></WebBrowser>
                  </DockPanel>                                                      Introduction
            </Window>                                                               The
                                                                                     FlowDocumentScrollViewer
                                                                                     control
                                                                                    The
            using System;                                                            FlowDocumentPageViewer
            using System.Windows;                                                    control
            using System.Windows.Input;                                             The FlowDocumentReader
                                                                                     control
            namespace WpfTutorialSamples.Misc_controls                              Creating a FlowDocument
            {                                                                        from Code-behind
            	          public partial class WebBrowserControlSample :               Advanced FlowDocument
            Window                                                                   content
            	{                                                                      The RichTextBox control
            		public WebBrowserControlSample()
            		{
            			InitializeComponent();
                                                                                  Misc. controls
            			wbSample.Navigate("http://www.wpf-
                                                                                    The Border control
            tutorial.com");
                                                                                    The Slider control
            		}
                                                                                    The ProgressBar control
                                                                                    The WebBrowser control
            		                     private void txtUrl_KeyUp(object sender,
                                                                                    The WindowsFormsHost
            KeyEventArgs e)
                                                                                    control
            		{
            			if(e.Key == Key.Enter)
            				
            wbSample.Navigate(txtUrl.Text);                                       The TabControl
            		}                                                                     Using the TabControl
                                                                                    Tab positions
            		                     private void wbSample_Navigating(object          Styling the TabItems
            sender,
            System.Windows.Navigation.NavigatingCancelEventArgs e)
            		{                                                                   List controls
            			txtUrl.Text =
                                                                                    The ItemsControl
            e.Uri.OriginalString;
                                                                                    The ListBox control
            		}
                                                                                    The ComboBox control
         
The code might seem a bit overwhelming at first, but if you take a second         Misc.
          look, you'll realize that there's a lot of repetition in it.                       The DispatcherTimer
         
Let's start off by talking about the XAML part. Notice that I'm using several
          concepts discussed elsewhere in this tutorial, including the
ToolBar control
                                                                                            Audio & Video
          and WPF commands. The ToolBar is used to host a couple of buttons for
          going backward and forward. After that, we have an address bar for
entering        Playing audio
          and showing the current URL, along with a button for navigating to the             Playing video
          entered URL.                                                                       How-to: Complete media
                                                                                             player
         
Below the toolbar, we have the actual WebBrowser control. As you can see,          Speech synthesis
          using it only requires a single line of XAML - in this case we subscribe to the    Speech recognition
          Navigating event, which occurs as soon as the WebBrowser starts
          navigating to a URL.
         
In Code-behind, we start off by navigating to a URL already in the
          constructor of the Window, to have something to show immediately
instead of
          a blank control. We then have the txtUrl_KeyUp event, in which we check to
          see if the user has hit Enter inside of the address
bar - if so, we start
          navigating to the entered URL.
         
The wbSample_Navigating event makes sure that the address bar is
          updated each time a new navigation starts. This is important because we
          want it to show the current URL no matter if the user initiated the navigation
          by entering a new URL or by clicking a link on the webpage.
         
The last part of the Code-behind is simple handling of our commands: Two
          for the back and forward buttons, where we use the CanGoBack and
          CanGoForward to
decide whether they can execute, and the GoBack and
          GoForward methods to do the actual work. This is very standard when
          dealing with WPF commands, as
described in the commands section of this
          tutorial.
         
For the last command, we allow it to always execute and when it does, we
          use the Navigate() method once again.
         
Summary
         
As you can see, hosting and using a complete webbrowser inside of your
          application becomes very easy with the WebBrowser control. However, you
          should be
aware that the WPF version of WebBrowser is a bit limited when
          compared to the WinForms version, but for basic usage and navigation, it
          works fine.
         
If you wish to use the WinForms version instead, you may do so using the
          WindowsFormsHost, which is explained elsewhere in this tutorial.
Previous Next
                                                                 
         
Download
                                                                  PDF!
                                                                                            
Back to Top
Home Contact Us
                                                                                           Download as PDF
       The WindowsFormsHost control
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
         
WPF and WinForms are two distinct UI frameworks, both created by                 About WPF
          Microsoft. WPF is meant as a more modern alternative to WinForms, which
                                                                                            What is WPF?
          was the first .NET
UI framework. To lighten the transition between the two,
                                                                                            WPF vs. WinForms
          Microsoft has made sure that WinForms controls may still be used inside of a
          WPF application. This
is done with the WindowsFormsHost, which we'll
          discuss in this article.
                                                                                           Getting started
         
To use the WindowsFormsHost and controls from WinForms, you need to               Visual Studio Express
          add a reference to the following assemblies in your application:                  Hello, WPF!
             WindowsFormsIntegration
             System.Windows.Forms
                                                                                           XAML
         
In Visual Studio, this is done by right-clicking the "References" node in your    What is XAML?
          project and selecting "Add reference":                                            Basic XAML
                                                                                            Events in XAML
                                                                                           A WPF application
                                                                                            Introduction
                                                                                            The Window
                                                                                            Working with App.xaml
                                                                                            Command-line parameters
                                                                                            Resources
                                                                                            Handling exceptions
                                                                                           Basic controls
                                                                                            The TextBlock control
                                                                                            The TextBlock control - Inline
         
In the dialog that pops up, you should select "Assemblies" and then check
                                                                                            formatting
          the two assemblies that we need to add:
                                                                                            The Label control
                                                                                            The TextBox control
                                                                                            The CheckBox control
                                                                                             Panels
                                                                                              Introduction to WPF Panels
                                                                                              The Canvas
                                                                                              The WrapPanel
                                                                                              The StackPanel
                                                                                              The DockPanel
                                                                                              The Grid
                                                                                              The Grid - Rows & Columns
                                                                                              The Grid - Units
                                                                                              The Grid - Spanning
                                                                                              The Grid - GridSplitter
                                                                                              Using the Grid: A contact
                                                                                               form
         
Using the WinForms WebBrowser control
         
In a previous article, we used the WPF WebBrowser control to create a small
          web browser. However, as stated in that article, the WPF WebBrowser                Data binding
          control is
a bit limited when compared to the WinForms version. There are           Introduction
          many examples on things easily done with the WinForms version, which are            Hello, bound world!
          either harder or
impossible to do with the WPF version.                             Using the DataContext
                                                                                              The UpdateSourceTrigger
         
A small example is the DocumentTitle property and corresponding                      property
          DocumentTitleChanged event, which makes it easy to get
and update the               Responding to changes
          title of the window to match the title of the current webpage. We'll use this as    Value conversion with
          an excuse to test out the WinForms version right here in
our WPF                     IValueConverter
          application:                                                                        The StringFormat property
                                                                                              Debugging data bindings
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.WindowsFormsHostSa
                                                                                             Commands
                                                                                              Introduction
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Using commands
                                                                                              Implementing custom
                                                                                               commands
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:wf="clr-
            namespace:System.Windows.Forms;assembly=System.Windows.Forms
                                                                                             Common interface
                                                                                             controls
                       Title="WindowsFormsHostSample" Height="350"
            Width="450">                                                                      The Menu control
                 <Grid>                                                                       The ContextMenu
                       <WindowsFormsHost Name="wfhSample">                                    The ToolBar control
                            <WindowsFormsHost.Child>                                          The StatusBar control
                                   <wf:WebBrowser                                             The Ribbon Control
            DocumentTitleChanged="wbWinForms_DocumentTitleChanged" />
                            </WindowsFormsHost.Child>
                       </WindowsFormsHost>                               Rich Text controls
                 </Grid>                                                   Introduction
            </Window>                                                      The
                                                                            FlowDocumentScrollViewer
                                                                            control
                                                                           The
            using System;
                                                                            FlowDocumentPageViewer
            using System.Windows;
                                                                            control
                                                                           The FlowDocumentReader
            namespace WpfTutorialSamples.Misc_controls
                                                                            control
            {
                                                                           Creating a FlowDocument
            	          public partial class WindowsFormsHostSample :
                                                                            from Code-behind
            Window
                                                                           Advanced FlowDocument
            	{
                                                                            content
            		public WindowsFormsHostSample()
                                                                           The RichTextBox control
            		{
            			InitializeComponent();
            			(wfhSample.Child as
            System.Windows.Forms.WebBrowser).Navigate("http://www.wpf-   Misc. controls
            tutorial.com");                                                The Border control
            		}                                                            The Slider control
                                                                           The ProgressBar control
            		private void                                                 The WebBrowser control
            wbWinForms_DocumentTitleChanged(object sender, EventArgs       The WindowsFormsHost
            e)                                                             control
            		{
            			                             this.Title = (sender as
            System.Windows.Forms.WebBrowser).DocumentTitle;              The TabControl
            		}
                                                                           Using the TabControl
            	}
                                                                           Tab positions
            }
                                                                           Styling the TabItems
                                                                         List controls
                                                                           The ItemsControl
                                                                           The ListBox control
                                                                           The ComboBox control
                 xmlns:wf="clr-
            namespace:System.Windows.Forms;assembly=System.Windows.Forms                 The TreeView control
                                                                                          Introduction
                                                                                          A simple TreeView
                                                                                          TreeView, data binding and
         
This will allow us to reference WinForms controls using the wf: prefix.          multiple templates
                                                                                          Handling
         
The WindowsFormsHost is fairly simple to use, as you can see. It has a Child     Selection/Expansion state
          property, in which you can define a single WinForms control, much like the      Lazy loading TreeView items
          WPF
Window only holds a single root control. If you need more controls from
          WinForms inside of your WindowsFormsHost, you can use the Panel
control
          from WinForms or any of the other container controls.                          The DataGrid control
                                                                                          Introduction
         
The WinForms WebBrowser control is used by referencing the
                                                                                          Custom columns
          System.Windows.Forms assembly, using the wf prefix, as explained above.
                                                                                          Details row
         
In Code-behind, we do an initial call to Navigate, to have a visible webpage
          instead of the empty control on startup. We then handle
          theDocumentTitleChanged event, in which we update the Title property of        Styles
          the Window in accordance with the current DocumentTitle value of the            Introduction
          WebBrowser control.                                                             Using styles
                                                                                          Triggers
         
Congratulations, you now have a WPF application with a WinForms
                                                                                          Multi triggers
          WebBrowser hosted inside of it.
                                                                                          Trigger animations
         
Summary
         
As you can see, using WinForms controls inside of your WPF applications is     Misc.
          pretty easy, but the question remains: Is it a good idea?                       The DispatcherTimer
         
In general, you may want to avoid it. There are a number of issues that may
          or may not affect your application (a lot of them are described in this MSDN
         
article: http://msdn.microsoft.com/en-                                         Audio & Video
         us/library/aa970911%28v=VS.100%29.aspx), but
a more serious problem is           Playing audio
          that this kind of UI framework mixing might not be supported in future          Playing video
          versions of the .NET framework.                                                 How-to: Complete media
                                                                                          player
         
In the end though, the decision is up to you - do you really need the           Speech synthesis
          WinForms control or is there a WPF alternative that might work just as well?    Speech recognition
Previous Next
                                                                 
         
Download
                                                                  PDF!
                                                                                            
Back to Top
Home Contact Us
                                                                                            Download as PDF
       Using the WPF TabControl
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
The WPF TabControl allows you to split your interface up into different areas,    About WPF
          each accessible by clicking on the tab header, usually positioned at the top
of
                                                                                             What is WPF?
          the control. Tab controls are commonly used in Windows applications and
                                                                                             WPF vs. WinForms
          even within Windows' own interfaces, like the properties dialog for
          files/folders etc.
         
Just like with most other WPF controls, the TabControl is very easy to get        Getting started
          started with. Here's a very basic example:                                         Visual Studio Express
                                                                                             Hello, WPF!
         
<Window x:Class="WpfTutorialSamples.Misc_controls.TabControlSample"
            <Window
                                                                                            XAML
            x:Class="WpfTutorialSamples.Misc_controls.TabControlSample"
                                                                                             What is XAML?
                                                                                             Basic XAML
                                                                                             Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             Panels
                                                                                              Introduction to WPF Panels
                                                                                              The Canvas
                                                                                              The WrapPanel
                                                                                              The StackPanel
         
As you can see, each tab is represented with a TabItem element, where the
                                                                                              The DockPanel
          text shown on it is controlled by the Header
property. The TabItem element
                                                                                              The Grid
          comes from the ContentControl class, which means that you may define a
                                                                                              The Grid - Rows & Columns
          single element inside of it that will be shown if the
tab is active (like on the
                                                                                              The Grid - Units
          screenshot). I used a Label in this example, but if you want to place more
                                                                                              The Grid - Spanning
          than one control inside of the tab, just use one of
the panels with child
                                                                                              The Grid - GridSplitter
          controls inside of it.
                                                                                              Using the Grid: A contact
                                                                                               form
         
Customized headers
         
Once again, WPF proves to be extremely flexible when you want to
          customize the look of your tabs. Obviously the content can be rendered any         Data binding
          way you like
it, but so can the tab headers! The Header property can be filled      Introduction
          with anything you like, which we'll take advantage of in the next example:          Hello, bound world!
                                                                                              Using the DataContext
            <Window                                                                           The UpdateSourceTrigger
            x:Class="WpfTutorialSamples.Misc_controls.TabControlWithCust                       property
                                                                                              Responding to changes
                                                                                              Value conversion with
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       IValueConverter
                                                                                              The StringFormat property
                                                                                              Debugging data bindings
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="TabControlWithCustomHeadersSample"
            Height="200" Width="250">                                                        Commands
                  <Grid>
                                                                                              Introduction
                       <Grid>
                                                                                              Using commands
                            <TabControl>
                                                                                              Implementing custom
                                   <TabItem>
                                                                                               commands
                                       <TabItem.Header>
                                             <StackPanel
            Orientation="Horizontal">
                                                                                             Common interface
                                                  <Image
                                                                                             controls
            Source="/WpfTutorialSamples;component/Images/bullet_blue.png
             />                                                                               The Menu control
                                                  <TextBlock Text="Blue"                      The ContextMenu
            Foreground="Blue" />                                                              The ToolBar control
                                             </StackPanel>                                    The StatusBar control
                                       </TabItem.Header>                                      The Ribbon Control
                                       <Label Content="Content goes here..."
            />
                                   </TabItem>                                             Rich Text controls
                                   <TabItem>                                                Introduction
                                       <TabItem.Header>                                     The
                                             <StackPanel                                     FlowDocumentScrollViewer
            Orientation="Horizontal">                                                        control
                                                  <Image                                    The
            Source="/WpfTutorialSamples;component/Images/bullet_red.png"                     FlowDocumentPageViewer
             />                                                                              control
                                                  <TextBlock Text="Red"                     The FlowDocumentReader
            Foreground="Red" />                                                              control
                                             </StackPanel>                                  Creating a FlowDocument
                                       </TabItem.Header>                                     from Code-behind
                                   </TabItem>                                               Advanced FlowDocument
                                   <TabItem>                                                 content
                                       <TabItem.Header>                                     The RichTextBox control
                                             <StackPanel
            Orientation="Horizontal">
                                                  <Image
                                                                                          Misc. controls
            Source="/WpfTutorialSamples;component/Images/bullet_green.pn
             />                                                                             The Border control
                                                  <TextBlock Text="Green"                   The Slider control
            Foreground="Green" />                                                           The ProgressBar control
                                             </StackPanel>                                  The WebBrowser control
                                       </TabItem.Header>                                    The WindowsFormsHost
                                   </TabItem>                                               control
                            </TabControl>
                       </Grid>
                  </Grid>                                                                 The TabControl
            </Window>                                                                       Using the TabControl
                                                                                            Tab positions
                                                                                            Styling the TabItems
                                                                                          List controls
                                                                                            The ItemsControl
                                                                                            The ListBox control
                                                                                            The ComboBox control
         
Controlling the TabControl                                                     How-to: ListView with
         
Sometimes you may wish to control which tab is selected programmatically        column sorting
          or perhaps get some information about the selected tab. The WPF                ListView filtering
          TabControl has
several properties which makes this possible, including
          SelectedIndex and SelectedItem. In the next example, I've added a couple of
          buttons to the first
example which allows us to control the TabControl:       The TreeView control
                                                                                         Introduction
            <Window                                                                      A simple TreeView
            x:Class="WpfTutorialSamples.Misc_controls.ControllingTheTabC                 TreeView, data binding and
                                                                                          multiple templates
                                                                                         Handling
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                  Selection/Expansion state
                                                                                         Lazy loading TreeView items
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ControllingTheTabControlSample"                           The DataGrid control
            Height="300" Width="350">
                                                                                         Introduction
                 <DockPanel>
                                                                                         Custom columns
                       <StackPanel Orientation="Horizontal"
                                                                                         Details row
            DockPanel.Dock="Bottom" Margin="2,5">
                            <Button Name="btnPreviousTab"
            Click="btnPreviousTab_Click">Prev.</Button>
                            <Button Name="btnNextTab"
                                                                                        Styles
            Click="btnNextTab_Click">Next</Button>                                       Introduction
                            <Button Name="btnSelectedTab"                                Using styles
            Click="btnSelectedTab_Click">Selected</Button>                               Triggers
                       </StackPanel>                                                     Multi triggers
                       <TabControl Name="tcSample">                                      Trigger animations
                            <TabItem Header="General">
                                   <Label Content="Content goes here..." />
                            </TabItem>                                                  Misc.
                            <TabItem Header="Security" />
                                                                                         The DispatcherTimer
                            <TabItem Header="Details" />
                       </TabControl>
            namespace WpfTutorialSamples.Misc_controls
            {
            	          public partial class
            ControllingTheTabControlSample : Window
            	{
            		public ControllingTheTabControlSample()
            		{
            			InitializeComponent();
            		}
         
As you can see, I've simply added a set of buttons in the lower part of the
          interface. The first two allows will select the previous or next tab on the
          control, while the last one will display information about the currently selected
          tab, as demonstrated on the screenshot.
         
The first two buttons uses the SelectedIndex property to determine where
          we are and then either subtracts or adds one to that value,
making sure that
          the new index doesn't fall below or above the amount of available items. The
          third button uses the SelectedItem property
to get a reference to the
          selected tab. As you can see, I have to typecast it into the TabItem class to
          get a hold of the header property, since the
SelectedProperty is of the object
          type by default.
         
Summary
         
The TabControl is great when you need a clear separation in a dialog or
          when there's simply not enough space for all the controls you want in it. In
          the next couple of chapters, we'll look into some of the possibilites there are
          when using the TabControl for various purposes.
Previous Next
                                                                  
         
Download
                                                       PDF!
                                                              
Back to Top
Home Contact Us
                                                                                            Download as PDF
        WPF TabControl: Tab positions
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
The tabs of a TabControl is usually placed on top of the control, which is also   About WPF
          how it will look by default when using the WPF TabControl:
                                                                                             What is WPF?
                                                                                             WPF vs. WinForms
                                                                                            Getting started
                                                                                             Visual Studio Express
                                                                                             Hello, WPF!
                                                                                            XAML
                                                                                             What is XAML?
                                                                                             Basic XAML
         
However, using the TabStripPlacement property, we can very easily change           Events in XAML
          this:
                                                                                            Panels
                                                                                             Introduction to WPF Panels
                                                                                             The Canvas
                                                                                             The WrapPanel
                                                                                             The StackPanel
                                                                                             The DockPanel
                                                                                             The Grid
                                                                                             The Grid - Rows & Columns
                                                                                             The Grid - Units
                                                                                             The Grid - Spanning
                                                                                             The Grid - GridSplitter
                                                                                             Using the Grid: A contact
         
The TabStripPlacement can be set to Top, Bottom, Left and Right. However,           form
          if we set it to Left or Right, we get a result like this:
                                                                                            Data binding
                                                                                             Introduction
                                                                                             Hello, bound world!
                                                                                             Using the DataContext
                                                                                             The UpdateSourceTrigger
                                                                                              property
                                                                                             Responding to changes
                                                                                             Value conversion with
                                                                                              IValueConverter
                                                                                             The StringFormat property
                                                                                             Debugging data bindings
         
I personally would expect that the tabs to be rotated when placed on one of
          the sides, so that the tab text becomes vertical instead of horizontal, but the
          WPF TabControl doesn't do this. Fortunately, we can accomplish this               Commands
          behavior with a small hack:
                                                                                             Introduction
                                                                                             Using commands
            <Window
                                                                                             Implementing custom
            x:Class="WpfTutorialSamples.Misc_controls.TabStripPlacementS
                                                                                              commands
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            Common interface
                                                                                            controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           The Menu control
                       Title="TabStripPlacementSample" Height="200"                          The ContextMenu
            Width="250" UseLayoutRounding="True">                                            The ToolBar control
                  <Grid>                                                                     The StatusBar control
                       <TabControl TabStripPlacement="Left">                                 The Ribbon Control
                             <TabControl.Resources>
                                   <Style TargetType="{x:Type TabItem}">
                                        <Setter Property="HeaderTemplate">                  Rich Text controls
                                              <Setter.Value>                                 Introduction
                                                   <DataTemplate>                            The
                                                            <ContentPresenter                 FlowDocumentScrollViewer
            Content="{TemplateBinding Content}">                                              control
                                                                                             The
            <ContentPresenter.LayoutTransform>                                                FlowDocumentPageViewer
                                                                    <RotateTransform          control
            Angle="270" />                                                                   The FlowDocumentReader
                                                                                              control
            </ContentPresenter.LayoutTransform>                                              Creating a FlowDocument
                                                            </ContentPresenter>               from Code-behind
                                                   </DataTemplate>                           Advanced FlowDocument
                                              </Setter.Value>                                 content
                                        </Setter>                                            The RichTextBox control
                                        <Setter Property="Padding" Value="3"
            />
                                   </Style>
                                                                                           Misc. controls
                             </TabControl.Resources>
                                                                                             The Border control
                             <TabItem Header="General">
                                                                                             The Slider control
                                   <Label Content="Content goes here..." />
                                                                                             The ProgressBar control
                             </TabItem>
                                                                                             The WebBrowser control
                             <TabItem Header="Security" />
                                                                                             The WindowsFormsHost
                             <TabItem Header="Details" />
                                                                                             control
                       </TabControl>
                  </Grid>
            </Window>
                                                                                           The TabControl
                                                                                             Using the TabControl
                                                                                             Tab positions
                                                                                             Styling the TabItems
                                                                                           List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
                                                                                             The ComboBox control
                                                                                             Styles
                                                                                              Introduction
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
                                                                                              Trigger animations
                                                                                             Misc.
                                                                                              The DispatcherTimer
                                                                  
         
Download
                                                                   PDF!
                                                            
Back to Top
Home Contact Us
                                                                                          Download as PDF
        WPF TabControl: Styling the TabItems
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
In one of the previous articles, we discovered how easy it was to customize     About WPF
          the tab headers of the WPF TabControl, for instance to add an image or color
                                                                                           What is WPF?
         
the text. However, if you wish to go beyond that and directly influence how
                                                                                           WPF vs. WinForms
          the tab looks, including shape and borders, you need to override the control
          template of the TabItem element, and while this is not as straight forward as
          most other areas of WPF, it's still manageable.
                                                                                          Getting started
         
So, if you would like to get full control of how the tabs of your TabControl     Visual Studio Express
          looks, check out the next example:                                               Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Misc_controls.StyledTabItemsSamp                  XAML
                                                                                           What is XAML?
                                                                                           Basic XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                          A WPF application
                       Title="StyledTabItemsSample" Height="150"
            Width="250">                                                                   Introduction
                  <Grid>                                                                   The Window
                       <TabControl Margin="10" BorderThickness="0"                         Working with App.xaml
            Background="LightGray">                                                        Command-line parameters
                             <TabControl.Resources>                                        Resources
                                   <Style TargetType="TabItem">                            Handling exceptions
                                        <Setter Property="Template">
                                              <Setter.Value>
                                                   <ControlTemplate                       Basic controls
            TargetType="TabItem">                                                          The TextBlock control
                                                         <Grid Name="Panel">               The TextBlock control - Inline
                                                              <ContentPresenter            formatting
            x:Name="ContentSite"                                                           The Label control
                                                                                           The TextBox control
            VerticalAlignment="Center"                                                     The CheckBox control
            ContentSource="Header"
                                                                   Margin="10,2"/>
                                                                                         Panels
                                                         </Grid>
                                                         <ControlTemplate.Triggers>       Introduction to WPF Panels
                                                              <Trigger                    The Canvas
            Property="IsSelected" Value="True">                                           The WrapPanel
                                                                   <Setter                The StackPanel
            TargetName="Panel" Property="Background"                                      The DockPanel
            Value="LightSkyBlue" />                                                       The Grid
                                                              </Trigger>                  The Grid - Rows & Columns
                                                              <Trigger                    The Grid - Units
            Property="IsSelected" Value="False">                                          The Grid - Spanning
                                                                   <Setter                The Grid - GridSplitter
            TargetName="Panel" Property="Background" Value="White" />                     Using the Grid: A contact
                                                              </Trigger>                   form
            </ControlTemplate.Triggers>
                                                   </ControlTemplate>                    Data binding
                                              </Setter.Value>                             Introduction
                                        </Setter>                                         Hello, bound world!
                                   </Style>                                               Using the DataContext
                             </TabControl.Resources>                                      The UpdateSourceTrigger
                             <TabItem Header="General">                                    property
                                   <Label Content="Content goes here..." />               Responding to changes
                             </TabItem>                                                   Value conversion with
                             <TabItem Header="Security" />                                 IValueConverter
                             <TabItem Header="Details" />                                 The StringFormat property
                       </TabControl>                                                      Debugging data bindings
                  </Grid>
            </Window>
                                                                                         Commands
                                                                                          Introduction
                                                                                          Using commands
                                                                                          Implementing custom
                                                                                           commands
                                                                                         Common interface
                                                                                         controls
                                                                                          The Menu control
         
As you can see, this makes the TabControl looks a bit Windows 8'ish, with no    The ContextMenu
          borders and a less subtle color to mark the selected tab and no background      The ToolBar control
          for
the unselected tabs. All of this is accomplished by changing the            The StatusBar control
          ControlTemplate, using a Style. By adding a ContentPresenter control, we        The Ribbon Control
         
specify where the content of the TabItem should be placed. We also have a
          couple of triggers, which controls the background color of the tabs based on
          the IsSelected property.                                                       Rich Text controls
         
In case you want a less subtle look, it's as easy as changing the template.      Introduction
          For instance, you might want a border, but with round corners and a gradient     The
          background - no problem! Check out this next example, where we                    FlowDocumentScrollViewer
          accomplish just that:                                                             control
                                                                                           The
                                                                                            FlowDocumentPageViewer
            <Window
                                                                                            control
            x:Class="WpfTutorialSamples.Misc_controls.StyledTabItemsWith
                                                                                           The FlowDocumentReader
                                                                                            control
                                                                                           Creating a FlowDocument
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            from Code-behind
                                                                                           Advanced FlowDocument
                                                                                            content
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                           The RichTextBox control
                       Title="StyledTabItemsWithBorderSample"
            Height="150" Width="250">
                  <Grid>
                       <TabControl Margin="10" BorderBrush="Gainsboro">
                                                                                         Misc. controls
                             <TabControl.Resources>                                        The Border control
                                   <Style TargetType="TabItem">                            The Slider control
                                        <Setter Property="Template">                       The ProgressBar control
                                              <Setter.Value>                               The WebBrowser control
                                                   <ControlTemplate                        The WindowsFormsHost
            TargetType="TabItem">                                                          control
                                                         <Border Name="Border"
            BorderThickness="1,1,1,0" BorderBrush="Gainsboro"
            CornerRadius="4,4,0,0" Margin="2,0">                                         The TabControl
                                                              <ContentPresenter
                                                                                           Using the TabControl
            x:Name="ContentSite"
                                                                                           Tab positions
                                                                                           Styling the TabItems
            VerticalAlignment="Center"
            HorizontalAlignment="Center"
                                                                                         List controls
            ContentSource="Header"                                                         The ItemsControl
                                                                   Margin="10,2"/>         The ListBox control
                                                         </Border>                         The ComboBox control
                                                         <ControlTemplate.Triggers>
                                                              <Trigger
            Property="IsSelected" Value="True">                                          The ListView control
                                                                   <Setter                 Introduction
            TargetName="Border" Property="Background"                                      A simple ListView
            Value="LightSkyBlue" />                                                        ListView, data binding and
                                                              </Trigger>                    ItemTemplate
                                                              <Trigger                     ListView with a GridView
            Property="IsSelected" Value="False">                                           How-to: Left aligned column
                                                                   <Setter                  names
            TargetName="Border" Property="Background"                                      ListView grouping
            Value="GhostWhite" />                                                          ListView sorting
                                                              </Trigger>                   How-to: ListView with
                                                                                            column sorting
                                                                                                    Styles
                                                                                                     Introduction
                                                                                                     Using styles
                                                                                                     Triggers
                                                                                                     Multi triggers
         
As you can see, I pretty much just added a Border control around the
                                                                                                     Trigger animations
          ContentPresenter to achieve this changed look. Hopefully this should
          demonstrate just
how easy it is to get custom styled tabs and how many
          possibilities there are in this technique.
                                                                                                    Misc.
                Previous                                                               Next          The DispatcherTimer
                                                                         
         
Download
                                                                          PDF!
                                                                   
Back to Top
Home Contact Us
                                                                                           Download as PDF
        The ItemsControl
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
          
WPF has a wide range of controls for displaying a list of data. They come in    About WPF
           several shapes and forms and vary in how complex they are and how much
                                                                                            What is WPF?
           work
they perform for you. The simplest variant is the ItemsControl, which is
                                                                                            WPF vs. WinForms
           pretty much just a markup-based loop - you need to apply all the styling and
           templating, but in many cases, that's just what you need.
          
A simple ItemsControl example                                                   Getting started
                                                                                            Visual Studio Express
          
Let's kick off with a very simple example, where we hand-feed the
                                                                                            Hello, WPF!
           ItemsControl with a set of items. This should show you just how simple the
           ItemsControl
is:
                                                                                           XAML
            <Window
                                                                                            What is XAML?
            x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
                                                                                            Basic XAML
                                                                                            Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          Introduction
            		xmlns:system="clr-                                                            The Window
            namespace:System;assembly=mscorlib"                                             Working with App.xaml
                        Title="ItemsControlSample" Height="150"                             Command-line parameters
            Width="200">                                                                    Resources
                  <Grid Margin="10">                                                        Handling exceptions
            		<ItemsControl>
            			<system:String>ItemsControl Item
            #1</system:String>                                                             Basic controls
            			<system:String>ItemsControl Item
                                                                                            The TextBlock control
            #2</system:String>
                                                                                            The TextBlock control - Inline
            			<system:String>ItemsControl Item
                                                                                            formatting
            #3</system:String>
                                                                                            The Label control
            			<system:String>ItemsControl Item
                                                                                            The TextBox control
            #4</system:String>
                                                                                            The CheckBox control
            			<system:String>ItemsControl Item
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Common interface
                                                                                              controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ItemsControlDataBindingSample" Height="150"                     The Menu control
              Width="300">                                                                     The ContextMenu
                  <Grid Margin="10">                                                           The ToolBar control
            		<ItemsControl Name="icTodoList">                                                 The StatusBar control
            			<ItemsControl.ItemTemplate>                                                     The Ribbon Control
            				<DataTemplate>
            					<Grid
            Margin="0,0,0,5">                                                                 Rich Text controls
            						                                                                    Introduction
            <Grid.ColumnDefinitions>                                                  The
            							                                                                    FlowDocumentScrollViewer
            <ColumnDefinition Width="*" />                                             control
            							                                                                   The
            <ColumnDefinition Width="100" />                                           FlowDocumentPageViewer
            						                                                                     control
            </Grid.ColumnDefinitions>                                                 The FlowDocumentReader
            						<TextBlock                                                           control
              Text="{Binding Title}" />                                               Creating a FlowDocument
            						                                                                     from Code-behind
            <ProgressBar Grid.Column="1" Minimum="0" Maximum="100"                    Advanced FlowDocument
            Value="{Binding Completion}" />                                            content
            					</Grid>                                                              The RichTextBox control
            				</DataTemplate>
            			</ItemsControl.ItemTemplate>
            		</ItemsControl>                                                       Misc. controls
            	</Grid>
                                                                                      The Border control
            </Window>
                                                                                      The Slider control
                                                                                      The ProgressBar control
                                                                                      The WebBrowser control
            using System;                                                             The WindowsFormsHost
            using System.Windows;                                                     control
            using System.Collections.Generic;
          
The most important part of this example is the template that we specify inside
           of the ItemsControl, using a DataTemplate tag inside of the                       The DataGrid control
           ItemsControl.ItemTemplate. We add a Grid panel, to get two columns: In the         Introduction
           first we have a TextBlock, which will show the title of the TODO item, and in      Custom columns
           the second column we have a ProgressBar control, which value we bind to            Details row
           the Completion property.
          
The template now represents a TodoItem, which we declare in the Code-
                                                                                             Styles
          behind file, where we also instantiate a number of them and add them to a
                                                                                              Introduction
           list. In the
end, this list is assigned to the ItemsSource property of our
                                                                                              Using styles
           ItemsControl, which then does the rest of the job for us. Each item in the
list
                                                                                              Triggers
           is displayed by using our template, as you can see from the resulting
                                                                                              Multi triggers
           screenshot.
                                                                                              Trigger animations
          
The ItemsPanelTemplate property
          
In the above examples, all items are rendered from top to bottom, with each       Misc.
           item taking up the full row. This happens because the ItemsControl throw all
                                                                                              The DispatcherTimer
           of
our items into a vertically aligned StackPanel by default. It's very easy to
           change though, since the ItemsControl allows you to change which panel
           type is
used to hold all the items. Here's an example:
                                                                                             Audio & Video
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            		xmlns:system="clr-
            namespace:System;assembly=mscorlib"
                        Title="ItemsControlPanelSample" Height="150"
            Width="250">
            	           <Grid Margin="10">
            		<ItemsControl>
            			<ItemsControl.ItemsPanel>
            				<ItemsPanelTemplate>
            					<WrapPanel />
            				</ItemsPanelTemplate>
            			</ItemsControl.ItemsPanel>
            			<ItemsControl.ItemTemplate>
            				<DataTemplate>
            					<Button Content="
            {Binding}" Margin="0,0,5,5" />
            				</DataTemplate>
            			</ItemsControl.ItemTemplate>
            			<system:String>Item
            #1</system:String>
            			<system:String>Item
            #2</system:String>
            			<system:String>Item
            #3</system:String>
            			<system:String>Item
            #4</system:String>
            			<system:String>Item
            #5</system:String>
            		</ItemsControl>
            	</Grid>
            </Window>
          
We specify that the ItemsControl should use a WrapPanel as its template by
           declaring one in the ItemsPanelTemplate property and just for
fun, we throw
           in an ItemTemplate that causes the strings to be rendered as buttons. You
           can use any of the WPF panels, but some are more useful than
others.
          
Another good example is the UniformGrid panel, where we can define a
           number of columns and then have our items neatly shown in equally-wide
           columns:
            <Window
            x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSa
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            		xmlns:system="clr-
            namespace:System;assembly=mscorlib"
                        Title="ItemsControlPanelSample" Height="150"
            Width="250">
            	           <Grid Margin="10">
            		<ItemsControl>
            			<ItemsControl.ItemsPanel>
            				<ItemsPanelTemplate>
            					<UniformGrid
            Columns="2" />
            				</ItemsPanelTemplate>
            			</ItemsControl.ItemsPanel>
            			<ItemsControl.ItemTemplate>
            				<DataTemplate>
            					<Button Content="
            {Binding}" Margin="0,0,5,5" />
            				</DataTemplate>
            			</ItemsControl.ItemTemplate>
            			<system:String>Item
            #1</system:String>
            			<system:String>Item
            #2</system:String>
            			<system:String>Item
            #3</system:String>
            			<system:String>Item
            #4</system:String>
            			<system:String>Item
            #5</system:String>
            		</ItemsControl>
            	</Grid>
            </Window>
          
ItemsControl with scrollbars
          
Once you start using the ItemsControl, you might run into a very common
           problem: By default, the ItemsControl doesn't have any scrollbars, which
           means that
if the content doesn't fit, it's just clipped. This can be seen by
           taking our first example from this article and resizing the window:
          
WPF makes this very easy to solve though. There are a number of possible
           solutions, for instance you can alter the template used by the ItemsControl to
           include a ScrollViewer control, but the easiest solution is to simply throw a
           ScrollViewer around the ItemsControl. Here's an example:
            <Window
            x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            		xmlns:system="clr-
            namespace:System;assembly=mscorlib"
                        Title="ItemsControlSample" Height="150"
            Width="200">
            	           <Grid Margin="10">
            		<ScrollViewer
            VerticalScrollBarVisibility="Auto"
            HorizontalScrollBarVisibility="Auto">
            			<ItemsControl>
            				
            <system:String>ItemsControl Item #1</system:String>
            				
            <system:String>ItemsControl Item #2</system:String>
            				
            <system:String>ItemsControl Item #3</system:String>
            				
            <system:String>ItemsControl Item #4</system:String>
            				
            <system:String>ItemsControl Item #5</system:String>
            			</ItemsControl>
            		</ScrollViewer>
            	</Grid>
            </Window>
          
I set the two visibility options to Auto, to make them only visible when
           needed. As you can see from the screenshot, you can now scroll through the
           list of
items.
          
Summary
          
The ItemsControl is great when you want full control of how your data is
           displayed, and when you don't need any of your content to be selectable. If
           you
want the user to be able to select items from the list, then you're better
           off with one of the other controls, e.g. the ListBox or the ListView. They will
           be described in upcoming chapters.
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                              
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The ListBox control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
In the last article, we had a look at the ItemsControl, which is probably the     About WPF
           simplest list in WPF. The ListBox control is the next control in line, which
                                                                                              What is WPF?
           adds a bit more functionality. One of the main differences is the fact that the
                                                                                              WPF vs. WinForms
           ListBox control actually deals with selections, allowing the end-user to
select
           one or several items from the list and automatically giving visual feedback for
           it.
                                                                                             Getting started
          
Here's an example of a very simple ListBox control:                                Visual Studio Express
                                                                                              Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.ListBox_control.ListBoxSample"
                                                                                             XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              What is XAML?
                                                                                              Basic XAML
                                                                                              Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ListBoxSample" Height="120" Width="200">
                  <Grid Margin="10">
                                                                                             A WPF application
            		<ListBox>
            			<ListBoxItem>ListBox Item                                                      Introduction
            #1</ListBoxItem>                                                                  The Window
            			<ListBoxItem>ListBox Item                                                      Working with App.xaml
            #2</ListBoxItem>                                                                  Command-line parameters
            			<ListBoxItem>ListBox Item                                                      Resources
            #3</ListBoxItem>                                                                  Handling exceptions
            		</ListBox>
            	</Grid>
            </Window>                                                                        Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          
This is as simple as it gets: We declare a ListBox control, and inside of it, we
           declare three ListBoxItem's, each with its own text. However, since the            Panels
           ListBoxItem is actually a ContentControl, we can define custom content for it:
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
            <Window                                                                            The WrapPanel
            x:Class="WpfTutorialSamples.ListBox_control.ListBoxSample"                         The StackPanel
                                                                                               The DockPanel
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       The Grid
                                                                                               The Grid - Rows & Columns
                                                                                               The Grid - Units
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             The Grid - Spanning
                        Title="ListBoxSample" Height="120" Width="200">                        The Grid - GridSplitter
            	           <Grid Margin="10">                                                     Using the Grid: A contact
            		<ListBox>                                                                         form
            			<ListBoxItem>
            				<StackPanel
            Orientation="Horizontal">
                                                                                              Data binding
            					<Image
                                                                                               Introduction
            Source="/WpfTutorialSamples;component/Images/bullet_blue.png
                                                                                               Hello, bound world!
              />
                                                                                               Using the DataContext
            					<TextBlock>ListBox
                                                                                               The UpdateSourceTrigger
              Item #1</TextBlock>
                                                                                                property
            				</StackPanel>
                                                                                               Responding to changes
            			</ListBoxItem>
                                                                                               Value conversion with
            			<ListBoxItem>
                                                                                                IValueConverter
            				<StackPanel
                                                                                               The StringFormat property
            Orientation="Horizontal">
                                                                                               Debugging data bindings
            					<Image
            Source="/WpfTutorialSamples;component/Images/bullet_green.pn
              />
            					<TextBlock>ListBox                                                           Commands
              Item #2</TextBlock>                                                              Introduction
            				</StackPanel>                                                                  Using commands
            			</ListBoxItem>                                                                  Implementing custom
            			<ListBoxItem>                                                                    commands
            				<StackPanel
            Orientation="Horizontal">
            					<Image                                                                       Common interface
            Source="/WpfTutorialSamples;component/Images/bullet_red.png"                      controls
              />
                                                                                               The Menu control
            					<TextBlock>ListBox
                                                                                               The ContextMenu
              Item #3</TextBlock>
                                                                                               The ToolBar control
            				</StackPanel>
                                                                                               The StatusBar control
            			</ListBoxItem>
          
I have re-used the TODO based example from the ItemsControl article,                 The TabControl
           where we build a cool TODO list using a simple Code-behind class and, in               Using the TabControl
           this case, a
ListBox control for the visual representation. Here's the example:        Tab positions
                                                                                                  Styling the TabItems
            <Window
            x:Class="WpfTutorialSamples.ListBox_control.ListBoxDataBindi
                                                                                                List controls
                                                                                                  The ItemsControl
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                  The ListBox control
                                                                                                  The ComboBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ListBoxDataBindingSample" Height="150"
                                                                                                The ListView control
            Width="300">
                  <Grid Margin="10">                                                              Introduction
            		<ListBox Name="lbTodoList"                                                          A simple ListView
            HorizontalContentAlignment="Stretch">                                                 ListView, data binding and
            			<ListBox.ItemTemplate>                                                              ItemTemplate
            				<DataTemplate>                                                                    ListView with a GridView
            					<Grid                                                                            How-to: Left aligned column
            Margin="0,2">                                                                          names
            						                                                                      ListView grouping
            <Grid.ColumnDefinitions>                                                    ListView sorting
            							                                                                     How-to: ListView with
            <ColumnDefinition Width="*" />                                               column sorting
            							                                                                     ListView filtering
            <ColumnDefinition Width="100" />
            						
            </Grid.ColumnDefinitions>                                                  The TreeView control
            						<TextBlock                                                            Introduction
              Text="{Binding Title}" />                                                 A simple TreeView
            						                                                                      TreeView, data binding and
            <ProgressBar Grid.Column="1" Minimum="0" Maximum="100"                       multiple templates
            Value="{Binding Completion}" />                                             Handling
            					</Grid>                                                                 Selection/Expansion state
            				</DataTemplate>                                                         Lazy loading TreeView items
            			</ListBox.ItemTemplate>
            		</ListBox>
            	</Grid>
                                                                                       The DataGrid control
            </Window>
                                                                                        Introduction
                                                                                        Custom columns
                                                                                        Details row
            using System;
            using System.Windows;
            using System.Collections.Generic;                                          Styles
                                                                                        Introduction
            namespace WpfTutorialSamples.ListBox_control
                                                                                        Using styles
            {
                                                                                        Triggers
            	           public partial class ListBoxDataBindingSample :
                                                                                        Multi triggers
            Window
                                                                                        Trigger animations
            	{
            		public ListBoxDataBindingSample()
            		{
            			InitializeComponent();
                                                                                       Misc.
            			                                   List<TodoItem> items = new            The DispatcherTimer
            List<TodoItem>();
            			                                   items.Add(new TodoItem() { Title =
                "Complete this WPF tutorial", Completion = 45 });                      Audio & Video
            			                                   items.Add(new TodoItem() { Title =
                                                                                        Playing audio
                "Learn C#", Completion = 80 });
                                                                                        Playing video
            			                                   items.Add(new TodoItem() { Title =
                                                                                        How-to: Complete media
                "Wash the car", Completion = 0 });
                                                                                        player
                                                                                        Speech synthesis
            			lbTodoList.ItemsSource = items;
                                                                                        Speech recognition
            		}
            	}
            	}
            }
          
All the magic happens in the ItemTemplate that we have defined for the
           ListBox. In there, we specify that each ListBox item should consist of a Grid,
           divided into two columns, with a TextBlock showing the title in the first and a
           ProgressBar showing the completion status in the second column. To get the
          
values out, we use some very simple data binding, which is all explained in
           the data binding part of this tutorial.
          
In the Code-behind file, we have declared a very simple TodoItem class to
           hold each of our TODO items. In the constructor of the window, we initialize a
          
list, add three TODO items to it and then assign it to the ItemsSource of the
           ListBox. The combination of the ItemsSource and the ItemTemplate we
           specified
in the XAML part, this is all WPF need to render all of the items as a
           TODO list.
          
Please notice the HorizontalContentAlignment property that I set to
           Stretch on the ListBox. The default content alignment
for a ListBox item is
           Left, which means that each item only takes up as much horizontal space as
           it needs. The result? Well, not quite
what we want:
          
By using the Stretch alignment, each item is stretched to take up the full
           amount of available space, as you can see from the previous screenshot.
          
Working with ListBox selection
          
As mentioned, a key difference between the ItemsControl and the ListBox is
           that the ListBox handles and displays user selection for you. Therefore, a lot
           of ListBox question revolves around somehow working with the selection. To
           help with some of these questions, I have created a bigger example, showing
           you
some selection related tricks:
<Window
x:Class="WpfTutorialSamples.ListBox_control.ListBoxSelection
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="ListBoxSelectionSample" Height="250"
            Width="450">
            	           <DockPanel Margin="10">
            		<StackPanel DockPanel.Dock="Right"
            Margin="10,0">
            			<StackPanel.Resources>
            				<Style
            TargetType="Button">
            					<Setter
            Property="Margin" Value="0,0,0,5" />
            				</Style>
            			</StackPanel.Resources>
            			<TextBlock FontWeight="Bold"
            Margin="0,0,0,10">ListBox selection</TextBlock>
            			<Button Name="btnShowSelectedItem"
              Click="btnShowSelectedItem_Click">Show selected</Button>
            			<Button Name="btnSelectLast"
            Click="btnSelectLast_Click">Select last</Button>
            			<Button Name="btnSelectNext"
            Click="btnSelectNext_Click">Select next</Button>
            			<Button Name="btnSelectCSharp"
            Click="btnSelectCSharp_Click">Select C#</Button>
            			<Button Name="btnSelectAll"
            Click="btnSelectAll_Click">Select all</Button>
            		</StackPanel>
            		<ListBox Name="lbTodoList"
            HorizontalContentAlignment="Stretch"
            SelectionMode="Extended"
            SelectionChanged="lbTodoList_SelectionChanged">
            			<ListBox.ItemTemplate>
            				<DataTemplate>
            					<Grid
            Margin="0,2">
            						
            <Grid.ColumnDefinitions>
            							
            <ColumnDefinition Width="*" />
            							
            <ColumnDefinition Width="100" />
            						
            </Grid.ColumnDefinitions>
            						<TextBlock
                Text="{Binding Title}" />
            						
            using System;
            using System.Windows;
            using System.Collections.Generic;
            namespace WpfTutorialSamples.ListBox_control
            {
            	           public partial class ListBoxSelectionSample :
            Window
            	{
            		public ListBoxSelectionSample()
            		{
            			InitializeComponent();
            			                                   List<TodoItem> items = new
            List<TodoItem>();
            			                                   items.Add(new TodoItem() { Title =
                "Complete this WPF tutorial", Completion = 45 });
            			                                   items.Add(new TodoItem() { Title =
                "Learn C#", Completion = 80 });
            			                                   items.Add(new TodoItem() { Title =
                "Wash the car", Completion = 0 });
            			lbTodoList.ItemsSource = items;
            		}
            		private void
            lbTodoList_SelectionChanged(object sender,
            System.Windows.Controls.SelectionChangedEventArgs e)
            		{
            			if(lbTodoList.SelectedItem !=
            null)
            				this.Title =
            (lbTodoList.SelectedItem as TodoItem).Title;
            		}
            		private void
            btnShowSelectedItem_Click(object sender, RoutedEventArgs
            e)
            		{
            			foreach(object o in
            lbTodoList.SelectedItems)
            				MessageBox.Show((o as
            TodoItem).Title);
            		}
          
As you can see, I have defined a range of buttons to the right of the ListBox,
           to either get or manipulate the selection. I've also changed the
           SelectionMode to Extended, to allow for the selection of multiple items. This
           can be done either programmatically, as I
do in the example, or by the end-
          user, by holding down [Ctrl] or [Shift] while clicking on the items.
          
For each of the buttons, I have defined a click handler in the Code-behind.
           Each action should be pretty self-explanatory and the C# code used is fairly
           simple, but if you're still in doubt, try running the example on your own
           machine and test out the various possibilities in the example.
          
Summary
          
The ListBox control is much like the ItemsControl and several of the same
           techniques can be used. The ListBox does offer a bit more functionality when
          
compared to the ItemsControl, especially the selection handling. For even
           more functionality, like column headers, you should have a look at the
           ListView
control, which is given a very thorough description later on in this
           tutorial with several articles explaining all the functionality.
Previous Next
                                                  
   
Download
                                                   PDF!
                                                                  
Back to Top
Home Contact Us
                                                                                        Download as PDF
       The ComboBox control
                                                                                               Download this entire
                                                                                               tutorial as PDF right
                                                                                        now!
         
The ComboBox control is in many ways like the ListBox control, but takes up   About WPF
          a lot less space, because the list of items is hidden when not needed. The
                                                                                         What is WPF?
          ComboBox control is used many places in Windows, but to make sure that
                                                                                         WPF vs. WinForms
          everyone knows how it looks and works, we'll jump straight into a simple
          example:
                                                                                        Getting started
            <Window
            x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSample"                 Visual Studio Express
                                                                                         Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                        XAML
                                                                                         What is XAML?
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                       Basic XAML
                       Title="ComboBoxSample" Height="150" Width="200">                  Events in XAML
                 <StackPanel Margin="10">
                       <ComboBox>
                            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
                                                                                        A WPF application
                            <ComboBoxItem IsSelected="True">ComboBox Item
                                                                                         Introduction
            #2</ComboBoxItem>
                                                                                         The Window
                            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
                                                                                         Working with App.xaml
                       </ComboBox>
                                                                                         Command-line parameters
                 </StackPanel>
                                                                                         Resources
            </Window>
                                                                                         Handling exceptions
                                                                                        Basic controls
                                                                                         The TextBlock control
                                                                                         The TextBlock control - Inline
                                                                                         formatting
                                                                                         The Label control
                                                                                         The TextBox control
                                                                                         The CheckBox control
         
In the screenshot, I have activated the control by clicking it, causing the list of    The RadioButton control
          items to be displayed. As you can see from the code, the ComboBox, in
its              The PasswordBox control
          simple form, is very easy to use. All I've done here is manually add some
          items, making one of them the default selected item by setting the IsSelected
         
property on it.                                                                       Panels
         
Custom content                                                                         Introduction to WPF Panels
                                                                                                 The Canvas
         
In the first example we only showed text in the items, which is pretty common          The WrapPanel
          for the ComboBox control, but since the ComboBoxItem is a ContentControl,              The StackPanel
          we
can actually use pretty much anything as content. Let's try making a                The DockPanel
          slightly more sophisticated list of items:                                             The Grid
                                                                                                 The Grid - Rows & Columns
            <Window                                                                              The Grid - Units
            x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxCustomC                         The Grid - Spanning
                                                                                                 The Grid - GridSplitter
                                                                                                 Using the Grid: A contact
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                          form
                            </ComboBoxItem>
                                                                                             Introduction
                       </ComboBox>
                                                                                             The
                 </StackPanel>
                                                                                              FlowDocumentScrollViewer
            </Window>
                                                                                              control
                                                                                             The
                                                                                              FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
                                                                                              from Code-behind
                                                                                             Advanced FlowDocument
                                                                                              content
                                                                                             The RichTextBox control
         
For each of the ComboBoxItem's we now add a StackPanel, in which we add
          an Image and a TextBlock. This gives us full control of the content as well as
          the
text rendering, as you can see from the screenshot, where both text color    Misc. controls
          and image indicates a color value.                                                 The Border control
                                                                                             The Slider control
         
Data binding the ComboBox                                                          The ProgressBar control
                                                                                             The WebBrowser control
         
As you can see from the first examples, manually defining the items of a
                                                                                             The WindowsFormsHost
          ComboBox control is easy using XAML, but you will likely soon run into a
                                                                                             control
          situation
where you need the items to come from some kind of data source,
          like a database or just an in-memory list. Using WPF data binding and a
          custom template, we
can easily render a list of colors, including a preview of
                                                                                           The TabControl
          the color:
                                                                                             Using the TabControl
                                                                                             Tab positions
            <Window
                                                                                             Styling the TabItems
            x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxDataBin
                       </ComboBox>
                                                                                                 ListView filtering
                 </StackPanel>
            </Window>
                                                                                                Misc.
                                                                                                 The DispatcherTimer
         
Each item, as defined by the ItemTemplate, consists of a StackPanel with a
          Rectangle and a TextBlock, each bound to the color value. This gives us a
          complete list of colors, with minimal effort - and it looks pretty good too, right?
         
IsEditable
         
In the first examples, the user was only able to select from our list of items,
          but one of the cool things about the ComboBox is that it supports the
          possibility of letting the user both select from a list of items or enter their own
          value. This is extremely useful in situations where you want to help
the user
          by giving them a pre-defined set of options, while still giving them the option
          to manually enter the desired value. This is all controlled by the IsEditable
          property, which changes the behavior and look of the ComboBox quite a bit:
            <Window
            x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxEditabl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ComboBoxEditableSample" Height="150"
            Width="200">
                 <StackPanel Margin="10">
                       <ComboBox IsEditable="True">
                            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
                            <ComboBoxItem>ComboBox Item #2</ComboBoxItem>
                            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
                       </ComboBox>
                 </StackPanel>
            </Window>
         
As you can see, I can enter a completely different value or pick one from the
          list. If picked from the list, it simply overwrites the text of the ComboBox.
         
As a lovely little bonus, the ComboBox will automatically try to help the user
          select an existing value when the user starts typing, as you can see from
the
          next screenshot, where I just started typing "Co":
         
By default, the matching is not case-sensitive but you can make it so by
          setting the IsTextSearchCaseSensitive to True. If you don't want
this auto
          complete behavior at all, you can disable it by setting the
IsTextSearchEnabled to False.
         
Working with ComboBox selection
         
A key part of using the ComboBox control is to be able to read the user
          selection, and even control it with code. In the next example, I've re-used the
          data bound ComboBox example, but added some buttons for controlling the
          selection. I've also used the SelectionChanged event to capture
when the
          selected item is changed, either by code or by the user, and act on it.
         
Here's the sample:
            <Window
            x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSelecti
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ComboBoxSelectionSample" Height="125"
            Width="250">
                 <StackPanel Margin="10">
                       <ComboBox Name="cmbColors"
            SelectionChanged="cmbColors_SelectionChanged">
                            <ComboBox.ItemTemplate>
                                   <DataTemplate>
                                       <StackPanel Orientation="Horizontal">
                                            <Rectangle Fill="{Binding Name}"
            Width="16" Height="16" Margin="0,2,5,2" />
                                            <TextBlock Text="{Binding Name}"
            />
                                       </StackPanel>
                                   </DataTemplate>
                            </ComboBox.ItemTemplate>
                       </ComboBox>
                       <WrapPanel Margin="15"
            HorizontalAlignment="Center">
                            <Button Name="btnPrevious"
            Click="btnPrevious_Click" Width="55">Previous</Button>
                            <Button Name="btnNext" Click="btnNext_Click"
            Margin="5,0" Width="55">Next</Button>
                            <Button Name="btnBlue" Click="btnBlue_Click"
            Width="55">Blue</Button>
                       </WrapPanel>
                 </StackPanel>
            </Window>
            using System;
            using System.Collections.Generic;
            using System.Reflection;
            using System.Windows;
            using System.Windows.Media;
            namespace WpfTutorialSamples.ComboBox_control
            {
            	          public partial class ComboBoxSelectionSample :
            Window
            	{
            		public ComboBoxSelectionSample()
            		{
            			InitializeComponent();
            			cmbColors.ItemsSource =
            typeof(Colors).GetProperties();
            		}
            		private void
            cmbColors_SelectionChanged(object sender,
            System.Windows.Controls.SelectionChangedEventArgs e)
            		{
            			                             Color selectedColor = (Color)
            (cmbColors.SelectedItem as PropertyInfo).GetValue(null,
            null);
            			this.Background = new
            SolidColorBrush(selectedColor);
            		}
            	}
         
The interesting part of this example is the three event handlers for our three
          buttons, as well as the SelectionChanged event handler. In
the first two, we
          select the previous or the next item by reading the SelectedIndex property
          and then subtracting or adding one to it.
Pretty simple and easy to work with.
         
In the third event handler, we use the SelectedItem to select a specific item
          based on the value. I do a bit of extra work here (using .NET reflection),
          because the ComboBox is bound to a list of properties, each being a color,
          instead of a simple list of colors, but basically it's all about giving the
value
          contained by one of the items to the SelectedItem property.
         
In the fourth and last event handler, I respond to the selected item being
          changed. When that happens, I read the selected color (once again using
          Reflection, as described above) and then use the selected color to create a
          new background brush for the Window. The effect can be seen on the
          screenshot.
         
If you're working with an editable ComboBox (IsEditable property set to true),
          you can read the Text property to know the value the user
has entered or
          selected.
Previous Next
                                                                   
         
Download
                                                                    PDF!
                                                                                              
Back to Top
Home Contact Us
                                                                                            Download as PDF
        Introduction to the ListView control
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
          The ListView control is very commonly used in Windows applications, to            About WPF
          represent lists of data. A great example of this is the file lists in Windows
                                                                                             What is WPF?
          Explorer, where each file can be shown by its name and, if desired, with
                                                                                             WPF vs. WinForms
          columns containing information about the size, last modification date and so
          on.
                                                                   Panels
                                                                    Introduction to WPF Panels
                                                                    The Canvas
                                                                    The WrapPanel
                                                                    The StackPanel
                                                                    The DockPanel
                                                                    The Grid
                                                                    The Grid - Rows & Columns
                                                                    The Grid - Units
                                                                    The Grid - Spanning
                                                                    The Grid - GridSplitter
                                                                    Using the Grid: A contact
                                                                     form
                                                                   Data binding
                                                                    Introduction
                                                                    Hello, bound world!
                                                                    Using the DataContext
                                                                    The UpdateSourceTrigger
                                                                     property
                                                                    Responding to changes
                                                                    Value conversion with
                                                                     IValueConverter
                                                                    The StringFormat property
                                                                    Debugging data bindings
                                                                   Commands
                                                                    Introduction
                                                                    Using commands
                                                                    Implementing custom
                                                                     commands
                                                                   Common interface
                                                                   controls
                                                                    The Menu control
                                                                    The ContextMenu
                                                                    The ToolBar control
                                                                    The StatusBar control
                                                                    The Ribbon Control
                                                                     Introduction
                                                                     The
                                                                      FlowDocumentScrollViewer
                                                                      control
                                                                     The
                                                                      FlowDocumentPageViewer
                                                                      control
                                                                     The FlowDocumentReader
                                                                      control
                                                                     Creating a FlowDocument
                                                                      from Code-behind
                                                                     Advanced FlowDocument
                                                                      content
                                                                     The RichTextBox control
                                                                   Misc. controls
                                                                     The Border control
                                                                     The Slider control
                                                                     The ProgressBar control
                                                                     The WebBrowser control
                                                                     The WindowsFormsHost
                                                                     control
                                                                   The TabControl
                                                                     Using the TabControl
                                                                     Tab positions
                                                                     Styling the TabItems
                                                                   List controls
                                                                     The ItemsControl
                                                                     The ListBox control
                                                                     The ComboBox control
ListView filtering
                                                                                                    Styles
                                                                                                     Introduction
                                                                                                     Using styles
                                                                                                     Triggers
                                                                                                     Multi triggers
                                                                                                     Trigger animations
                                                                                                    Misc.
                                                                                                     The DispatcherTimer
                                                                         
         
Download
                                                                          PDF!
                                                                   
Back to Top
Home Contact Us
                                                                                              Download as PDF
        A simple ListView example
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
         The WPF ListView control is very bare minimum in its most simple form. In            About WPF
         fact, it will look a whole lot like the WPF ListBox, until you start adding
                                                                                               What is WPF?
         specialized views to it. That's not so strange, since a ListView inherits directly
                                                                                               WPF vs. WinForms
         from the ListBox control. So, a default ListView is actually just a ListBox, with
         a different selection mode (more on that later).
         Let's try creating a ListView in its most simple form:                               Getting started
                                                                                               Visual Studio Express
            <Window                                                                            Hello, WPF!
            x:Class="WpfTutorialSamples.ListView_control.ListViewBasicSa
                                                                                              XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                               What is XAML?
                                                                                               Basic XAML
                                                                                               Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ListViewBasicSample" Height="200"
            Width="200">
                                                                                              A WPF application
                  <Grid>
            		<ListView Margin="10">                                                           Introduction
            			<ListViewItem>A                                                                 The Window
            ListView</ListViewItem>                                                            Working with App.xaml
            			<ListViewItem                                                                   Command-line parameters
            IsSelected="True">with several</ListViewItem>                                      Resources
            			<ListViewItem>items</ListViewItem>                                              Handling exceptions
            		</ListView>
            	</Grid>
            </Window>                                                                         Basic controls
                                                                                               The TextBlock control
                                                                                               The TextBlock control - Inline
                                                                                               formatting
                                                                                               The Label control
                                                                                               The TextBox control
                                                                                               The CheckBox control
                                                                                             Panels
                                                                                              Introduction to WPF Panels
                                                                                              The Canvas
         This is pretty much as simple as it gets, using manually specified                   The WrapPanel
         ListViewItem to fill the list and with nothing but a text label representing each    The StackPanel
         item - a bare minimum WPF ListView control.                                          The DockPanel
                                                                                              The Grid
         ListViewItem with an image                                                           The Grid - Rows & Columns
                                                                                              The Grid - Units
         Because of the look-less nature of WPF, specifying an image for a
                                                                                              The Grid - Spanning
         ListViewItem isn't just about assigning an image ID or key to a property.
                                                                                              The Grid - GridSplitter
         Instead, you take full control of it and specify the controls needed to render
                                                                                              Using the Grid: A contact
         both image and text in the ListViewItem. Here's an example:
                                                                                               form
            <Window
            x:Class="WpfTutorialSamples.ListView_control.ListViewBasicSa
                                                                                             Data binding
                                                                                              Introduction
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      Hello, bound world!
                                                                                              Using the DataContext
                                                                                              The UpdateSourceTrigger
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             property
                       Title="ListViewBasicSample" Height="200"                               Responding to changes
            Width="200">                                                                      Value conversion with
                  <Grid>                                                                       IValueConverter
            		<ListView Margin="10">                                                          The StringFormat property
            			<ListViewItem>                                                                 Debugging data bindings
            				<StackPanel
            Orientation="Horizontal">
            					<Image                                                                      Commands
            Source="/WpfTutorialSamples;component/Images/bullet_green.pn                      Introduction
             Margin="0,0,5,0" />                                                              Using commands
            					                                                                             Implementing custom
            <TextBlock>Green</TextBlock>                                                       commands
            				</StackPanel>
            			</ListViewItem>
            			<ListViewItem>
                                                                                             Common interface
            				<StackPanel
                                                                                             controls
            Orientation="Horizontal">
                                                                                              The Menu control
            					<Image
                                                                                              The ContextMenu
            Source="/WpfTutorialSamples;component/Images/bullet_blue.png
                                                                                              The ToolBar control
             Margin="0,0,5,0" />
                                                                                              The StatusBar control
            					
                                                                                        Misc. controls
                                                                                          The Border control
                                                                                          The Slider control
                                                                                          The ProgressBar control
                                                                                          The WebBrowser control
         What we do here is very simple. Because the ListViewItem derives from the        The WindowsFormsHost
         ContentControl class, we can specify a WPF control as its content. In this       control
         case, we use a StackPanel, which has an Image and a TextBlock as its child
         controls.
                                                                                        The TabControl
         Summary                                                                          Using the TabControl
         As you can see, building a ListView manually in XAML is very simple, but in      Tab positions
         most cases, your ListView data will come from some sort of data source,          Styling the TabItems
         which should be rendered in the ListView at runtime. We will look into doing
         just that in the next chapter.
                                                                                        List controls
                Previous                                                  Next            The ItemsControl
                                                                                          The ListBox control
                                                                                          The ComboBox control
                                                                                          ListView grouping
                                                                                          ListView sorting
                                                                                          How-to: ListView with
                                                                                           column sorting
                                                                                          ListView filtering
                                                                                         Styles
                                                                                          Introduction
                                                                                          Using styles
                                                                                          Triggers
                                                                                          Multi triggers
                                                                                          Trigger animations
                                                                                         Misc.
                                                                                          The DispatcherTimer
                                                        
   
Download
                                                         PDF!
                                                                        
Back to Top
Home Contact Us
                                                                                            Download as PDF
        ListView, data binding and
        ItemTemplate                                                                               Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
                                                                                            About WPF
          In the previous article, we manually populated a ListView control through
                                                                                             What is WPF?
           XAML code, but in WPF, it's all about data binding. The concept of data
                                                                                             WPF vs. WinForms
           binding is explained in detail in another part of this tutorial, but generally
           speaking it's about separating data from layout. So, let's try binding some
           data to a ListView:
                                                                                            Getting started
            <Window                                                                          Visual Studio Express
            x:Class="WpfTutorialSamples.ListView_control.ListViewDataBin                     Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    XAML
                                                                                             What is XAML?
                                                                                             Basic XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           Events in XAML
                        Title="ListViewDataBindingSample" Height="300"
            Width="300">
                  <Grid>
                                                                                            A WPF application
            		<ListView Margin="10"
                                                                                             Introduction
            Name="lvDataBinding"></ListView>
                                                                                             The Window
            	</Grid>
                                                                                             Working with App.xaml
            </Window>
                                                                                             Command-line parameters
                                                                                             Resources
                                                                                             Handling exceptions
            using System;
            using System.Collections.Generic;
            using System.Windows;                                                           Basic controls
                                                                                             The TextBlock control
            namespace WpfTutorialSamples.ListView_control
                                                                                             The TextBlock control - Inline
            {
                                                                                             formatting
            	           public partial class ListViewDataBindingSample :
                                                                                             The Label control
            Window
                                                                                             The TextBox control
            	{
                                                                                             The CheckBox control
            		public ListViewDataBindingSample()
                                                                                          Commands
                                                                                           Introduction
                                                                                           Using commands
          Each user is represented by their type name in the ListView. This is to be       Implementing custom
          expected, because .NET doesn't have a clue about how you want your data           commands
          to be displayed, so it just calls the ToString() method on each object and
          uses that to represent the item. We can use that to our advantage and
          override the ToString() method, to get a more meaningful output. Try            Common interface
          replacing the User class with this version:                                     controls
                                                                                           The Menu control
            public class User                                                              The ContextMenu
            {                                                                              The ToolBar control
            	           public string Name { get; set; }                                   The StatusBar control
                                                                                           The Ribbon Control
            	           public int Age { get; set; }
            	{
                                                                                              Introduction
            		                     return this.Name + ", " + this.Age + "
                                                                                              The
            years old";
                                                                                               FlowDocumentScrollViewer
            	}
                                                                                               control
            }
                                                                                              The
                                                                                               FlowDocumentPageViewer
                                                                                               control
                                                                                              The FlowDocumentReader
                                                                                               control
                                                                                              Creating a FlowDocument
                                                                                               from Code-behind
                                                                                              Advanced FlowDocument
                                                                                               content
                                                                                              The RichTextBox control
          This is a much more user friendly display and will do just fine in some cases,
          but relying on a simple string is not that flexible. Perhaps you want a part of
          the text to be bold or another color? Perhaps you want an image?                  Misc. controls
          Fortunately, WPF makes all of this very simple using templates.                     The Border control
                                                                                              The Slider control
          ListView with an ItemTemplate                                                       The ProgressBar control
                                                                                              The WebBrowser control
          WPF is all about templating, so specifying a data template for the ListView is
                                                                                              The WindowsFormsHost
          very easy. In this example, we'll do a bunch of custom formatting in each
                                                                                              control
          item, just to show you how flexible this makes the WPF ListView.
          We use a bunch of TextBlock controls to build each item, where we put part of
          the text in bold. For the e-mail address, which we added to this example, we
          underline it, give it a blue color and change the mouse cursor, to make it
          behave like a hyperlink.
          Summary
          Using an ItemTemplate and data binding, we produced a pretty cool ListView
          control. However, it still looks a lot like a ListBox. A very common usage
          scenario for a ListView is to have columns, sometimes (e.g. in WinForms)
          referred to as a details view. WPF comes with a built-in view class to handle
          this, which we will talk about in the next chapter.
Previous Next
                                                                       
         
Download
                                                                        PDF!
                                                                                                  
Back to Top
Home Contact Us
                                                                                          Download as PDF
        ListView with a GridView
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
In the previous ListView articles, we have used the most basic version of the   About WPF
          WPF ListView, which is the one without a custom View specified. This results
                                                                                           What is WPF?
         
in a ListView that acts very much like the WPF ListBox, with some subtle
                                                                                           WPF vs. WinForms
          differences. The real power lies in the views though and WPF comes with
          one
specialized view built-in: The GridView.
         
By using the GridView, you can get several columns of data in your ListView,    Getting started
          much like you see it in Windows Explorer. Just to make sure that everyone        Visual Studio Express
          can
visualize it, we'll start off with a basic example:                          Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.ListView_control.ListViewGridVie                  XAML
                                                                                           What is XAML?
                                                                                           Basic XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                          A WPF application
                       Title="ListViewGridViewSample" Height="200"
            Width="400">                                                                   Introduction
                  <Grid>                                                                   The Window
            		                     <ListView Margin="10" Name="lvUsers">                   Working with App.xaml
            			<ListView.View>                                                             Command-line parameters
            				<GridView>                                                                 Resources
            					<GridViewColumn                                                           Handling exceptions
            Header="Name" Width="120" DisplayMemberBinding="{Binding
            Name}" />
            					<GridViewColumn                                                          Basic controls
            Header="Age" Width="50" DisplayMemberBinding="{Binding                         The TextBlock control
            Age}" />                                                                       The TextBlock control - Inline
            					<GridViewColumn                                                           formatting
            Header="Mail" Width="150" DisplayMemberBinding="{Binding                       The Label control
            Mail}" />                                                                      The TextBox control
            				</GridView>                                                                The CheckBox control
            			</ListView.View>
                                                                                  Panels
                                                                                   Introduction to WPF Panels
            using System;                                                          The Canvas
            using System.Collections.Generic;                                      The WrapPanel
            using System.Windows;                                                  The StackPanel
                                                                                   The DockPanel
            namespace WpfTutorialSamples.ListView_control                          The Grid
            {                                                                      The Grid - Rows & Columns
            	          public partial class ListViewGridViewSample :               The Grid - Units
            Window                                                                 The Grid - Spanning
            	{                                                                     The Grid - GridSplitter
            		public ListViewGridViewSample()                                      Using the Grid: A contact
            		{                                                                     form
            			InitializeComponent();
            			                               List<User> items = new List<User>
            ();                                                                   Data binding
            			                               items.Add(new User() { Name =
                                                                                   Introduction
            "John Doe", Age = 42, Mail = "john@doe-family.com" });
                                                                                   Hello, bound world!
            			                               items.Add(new User() { Name =
                                                                                   Using the DataContext
            "Jane Doe", Age = 39, Mail = "jane@doe-family.com" });
                                                                                   The UpdateSourceTrigger
            			                               items.Add(new User() { Name =
                                                                                    property
            "Sammy Doe", Age = 7, Mail = "sammy.doe@gmail.com" });
                                                                                   Responding to changes
            			lvUsers.ItemsSource = items;
                                                                                   Value conversion with
            		}
                                                                                    IValueConverter
            	}
                                                                                   The StringFormat property
                                                                                   Debugging data bindings
            	          public class User
            	{
            		                     public string Name { get; set; }
                                                                                  Commands
            		                     public int Age { get; set; }                    Introduction
                                                                                   Using commands
            		                     public string Mail { get; set; }                Implementing custom
            	}                                                                      commands
            }
                                                                                  Common interface
                                                                                  controls
                                                                                   The Menu control
                                                                                   The ContextMenu
                                                                                   The ToolBar control
                                                                                   The StatusBar control
                                                                                   The Ribbon Control
                                                                                                Introduction
         
So, we use the same User class as previously, for test data, which we then            The
          bind to the ListView. This is all the same as we saw in previous chapters, but         FlowDocumentScrollViewer
          as you can see from the screenshot, the layout is very different. This is the          control
          power of data binding - the same data, but presented in a completely                  The
          different way, just by changing the markup.                                            FlowDocumentPageViewer
                                                                                                 control
         
In the markup (XAML), we define a View for the ListView, using the                    The FlowDocumentReader
          ListView.View property. We set it to a GridView, which is currently the only           control
          included
view type in WPF (you can easily create your own though!). The               Creating a FlowDocument
          GridView is what gives us the column-based view that you see on the                    from Code-behind
          screenshot.                                                                           Advanced FlowDocument
                                                                                                 content
         
Inside of the GridView, we define three columns, one for each of the pieces
                                                                                                The RichTextBox control
          of data that we wish to show. The Header property is used to
specify the text
          that we would like to show for the column and then we use the
          DisplayMemberBinding property to bind the value to a
property from our
          User class.                                                                         Misc. controls
                                                                                                The Border control
         
Templated cell content                                                                The Slider control
                                                                                                The ProgressBar control
         
Using the DisplayMemberBinding property is pretty much limited to
                                                                                                The WebBrowser control
          outputting simple strings, with no custom formatting at all, but the WPF
                                                                                                The WindowsFormsHost
          ListView is much more flexible than that. By specifying a CellTemplate, we
                                                                                                control
          take full control of how the content is rendered within the
specific column cell.
         
The GridViewColumn will use the DisplayMemberBinding as its first priority, it
          it's present. The second choice will be the CellTemplate property, which
we'll      The TabControl
          use for this example:                                                                 Using the TabControl
                                                                                                Tab positions
            <Window                                                                             Styling the TabItems
            x:Class="WpfTutorialSamples.ListView_control.ListViewGridVie
                                                                                              List controls
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                        The ItemsControl
                                                                                                The ListBox control
                                                                                                The ComboBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ListViewGridViewCellTemplateSample"
            Height="200" Width="400">
                                                                                              The ListView control
                  <Grid>
                                                                                                Introduction
            		                     <ListView Margin="10" Name="lvUsers">
                                                                                                A simple ListView
            			<ListView.View>
                                                                                                ListView, data binding and
            				<GridView>
                                                                                                 ItemTemplate
            					<GridViewColumn
                                                                                                ListView with a GridView
            Header="Name" Width="120" DisplayMemberBinding="{Binding
                                                                                                How-to: Left aligned column
            Name}" />
                                                                                                 names
            					<GridViewColumn
                                                                                                ListView grouping
            Header="Age" Width="50" DisplayMemberBinding="{Binding
                                                                                                ListView sorting
            Age}" />
                                                                                                How-to: ListView with
            					<GridViewColumn
                                                                                                 column sorting
            Header="Mail" Width="150">
                                                                                          ListView filtering
            						
            <GridViewColumn.CellTemplate>
            							
            <DataTemplate>                                                               The TreeView control
            							                                                                       Introduction
            	          <TextBlock Text="{Binding Mail}"                                   A simple TreeView
            TextDecorations="Underline" Foreground="Blue"                                 TreeView, data binding and
            Cursor="Hand" />                                                               multiple templates
            							                                                                       Handling
            </DataTemplate>                                                                Selection/Expansion state
            						                                                                        Lazy loading TreeView items
            </GridViewColumn.CellTemplate>
            					</GridViewColumn>
            				</GridView>                                                              The DataGrid control
            			</ListView.View>
                                                                                          Introduction
            		</ListView>
                                                                                          Custom columns
            	</Grid>
                                                                                          Details row
            </Window>
                                                                                         Styles
                                                                                          Introduction
                                                                                          Using styles
                                                                                          Triggers
                                                                                          Multi triggers
                                                                                          Trigger animations
                                                                                         Misc.
                                                                                          The DispatcherTimer
         Please notice: The Code-behind code for this example is the same as the one     Audio & Video
         used for the first example in this article.                                      Playing audio
                                                                                          Playing video
         
We specify a custom CellTemplate for the last column, where we would like
                                                                                          How-to: Complete media
          to do some special formatting for the e-mail addresses. For the
other
                                                                                          player
          columns, where we just want basic text output, we stick with the
                                                                                          Speech synthesis
          DisplayMemberBinding, simply because it requires way less markup.
                                                                                          Speech recognition
Previous Next
                                                       
   
Download
                                                       PDF!
                                                                       
Back to Top
Home Contact Us
                                                                                            Download as PDF
        How-to: ListView with left aligned
        column names                                                                               Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
                                                                                            About WPF
          
In a normal ListView, the column names are left aligned, but for some
                                                                                             What is WPF?
           reason, Microsoft decided to center the names by default in the WPF
                                                                                             WPF vs. WinForms
           ListView. In many
cases this will make your application look out-of-style
           compared to other Windows applications. This is how the ListView will look in
           WPF by default:
                                                                                            Getting started
                                                                                             Visual Studio Express
                                                                                             Hello, WPF!
                                                                                            XAML
                                                                                             What is XAML?
                                                                                             Basic XAML
                                                                                             Events in XAML
                                                                                            A WPF application
          
Let's try changing that to left aligned column names. Unfortunately, there are
           no direct properties on the GridViewColumn to control this, but fortunately       Introduction
           that doesn't mean that it can't be changed.                                       The Window
                                                                                             Working with App.xaml
          
Using a Style, targeted at the GridViewColumHeader, which is the element          Command-line parameters
           used to show the header of a GridViewColumn, we can change the                    Resources
           HorizontalAlignment
property. In this case it defaults to Center, but we can      Handling exceptions
           change it to Left, to accomplish what we want:
                                                                                              Commands
                                                                                               Introduction
                                                                                               Using commands
                                                                                               Implementing custom
                                                                                                commands
                                                                                              Common interface
          
The part that does all the work for us, is the Style defined in the Resources of   controls
           the ListView:                                                                       The Menu control
                                                                                               The ContextMenu
            <Style TargetType="{x:Type GridViewColumnHeader}">                                 The ToolBar control
            					<Setter                                                                       The StatusBar control
            Property="HorizontalContentAlignment" Value="Left" />                              The Ribbon Control
            </Style>
                                                                                                   Introduction
          
By defining the Style within the control itself, it only applies to this particular
                                                                                                   The
           ListView. In many cases you might like to make it apply to all the ListViews
                                                                                                    FlowDocumentScrollViewer
           within the
same Window/Page or perhaps even globally across the
                                                                                                    control
           application. You can do this by either copying the style to the Window
                                                                                                   The
           resources or the Application
resources. Here's the same example, where we
                                                                                                    FlowDocumentPageViewer
           have applied the style to the entire Window instead of just the particular
                                                                                                    control
           ListView:
                                                                                                   The FlowDocumentReader
                                                                                                    control
            <Window                                                                                Creating a FlowDocument
            x:Class="WpfTutorialSamples.ListView_control.ListViewGridVie                            from Code-behind
                                                                                                   Advanced FlowDocument
                                                                                                    content
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                           The RichTextBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                 Misc. controls
                        Title="ListViewGridViewSample" Height="200"
                                                                                                   The Border control
            Width="400">
                                                                                                   The Slider control
            	<Window.Resources>
                                                                                                   The ProgressBar control
            		<Style TargetType="{x:Type
                                                                                                   The WebBrowser control
            GridViewColumnHeader}">
                                                                                                   The WindowsFormsHost
            			<Setter
                                                                                                   control
            Property="HorizontalContentAlignment" Value="Left" />
            		</Style>
            	</Window.Resources>
            	<Grid>                                                                              The TabControl
            		                     <ListView Margin="10" Name="lvUsers">                           Using the TabControl
            			<ListView.View>                                                                     Tab positions
            				<GridView>                                                                         Styling the TabItems
            					<GridViewColumn
            Header="Name" Width="120" DisplayMemberBinding="{Binding
            Name}" />                                                                            List controls
            					<GridViewColumn
                                                                                                   The ItemsControl
            Header="Age" Width="50" DisplayMemberBinding="{Binding
                                                                                                   The ListBox control
            Age}" />
                                                                                                   The ComboBox control
            					<GridViewColumn
            Header="Mail" Width="150" DisplayMemberBinding="{Binding
            Mail}" />
            				</GridView>
                                                                                                 The ListView control
            			</ListView.View>                                                                    Introduction
            		</ListView>                                                                          A simple ListView
            	</Grid>                                                                               ListView, data binding and
            </Window>                                                                               ItemTemplate
                                                                                                   ListView with a GridView
                                                                                                   How-to: Left aligned column
                                                                                                    names
          
In case you want another alignment, e.g. right alignment, you just change the           ListView grouping
           value of the style like this:                                                           ListView sorting
                                                                                                   How-to: ListView with
                                                                                                    column sorting
            <Setter Property="HorizontalContentAlignment"
                                                                                                   ListView filtering
            Value="Right" />
                                                                                                  Styles
                                                                                                   Introduction
                                                                                                   Using styles
                                                                                                   Triggers
                                                                                                   Multi triggers
                                                                                                   Trigger animations
                                                                                                  Misc.
                                                                                                   The DispatcherTimer
                                                                       
         
Download
                                                                        PDF!
                                                                              
Back to Top
Home Contact Us
                                                                                          Download as PDF
        ListView grouping
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
          
As we already talked about earlier, the WPF ListView is very flexible.         About WPF
           Grouping is yet another thing that it supports out of the box, and it's both
                                                                                           What is WPF?
           easy to
use and extremely customizable. Let's jump straight into the first
                                                                                           WPF vs. WinForms
           example, then I'll explain it and afterwards we can use the standard WPF
           tricks to
customize the appearance even further.
          
For this article, I've borrowed the sample code from a previous article and    Getting started
           then expanded on it to support grouping. It looks like this:                    Visual Studio Express
                                                                                           Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.ListView_control.ListViewGroupSa
                                                                                          XAML
                                                                                           What is XAML?
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Basic XAML
                                                                                           Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ListViewGroupSample" Height="300"
                                                                                          A WPF application
            Width="300">
                  <Grid Margin="10">                                                       Introduction
                       <ListView Name="lvUsers">                                           The Window
                             <ListView.View>                                               Working with App.xaml
                                   <GridView>                                              Command-line parameters
                                        <GridViewColumn Header="Name"                      Resources
            Width="120" DisplayMemberBinding="{Binding Name}" />                           Handling exceptions
                                        <GridViewColumn Header="Age"
            Width="50" DisplayMemberBinding="{Binding Age}" />
                                   </GridView>                                            Basic controls
                             </ListView.View>                                              The TextBlock control
                                                                                           The TextBlock control - Inline
                             <ListView.GroupStyle>                                         formatting
                                   <GroupStyle>                                            The Label control
                                        <GroupStyle.HeaderTemplate>                        The TextBox control
                                                <DataTemplate>                             The CheckBox control
                                                    <TextBlock FontWeight="Bold"
            			CollectionView view =
                                                                                    Commands
            (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.             Introduction
                                                                                     Using commands
            			PropertyGroupDescription                                              Implementing custom
            groupDescription = new PropertyGroupDescription("Sex");                   commands
            			
            view.GroupDescriptions.Add(groupDescription);
            		}                                                                     Common interface
            	}                                                                      controls
                                                                                     The Menu control
            	          public enum SexType { Male, Female };
                                                                                     The ContextMenu
                                                                                     The ToolBar control
            	          public class User
                                                                                     The StatusBar control
            	{
                                                                                     The Ribbon Control
            		                     public string Name { get; set; }
                                                                                              Misc. controls
                                                                                                The Border control
                                                                                                The Slider control
                                                                                                The ProgressBar control
          
In XAML, I have added a GroupStyle to the ListView, in which I define a
                                                                                                The WebBrowser control
           template for the header of each group. It consists of a TextBlock control,
                                                                                                The WindowsFormsHost
           where
I've used a slightly larger and bold text to show that it's a group - as
                                                                                                control
           we'll see later on, this can of course be customized a lot more. The TextBlock
          
Text property is bound to a Name property, but please be aware that this is
           not the Name property on the data object (in this case the User class).
           Instead, it is the name of the
group, as assigned by WPF, based on the             The TabControl
           property we use to divide the objects into groups.                                   Using the TabControl
                                                                                                Tab positions
          
In Code-behind, we do the same as we did before: We create a list and add            Styling the TabItems
           some User objects to it and then we bind the list to the ListView - nothing
           new
there, except for the new Sex property that I've added, which tells
           whether the user is male or female.
                                                                                              List controls
          
After assigning an ItemsSource, we use this to get a CollectionView that the         The ItemsControl
           ListView creates for us. This specialized View instance contains a lot of            The ListBox control
           possibilities, including the ability to group the items. We use this by adding a     The ComboBox control
           so-called PropertyGroupDescription to the GroupDescriptions of the view.
           This basically tells WPF to group by a specific property on the data objects,
           in this case the Sex property.                                                     The ListView control
                                                                                                Introduction
          
Customizing the group header                                                         A simple ListView
          
The above example was great for showing the basics of ListView grouping,             ListView, data binding and
           but the look was a tad boring, so let's exploit the fact that WPF lets us define      ItemTemplate
           our own templates and spice things up. A common request is to be able to             ListView with a GridView
           collapse and expand the group, and while WPF doesn't provide this behavior           How-to: Left aligned column
           by
default, it's somewhat easy to implement yourself. We'll do it by                  names
           completely re-templating the group container.                                        ListView grouping
                                                                                                ListView sorting
          
It might look a bit cumbersome, but the principles used are somewhat simple          How-to: ListView with
           and you will see them in other situations when you customize the WPF                  column sorting
          controls.
Here's the code:                                                ListView filtering
            <Window
            x:Class="WpfTutorialSamples.ListView_control.ListViewCollaps           The TreeView control
                                                                                    Introduction
                                                                                    A simple TreeView
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta            TreeView, data binding and
                                                                                     multiple templates
                                                                                    Handling
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                   Selection/Expansion state
                       Title="ListViewCollapseExpandGroupSample"                    Lazy loading TreeView items
            Height="300" Width="300">
                   <Grid Margin="10">
                       <ListView Name="lvUsers">                                   The DataGrid control
                             <ListView.View>
                                                                                    Introduction
                                   <GridView>
                                                                                    Custom columns
                                        <GridViewColumn Header="Name"
                                                                                    Details row
            Width="120" DisplayMemberBinding="{Binding Name}" />
                                        <GridViewColumn Header="Age"
            Width="50" DisplayMemberBinding="{Binding Age}" />
                                   </GridView>                                     Styles
                             </ListView.View>                                       Introduction
                                                                                    Using styles
                             <ListView.GroupStyle>                                  Triggers
                                   <GroupStyle>                                     Multi triggers
                                        <GroupStyle.ContainerStyle>                 Trigger animations
                                                <Style TargetType="{x:Type
            GroupItem}">
                                                    <Setter Property="Template">   Misc.
                                                        <Setter.Value>
                                                                                    The DispatcherTimer
                                                            <ControlTemplate>
                                                                <Expander
            IsExpanded="True">
                                                                                   Audio & Video
            <Expander.Header>                                                       Playing audio
                                                                                    Playing video
            <StackPanel Orientation="Horizontal">                                   How-to: Complete media
                                                                                    player
            <TextBlock Text="{Binding Name}" FontWeight="Bold"                      Speech synthesis
            Foreground="Gray" FontSize="22" VerticalAlignment="Bottom"              Speech recognition
              />
</StackPanel>
</Expander.Header>
            <ItemsPresenter />
                                                                   </Expander>
                                                              </ControlTemplate>
                                                        </Setter.Value>
                                                    </Setter>
                                                </Style>
                                        </GroupStyle.ContainerStyle>
                                   </GroupStyle>
                             </ListView.GroupStyle>
                       </ListView>
                  </Grid>
            </Window>
          The Code-behind is exactly the same as used in the first example - feel
          free to scroll up and grab it.
          
Now our groups look a bit more exciting, and they even include an expander
           button, that will toggle the visibility of the group items when you click it
(that's
           why the single female user is not visible on the screenshot - I collapsed that
           particular group). By using the ItemCount property that the group
exposes,
           we can even show how many items each group currently consists of.
          
As you can see, it requires a bit more markup than we're used to, but this
           example also goes a bit beyond what we usually do, so that seems fair.
           When you
read through the code, you will quickly realize that many of the
           lines are just common elements like style and template.
          
Summary
          
Adding grouping to the WPF ListView is very simple - all you need is a
           GroupStyle with a HeaderTemplate, to tell the ListView how to render a
           group, and a
few lines of Code-behind code to tell WPF which property to
           group by. As you can see from the last example, the group is even very
           customizable, allowing
you to create some really cool views, without too
           much work.
Previous Next
                                                      
         
Download
                                                       PDF!
                                                                                 
Back to Top
Home Contact Us
                                                                                          Download as PDF
        ListView sorting
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
          
In the last chapter we saw how we could group items in the WPF ListView by     About WPF
           accessing the View instance of the ListView and then adding a group
                                                                                           What is WPF?
           description.
Applying sorting to a ListView is just as easy, and most of the
                                                                                           WPF vs. WinForms
           process is exactly the same. Let's try a simple example where we sort the
           user objects by
their age:
                                                                                          Getting started
             <Window
             x:Class="WpfTutorialSamples.ListView_control.ListViewSorting                  Visual Studio Express
                                                                                           Hello, WPF!
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                          XAML
                                                                                           What is XAML?
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                        Basic XAML
                        Title="ListViewSortingSample" Height="200"                         Events in XAML
             Width="300">
                  <Grid Margin="10">
                        <ListView Name="lvUsers">
                                                                                          A WPF application
                              <ListView.View>
                                                                                           Introduction
                                   <GridView>
                                                                                           The Window
                                         <GridViewColumn Header="Name"
                                                                                           Working with App.xaml
             Width="120" DisplayMemberBinding="{Binding Name}" />
                                                                                           Command-line parameters
                                         <GridViewColumn Header="Age"
                                                                                           Resources
             Width="50" DisplayMemberBinding="{Binding Age}" />
                                                                                           Handling exceptions
                                   </GridView>
                              </ListView.View>
                        </ListView>
                  </Grid>                                                                 Basic controls
             </Window>                                                                     The TextBlock control
                                                                                           The TextBlock control - Inline
                                                                                           formatting
                                                                                           The Label control
             using System;
                                                                                           The TextBox control
             using System.Collections.Generic;
                                                                                           The CheckBox control
             using System.ComponentModel;
             namespace WpfTutorialSamples.ListView_control
                                                                                   Panels
             {
             	          public partial class ListViewSortingSample :                Introduction to WPF Panels
             Window                                                                 The Canvas
             	{                                                                     The WrapPanel
             		public ListViewSortingSample()                                       The StackPanel
             		{                                                                    The DockPanel
             			InitializeComponent();                                              The Grid
             			                               List<User> items = new List<User>    The Grid - Rows & Columns
             ();                                                                    The Grid - Units
             			                               items.Add(new User() { Name =        The Grid - Spanning
             "John Doe", Age = 42 });                                               The Grid - GridSplitter
             			                               items.Add(new User() { Name =        Using the Grid: A contact
             "Jane Doe", Age = 39 });                                                form
             			                               items.Add(new User() { Name =
             "Sammy Doe", Age = 13 });
             			                               items.Add(new User() { Name =       Data binding
             "Donna Doe", Age = 13 });                                              Introduction
             			lvUsers.ItemsSource = items;                                        Hello, bound world!
                                                                                    Using the DataContext
             			CollectionView view =                                               The UpdateSourceTrigger
             (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.            property
                                                                                    Responding to changes
             			view.SortDescriptions.Add(new                                       Value conversion with
             SortDescription("Age", ListSortDirection.Ascending));                   IValueConverter
             		}                                                                    The StringFormat property
             	}                                                                     Debugging data bindings
                                                                                   Common interface
                                                                                   controls
                                                                                    The Menu control
                                                                                    The ContextMenu
                                                                                    The ToolBar control
                                                                                    The StatusBar control
                                                                                    The Ribbon Control
                                                                                               Introduction
          
The XAML looks just like a previous example, where we simply have a                 The
           couple of columns for displaying information about the user - nothing new            FlowDocumentScrollViewer
           here.                                                                                control
                                                                                               The
          
In the Code-behind, we once again create a list of User objects, which we            FlowDocumentPageViewer
           then assign as the ItemsSource of the ListView. Once we've done that, we             control
           use the
ItemsSource property to get the CollectionView instance that the            The FlowDocumentReader
           ListView automatically creates for us and which we can use to manipulate             control
           how the ListView
shows our objects.                                                 Creating a FlowDocument
                                                                                                from Code-behind
          
With the view object in our hand, we add a new SortDescription to it,
                                                                                               Advanced FlowDocument
           specifying that we want our list sorted by the Age property, in ascending
                                                                                                content
           order. As
you can see from the screenshot, this works perfectly well - the list
                                                                                               The RichTextBox control
           is sorted by age, instead of being in the same order as the items were added.
          
Multiple sort criteria
                                                                                             Misc. controls
          
As shown in the first example, sorting is very easy, but on the screenshot          The Border control
           you'll see that Sammy comes before Donna. They have the same age, so in             The Slider control
           this
case, WPF will just use the order in which they were added. Fortunately,       The ProgressBar control
           WPF lets us specify as many sort criteria as we want. In the example above,         The WebBrowser control
           try
changing the view-related code into something like this:                        The WindowsFormsHost
                                                                                               control
             CollectionView view =
             (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.
                                                                                             The TabControl
             view.SortDescriptions.Add(new SortDescription("Age",
                                                                                               Using the TabControl
             ListSortDirection.Ascending));
                                                                                               Tab positions
             view.SortDescriptions.Add(new SortDescription("Name",
                                                                                               Styling the TabItems
             ListSortDirection.Ascending));
                                                                                             List controls
                                                                                               The ItemsControl
                                                                                               The ListBox control
                                                                                               The ComboBox control
                                                                                               A simple ListView
                                                                                               ListView, data binding and
                                                                                                ItemTemplate
          
Now the view will be sorted using age first, and when two identical values are
                                                                                               ListView with a GridView
           found, the name will be used as a secondary sorting parameter.
                                                                                               How-to: Left aligned column
          
Summary                                                                              names
                                                                                               ListView grouping
          
It's very easy to sort the contents of a ListView, as seen in the above             ListView sorting
           examples, but so far, all the sorting is decided by the programmer and not          How-to: ListView with
           the
end-user. In the next article I'll give you a how-to article showing you how     column sorting
           to let the user decide the sorting by clicking on the columns, as seen in           ListView filtering
           Windows.
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                     
         
Download
                                                      PDF!
                                                                                       
Back to Top
Home Contact Us
                                                                                                 Download as PDF
        How-to: ListView with column sorting
                                                                                                        Download this entire
                                                                                                        tutorial as PDF right
                                                                                                 now!
          
In the last chapter we saw how we could easily sort a ListView from Code-             About WPF
          behind, and while this will suffice for some cases, it doesn't allow the end-user
                                                                                                  What is WPF?
          
to decide on the sorting. Besides that, there was no indication on which
                                                                                                  WPF vs. WinForms
           column the ListView was sorted by. In Windows, and in many user interfaces
           in
general, it's common to illustrate sort directions in a list by drawing a
           triangle next to the column name currently used to sort by.
                                                                                                 Getting started
          
In this how-to article, I'll give you a practical solution that gives us all of the    Visual Studio Express
           above, but please bear in mind that some of the code here goes a bit
beyond            Hello, WPF!
           what we have learned so far - that's why it has the "how-to" label.
          
This article builds upon the previous one, but I'll still explain each part as we
                                                                                                 XAML
           go along. Here's our goal - a ListView with column sorting, including
visual
           indication of sort field and direction. The user simply clicks a column to sort        What is XAML?
           by and if the same column is clicked again, the sort direction is
reversed.            Basic XAML
           Here's how it looks:                                                                   Events in XAML
                                                                                                 A WPF application
                                                                                                  Introduction
                                                                                                  The Window
                                                                                                  Working with App.xaml
                                                                                                  Command-line parameters
                                                                                                  Resources
                                                                                                  Handling exceptions
                                                                                                 Basic controls
          
The XAML                                                                               The TextBlock control
          
The first thing we need is some XAML to define our user interface. It currently        The TextBlock control - Inline
           looks like this:                                                                       formatting
                                                                                                  The Label control
                                                                                                  The TextBox control
            <Window
                                                                                                  The CheckBox control
            x:Class="WpfTutorialSamples.ListView_control.ListViewColumnS
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                            Panels
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           Introduction to WPF Panels
                        Title="ListViewColumnSortingSample" Height="200"                     The Canvas
            Width="350">                                                                     The WrapPanel
                  <Grid Margin="10">                                                         The StackPanel
                        <ListView Name="lvUsers">                                            The DockPanel
                             <ListView.View>                                                 The Grid
                                   <GridView>                                                The Grid - Rows & Columns
                                        <GridViewColumn Width="120"                          The Grid - Units
            DisplayMemberBinding="{Binding Name}">                                           The Grid - Spanning
                                              <GridViewColumn.Header>                        The Grid - GridSplitter
                                                    <GridViewColumnHeader                    Using the Grid: A contact
            Tag="Name"                                                                        form
            Click="lvUsersColumnHeader_Click">Name</GridViewColumnHeader
          
The Tag property is used to hold the field name that will be used to sort by, if     Introduction
           this particular column is clicked. This is done in the                               The
           lvUsersColumnHeader_Click event that each of the columns subscribes to.               FlowDocumentScrollViewer
                                                                                                 control
          
That was the key concepts of the XAML. Besides that, we bind to our Code-            The
          behind properties Name, Age and Sex, which we'll discuss now.                          FlowDocumentPageViewer
                                                                                                 control
          
The Code-behind                                                                      The FlowDocumentReader
                                                                                                 control
          
In Code-behind, there are quite a few things happening. I use a total of three       Creating a FlowDocument
           classes, which you would normally divide up into individual files, but for            from Code-behind
           convenience, I have kept them in the same file, giving us a total of ~100            Advanced FlowDocument
           lines. First the code and then I'll explain how it works:                             content
                                                                                                The RichTextBox control
            using System;
            using System.Collections.Generic;
            using System.ComponentModel;                                                      Misc. controls
            using System.Windows;
                                                                                                The Border control
            using System.Windows.Controls;
                                                                                                The Slider control
            using System.Windows.Data;
                                                                                                The ProgressBar control
            using System.Windows.Documents;
                                                                                                The WebBrowser control
            using System.Windows.Media;
                                                                                                The WindowsFormsHost
                                                                                                control
            namespace WpfTutorialSamples.ListView_control
            {
            	           public partial class ListViewColumnSortingSample :
              Window                                                                          The TabControl
            	{                                                                                  Using the TabControl
            		private GridViewColumnHeader                                                      Tab positions
            listViewSortCol = null;                                                             Styling the TabItems
            		                     private SortAdorner listViewSortAdorner =
            null;
                                                                                              List controls
            		public ListViewColumnSortingSample()
                                                                                                The ItemsControl
            		{
                                                                                                The ListBox control
            			InitializeComponent();
                                                                                                The ComboBox control
            			                               List<User> items = new List<User>
            ();
            			                               items.Add(new User() { Name =
                                                                                              The ListView control
            "John Doe", Age = 42, Sex = SexType.Male });
            			                               items.Add(new User() { Name =                     Introduction
            "Jane Doe", Age = 39, Sex = SexType.Female });                                      A simple ListView
            			                               items.Add(new User() { Name =                     ListView, data binding and
            "Sammy Doe", Age = 13, Sex = SexType.Male });                                        ItemTemplate
            			                               items.Add(new User() { Name =                     ListView with a GridView
            "Donna Doe", Age = 13, Sex = SexType.Female });                                     How-to: Left aligned column
            			lvUsers.ItemsSource = items;                                                      names
            		}                                                                                 ListView grouping
                                                                                                ListView sorting
            		private void                                                                      How-to: ListView with
            lvUsersColumnHeader_Click(object sender, RoutedEventArgs                             column sorting
            e)                                                                     ListView filtering
            		{
            			GridViewColumnHeader column =
            (sender as GridViewColumnHeader);                                     The TreeView control
            			string sortBy =                                                     Introduction
            column.Tag.ToString();                                                 A simple TreeView
            			if(listViewSortCol != null)                                         TreeView, data binding and
            			{                                                                    multiple templates
            				                                                                   Handling
            AdornerLayer.GetAdornerLayer(listViewSortCol).Remove(listVie            Selection/Expansion state
                                                                                   Lazy loading TreeView items
            				
            lvUsers.Items.SortDescriptions.Clear();
            			}
                                                                                  The DataGrid control
                                                                                   Introduction
            			ListSortDirection newDir =
                                                                                   Custom columns
            ListSortDirection.Ascending;
                                                                                   Details row
            			                               if(listViewSortCol == column &&
            listViewSortAdorner.Direction == newDir)
            				newDir =
            ListSortDirection.Descending;                                         Styles
                                                                                   Introduction
            			listViewSortCol = column;                                           Using styles
            			listViewSortAdorner = new                                           Triggers
            SortAdorner(listViewSortCol, newDir);                                  Multi triggers
            			                                                                    Trigger animations
            AdornerLayer.GetAdornerLayer(listViewSortCol).Add(listViewSo
            			                                                                   Misc.
            lvUsers.Items.SortDescriptions.Add(new
                                                                                   The DispatcherTimer
            SortDescription(sortBy, newDir));
            		}
            	}
                                                                                  Audio & Video
            	           public enum SexType { Male, Female };                      Playing audio
                                                                                   Playing video
            	           public class User                                          How-to: Complete media
            	{                                                                     player
            		                     public string Name { get; set; }                Speech synthesis
                                                                                   Speech recognition
            		                     public int Age { get; set; }
4 Z");
            			if(AdornedElement.RenderSize.Width
              < 20)
            				return;
            			drawingContext.Pop();
            		}
            	}
            }
          
Allow me to start from the bottom and then work my way up while explaining
          what happens. The last class in the file is an Adorner class called
          SortAdorner. All this little class does is to draw a triangle, either pointing up
          or down, depending on the sort direction. WPF uses the
concept of adorners
          to allow you to paint stuff over other controls, and this is exactly what we
          want here: The ability to draw a sorting triangle on top
of our ListView column
          header.
          
The SortAdorner works by defining two Geometry objects, which are
           basically used to describe 2D shapes - in this case a
triangle with the tip
           pointing up and one with the tip pointing down. The Geometry.Parse()
           method uses the list of points to draw the triangles, which will
be explained
           more thoroughly in a later article.
          
The SortAdorner is aware of the sort direction, because it needs to draw the
           proper triangle, but is not aware of the field that we order
by - this is handled
           in the UI layer.
          
The User class is just a basic information class, used to contain information
           about a user. Some of this information is used in the UI
layer, where we bind
           to the Name, Age and Sex properties.
          
In the Window class, we have two methods: The constructor where we build
           a list of users and assign it to the ItemsSource of our ListView, and then the
          
more interesting click event handler that will be hit when the user clicks a
           column. In the top of the class, we have defined two private variables:
           listViewSortCol and listViewSortAdorner. These will help us keep track of
           which column we're currently sorting by and the adorner we
placed to
           indicate it.
          
In the lvUsersColumnHeader_Click event handler, we start off by getting a
           reference to the column that the user clicked. With this, we can decide which
           property on the User class to sort by, simply by looking at the Tag property
           that we defined in XAML. We then check if we're already sorting by a column
           -
if that is the case, we remove the adorner and clear the current sort
           descriptions.
          
After that, we're ready to decide the direction. The default is ascending, but
           we do a check to see if we're already sorting by the column that the user
           clicked - if that is the case, we change the direction to descending.
          
In the end, we create a new SortAdorner, passing in the column that it should
           be rendered on, as well as the direction. We add this to the AdornerLayer of
           the column header, and at the very end, we add a SortDescription to the
           ListView, to let it know which property to sort by and in which direction.
          
Summary
          
Congratulations, you now have a fully sortable ListView with visual indication
           of sort column and direction. In case you want to know more about some of
           the concepts used in this article, like data binding, geometry or ListViews in
           general, then please check out some of the other articles, where each of the
           subjects are covered in depth.
Previous Next
                                                                         
         
Download
                                                                          PDF!
                                                                                                    
Back to Top
Home Contact Us
                                                                                             Download as PDF
        ListView filtering
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
We've already done several different things with the ListView, like grouping      About WPF
           and sorting, but another very useful ability is filtering. Obviously, you
could
                                                                                              What is WPF?
           just limit the items you add to the ListView in the first place, but often you
                                                                                              WPF vs. WinForms
           would need to filter the ListView dynamically, in runtime, usually
based on a
           user entered filter string. Luckily for us, the view mechanisms of the ListView
           also make it easy to do just that, like we saw it with sorting
and grouping.
                                                                                             Getting started
          
Filtering is actually quite easy to do, so let's jump straight into an example,    Visual Studio Express
           and then we'll discuss it afterwards:                                              Hello, WPF!
             <Window
             x:Class="WpfTutorialSamples.ListView_control.FilteringSample                    XAML
                                                                                              What is XAML?
                                                                                              Basic XAML
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              Events in XAML
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                             A WPF application
                        Title="FilteringSample" Height="200" Width="300">
                   <DockPanel Margin="10">                                                    Introduction
                        <TextBox DockPanel.Dock="Top" Margin="0,0,0,10"                       The Window
             Name="txtFilter" TextChanged="txtFilter_TextChanged" />                          Working with App.xaml
                        <ListView Name="lvUsers">                                             Command-line parameters
                              <ListView.View>                                                 Resources
                                    <GridView>                                                Handling exceptions
                                          <GridViewColumn Header="Name"
             Width="120" DisplayMemberBinding="{Binding Name}" />
                                          <GridViewColumn Header="Age"                       Basic controls
             Width="50" DisplayMemberBinding="{Binding Age}" />                               The TextBlock control
                                    </GridView>                                               The TextBlock control - Inline
                              </ListView.View>                                                formatting
                        </ListView>                                                           The Label control
                   </DockPanel>                                                               The TextBox control
             </Window>                                                                        The CheckBox control
             using System;
             using System.Collections.Generic;
             using System.Windows;                                                   Panels
             using System.Windows.Data;                                               Introduction to WPF Panels
                                                                                      The Canvas
             namespace WpfTutorialSamples.ListView_control                            The WrapPanel
             {                                                                        The StackPanel
             	          public partial class FilteringSample : Window                 The DockPanel
             	{                                                                       The Grid
             		public FilteringSample()                                               The Grid - Rows & Columns
             		{                                                                      The Grid - Units
             			InitializeComponent();                                                The Grid - Spanning
             			                                 List<User> items = new List<User>    The Grid - GridSplitter
             ();                                                                      Using the Grid: A contact
             			                                 items.Add(new User() { Name =         form
             "John Doe", Age = 42 });
             			                                 items.Add(new User() { Name =
             "Jane Doe", Age = 39 });                                                Data binding
             			                                 items.Add(new User() { Name =
                                                                                      Introduction
             "Sammy Doe", Age = 13 });
                                                                                      Hello, bound world!
             			                                 items.Add(new User() { Name =
                                                                                      Using the DataContext
             "Donna Doe", Age = 13 });
                                                                                      The UpdateSourceTrigger
             			lvUsers.ItemsSource = items;
                                                                                       property
                                                                                      Responding to changes
             			CollectionView view =
                                                                                      Value conversion with
             (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.
                                                                                       IValueConverter
                                                                                      The StringFormat property
             			view.Filter = UserFilter;
                                                                                      Debugging data bindings
             		}
             		}
                                                                                     Rich Text controls
             	}
                                                                                                  Introduction
             	          public enum SexType { Male, Female };                                     The
                                                                                                   FlowDocumentScrollViewer
             	          public class User                                                          control
             	{                                                                                   The
             		                     public string Name { get; set; }                               FlowDocumentPageViewer
                                                                                                   control
             		                     public int Age { get; set; }                                  The FlowDocumentReader
                                                                                                   control
             		                     public string Mail { get; set; }                              Creating a FlowDocument
                                                                                                   from Code-behind
             		                     public SexType Sex { get; set; }                              Advanced FlowDocument
             	}                                                                                    content
             }                                                                                    The RichTextBox control
                                                                                                Misc. controls
                                                                                                  The Border control
                                                                                                  The Slider control
                                                                                                  The ProgressBar control
                                                                                                  The WebBrowser control
                                                                                                  The WindowsFormsHost
                                                                                                  control
                                                                                                The TabControl
                                                                                                  Using the TabControl
          
The XAML part is pretty simple: We have a TextBox, where the user can                  Tab positions
           enter a search string, and then a ListView to show the result in.                      Styling the TabItems
          
In Code-behind, we start off by adding some User objects to the ListView,
           just like we did in previous examples. The interesting part happens in the last
                                                                                                List controls
          
two lines of the constructor, where we obtain a reference to the
           CollectionView instance for the ListView and then assign a delegate to
the             The ItemsControl
           Filter property. This delegate points to the function called UserFilter, which         The ListBox control
           we have implemented just below. It
takes each item as the first (and only)             The ComboBox control
           parameter and then returns a boolean value that indicates whether or not the
           given item should be visible on the
list.
                                                                                                The ListView control
          
In the UserFilter() method, we take a look at the TextBox control (txtFilter),         Introduction
           to see if it contains any text - if it does, we use it to
check whether or not the     A simple ListView
           name of the User (which is the property we have decided to filter on) contains         ListView, data binding and
           the entered string, and then return true or false
depending on that. If the             ItemTemplate
           TextBox is empty, we return true, because in that case we want all the items           ListView with a GridView
           to be visible.                                                                         How-to: Left aligned column
                                                                                                   names
          
The txtFilter_TextChanged event is also important. Each time the text
                                                                                                  ListView grouping
           changes, we get a reference to the View object of the ListView and then call
                                                                                                  ListView sorting
           the
Refresh() method on it. This ensures that the Filter delegate is called
                                                                                                  How-to: ListView with
           each time the user changes the value of the search/filter string text box.
                                                                                                   column sorting
          
Summary                                                                             ListView filtering
          
This was a pretty simple implementation, but since you get access to each
           item, in this case of the User class, you can do any sort of custom filtering      The TreeView control
           that you like, since you have access to all of the data about each of the items
                                                                                               Introduction
           in the list. For instance, the above example could easily be changed to
filter
                                                                                               A simple TreeView
           on age, by looking at the Age property instead of the Name property, or you
                                                                                               TreeView, data binding and
           could modify it to look at more than one property, e.g. to filter out
users with
                                                                                                multiple templates
           an age below X AND a name that doesn't contain "Y".
                                                                                               Handling
                                                                                                Selection/Expansion state
                Previous                                                         Next          Lazy loading TreeView items
                                                                                              Styles
                                                                                               Introduction
                                                                                               Using styles
                                                                                               Triggers
                                                                                               Multi triggers
                                                                                               Trigger animations
                                                                                              Misc.
                                                                                               The DispatcherTimer
                                                                   
         
Download
                                                                    PDF!
                                                 
Back to Top
Home Contact Us
                                                                                                  Download as PDF
        TreeView introduction
                                                                                                         Download this entire
                                                                                                         tutorial as PDF right
                                                                                                  now!
          
The TreeView control enabled you to display hierarchical data, with each               About WPF
           piece of data represented by a node in the tree. Each node can then have
                                                                                                   What is WPF?
           child
nodes, and the child nodes can have child nodes and so on. If you have
                                                                                                   WPF vs. WinForms
           ever used the Windows Explorer, you also know how a TreeView looks - it's
           the
control that shows the current folder structure on your machine, in the left
           part of the Windows Explorer window.
                                                                                                  Getting started
          
TreeView in WPF vs. WinForms                                                            Visual Studio Express
                                                                                                   Hello, WPF!
          
If you have previously worked with the TreeView control in WinForms, you
           might think of the TreeView control as one that's easy to use but hard to
           customize. In WPF it's a little bit the other way around, at least for newbies: It
                                                                                                  XAML
           feels a bit complicated to get started with, but it's a LOT easier to
customize.
           Just like most other WPF controls, the TreeView is almost lookless once you             What is XAML?
           start, but it can be styled almost endlessly without much effort.                       Basic XAML
                                                                                                   Events in XAML
          
Just like with the ListView control, the TreeView control does have its own
           item type, the TreeViewItem, which you can use to populate the TreeView. If
           you
come from the WinForms world, you will likely start by generating                  A WPF application
           TreeViewItem's and adding them to the Items property, and this is indeed
                                                                                                   Introduction
           possible. But
since this is WPF, the preferred way is to bind the TreeView to
                                                                                                   The Window
           a hierarchical data structure and then use an appropriate template to render
                                                                                                   Working with App.xaml
           the content.
                                                                                                   Command-line parameters
          
We'll show you how to do it both ways, and while the good, old WinForms                 Resources
           inspired way might seem like the easy choice at first, you should definitely            Handling exceptions
           give
the WPF way a try - in the long run, it offers more flexibility and will fit in
           better with the rest of the WPF code you write.
                                                                                                  Basic controls
          
Summary                                                                                 The TextBlock control
                                                                                                   The TextBlock control - Inline
          
The WPF TreeView is indeed a complex control. In the first example, which
                                                                                                   formatting
           we'll get into already in the next chapter, it might seem simple, but once you
                                                                                                   The Label control
           dig deeper, you'll see the complexity. Fortunately, the WPF TreeView control
                                                                                                   The TextBox control
           rewards you with great usability and flexibility. To show you all of them,
we
                                                                                                   The CheckBox control
           have dedicated an entire category to all the TreeView articles. Click on to the
                Previous                            Next
                                                           Panels
                                                            Introduction to WPF Panels
                                                            The Canvas
          comments powered by Disqus
                                                            The WrapPanel
                                                            The StackPanel
                                                            The DockPanel
                                                            The Grid
                                                            The Grid - Rows & Columns
                                                            The Grid - Units
                                                            The Grid - Spanning
                                                            The Grid - GridSplitter
                                                            Using the Grid: A contact
                                                             form
                                                           Data binding
                                                            Introduction
                                                            Hello, bound world!
                                                            Using the DataContext
                                                            The UpdateSourceTrigger
                                                             property
                                                            Responding to changes
                                                            Value conversion with
                                                             IValueConverter
                                                            The StringFormat property
                                                            Debugging data bindings
                                                           Commands
                                                            Introduction
                                                            Using commands
                                                            Implementing custom
                                                             commands
                                                           Common interface
                                                           controls
                                                            The Menu control
                                                            The ContextMenu
                                                            The ToolBar control
                                                            The StatusBar control
                                                            The Ribbon Control
                                                      Introduction
                                                      The
                                                       FlowDocumentScrollViewer
                                                       control
                                                      The
                                                       FlowDocumentPageViewer
                                                       control
                                                      The FlowDocumentReader
                                                       control
                                                      Creating a FlowDocument
                                                       from Code-behind
                                                      Advanced FlowDocument
                                                       content
                                                      The RichTextBox control
                                                    Misc. controls
                                                      The Border control
                                                      The Slider control
                                                      The ProgressBar control
                                                      The WebBrowser control
                                                      The WindowsFormsHost
                                                      control
                                                    The TabControl
                                                      Using the TabControl
                                                      Tab positions
                                                      Styling the TabItems
                                                    List controls
                                                      The ItemsControl
                                                      The ListBox control
                                                      The ComboBox control
ListView filtering
                                                                                     Styles
                                                                                      Introduction
                                                                                      Using styles
                                                                                      Triggers
                                                                                      Multi triggers
                                                                                      Trigger animations
                                                                                     Misc.
                                                                                      The DispatcherTimer
                                                          
         
Download
                                                           PDF!
                                                    
Back to Top
Home Contact Us
                                                                                        Download as PDF
       A simple TreeView example
                                                                                               Download this entire
                                                                                               tutorial as PDF right
                                                                                        now!
         
As we talked about in the previous article, the WPF TreeView can be used in   About WPF
          a very simple manner, by adding TreeViewItem objects to it, either from
                                                                                         What is WPF?
          Code-behind or simply by declaring them directly in your XAML. This is
                                                                                         WPF vs. WinForms
          indeed very easy to get started with, as you can see from the example here:
            <Window
                                                                                        Getting started
            x:Class="WpfTutorialSamples.TreeView_control.TreeViewSample"
                                                                                         Visual Studio Express
                                                                                         Hello, WPF!
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                        XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                       What is XAML?
                       Title="TreeViewSample" Height="200" Width="250">                  Basic XAML
                 <Grid Margin="10">                                                      Events in XAML
            		<TreeView>
            			<TreeViewItem Header="Level 1"
            IsExpanded="True">
                                                                                        A WPF application
            				<TreeViewItem
                                                                                         Introduction
            Header="Level 2.1" />
                                                                                         The Window
            				<TreeViewItem
                                                                                         Working with App.xaml
            Header="Level 2.2" IsExpanded="True">
                                                                                         Command-line parameters
            					<TreeViewItem
                                                                                         Resources
            Header="Level 3.1" />
                                                                                         Handling exceptions
            					<TreeViewItem
            Header="Level 3.2" />
            				</TreeViewItem>
            				<TreeViewItem                                                           Basic controls
            Header="Level 2.3" />                                                        The TextBlock control
            			</TreeViewItem>                                                           The TextBlock control - Inline
            		</TreeView>                                                                formatting
            	</Grid>                                                                     The Label control
            </Window>                                                                    The TextBox control
                                                                                         The CheckBox control
                                                                                               Panels
                                                                                                Introduction to WPF Panels
                                                                                                The Canvas
                                                                                                The WrapPanel
                                                                                                The StackPanel
                                                                                                The DockPanel
                                                                                                The Grid
                                                                                                The Grid - Rows & Columns
         
We simply declare the TreeViewItem objects directly in the XAML, in the               The Grid - Units
          same structure that we want to display them in, where the first tag is a child        The Grid - Spanning
          of
the TreeView control and its child objects are also child tags to its parent       The Grid - GridSplitter
          object. To specify the text we want displayed for each node, we use                   Using the Grid: A contact
          theHeader property. By default, a TreeViewItem is not expanded, but to                 form
          show you the structure of the example, I have used the IsExpanded property
          to expand the two parent items.
                                                                                               Data binding
         
TreeViewItem's with images and other                                                  Introduction
          controls                                                                              Hello, bound world!
         
The Header is an interesting property, though. As you can see, I can just             Using the DataContext
          specify a text string and then have it rendered directly without
doing anything       The UpdateSourceTrigger
          else, but this is WPF being nice to us - internally, it wraps the text inside of a     property
          TextBlock control, instead of forcing you to do it. This
shows us that we can         Responding to changes
          stuff pretty much whatever we want to into the Header property instead of             Value conversion with
          just a string and then have the TreeView render it - a great
example of why            IValueConverter
          it's so easy to customize the look of WPF controls.                                   The StringFormat property
                                                                                                Debugging data bindings
         
One of the common requests from people coming from WinForms or even
          other UI libraries is the ability to show an image next to the text label of a
          TreeView
item. This is very easy to do with WinForms, because the                    Commands
          TreeView is built exactly for this scenario. With the WPF TreeView, it's a bit
                                                                                                Introduction
          more complex, but
you're rewarded with a lot more flexibility than you could
                                                                                                Using commands
          ever get from the WinForms TreeView. Here's an example of it:
                                                                                                Implementing custom
                                                                                                 commands
            <Window
            x:Class="WpfTutorialSamples.TreeView_control.TreeViewCustomI
                                                                                               Common interface
                                                                                               controls
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                The Menu control
                                                                                                The ContextMenu
                                                                                                The ToolBar control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                The StatusBar control
                       Title="TreeViewCustomItemsSample" Height="200"
                                                                                                The Ribbon Control
            Width="250">
            	          <Grid Margin="10">
            		<TreeView>
            			<TreeViewItem IsExpanded="True">                                                Rich Text controls
            				<TreeViewItem.Header>                                        Introduction
            					<StackPanel                                                 The
            Orientation="Horizontal">                                         FlowDocumentScrollViewer
            						<Image                                                      control
            Source="/WpfTutorialSamples;component/Images/bullet_blue.png     The
             />                                                               FlowDocumentPageViewer
            						<TextBlock                                                  control
             Text="Level 1 (Blue)" />                                        The FlowDocumentReader
            					</StackPanel>                                                control
            				</TreeViewItem.Header>                                       Creating a FlowDocument
            				<TreeViewItem>                                                from Code-behind
            					                                                            Advanced FlowDocument
            <TreeViewItem.Header>                                             content
            						                                                           The RichTextBox control
            <StackPanel Orientation="Horizontal">
            							
            <TextBlock Text="Level 2.1" Foreground="Blue" />               Misc. controls
            						
                                                                             The Border control
            </StackPanel>
                                                                             The Slider control
            					
                                                                             The ProgressBar control
            </TreeViewItem.Header>
                                                                             The WebBrowser control
            				</TreeViewItem>
                                                                             The WindowsFormsHost
            				<TreeViewItem
                                                                             control
            IsExpanded="True">
            					
            <TreeViewItem.Header>
            						
                                                                           The TabControl
            <StackPanel Orientation="Horizontal">                            Using the TabControl
            							                                                          Tab positions
            <Image                                                           Styling the TabItems
            Source="/WpfTutorialSamples;component/Images/bullet_green.pn
             />
            							                                                        List controls
            <TextBlock Text="Level 2.2 (Green)" Foreground="Blue" />
                                                                             The ItemsControl
            						
                                                                             The ListBox control
            </StackPanel>
                                                                             The ComboBox control
            					
            </TreeViewItem.Header>
            					<TreeViewItem>
                                                                           The ListView control
            						
            <TreeViewItem.Header>                                            Introduction
            							                                                          A simple ListView
            <TextBlock Text="Level 3.1" Foreground="Green" />                ListView, data binding and
            						                                                            ItemTemplate
            </TreeViewItem.Header>                                           ListView with a GridView
            					</TreeViewItem>                                             How-to: Left aligned column
            					<TreeViewItem>                                               names
            						                                                           ListView grouping
            <TreeViewItem.Header>                                            ListView sorting
            							                                                          How-to: ListView with
            <TextBlock Text="Level 3.2" Foreground="Green" />                 column sorting
            						                                                                            ListView filtering
            </TreeViewItem.Header>
            					</TreeViewItem>
            				</TreeViewItem>                                                              The TreeView control
            				<TreeViewItem>                                                                Introduction
            					                                                                             A simple TreeView
            <TreeViewItem.Header>                                                             TreeView, data binding and
            						<TextBlock                                                                   multiple templates
             Text="Level 2.3" Foreground="Blue" />                                            Handling
            					                                                                              Selection/Expansion state
            </TreeViewItem.Header>                                                            Lazy loading TreeView items
            				</TreeViewItem>
            			</TreeViewItem>
            		</TreeView>
                                                                                             The DataGrid control
            	</Grid>
                                                                                              Introduction
            </Window>
                                                                                              Custom columns
                                                                                              Details row
                                                                                             Styles
                                                                                              Introduction
                                                                                              Using styles
                                                                                              Triggers
                                                                                              Multi triggers
                                                                                              Trigger animations
                                                                                             Misc.
         
I did a whole bunch of things here, just to show you the kind of flexibility you    The DispatcherTimer
          get: I colored the child items and I added images and even buttons to the
          parent items. Because we're defining the entire thing with simple markup,
          you can do almost anything, but as you can see from the example code, it           Audio & Video
          does
come with a price: Huge amounts of XAML code, for a tree with just six         Playing audio
          nodes in total!                                                                     Playing video
                                                                                              How-to: Complete media
         
Summary                                                                             player
         
While it is entirely possible to define an entire TreeView just using markup, as    Speech synthesis
          we did in the above examples, it's not the best approach in most
situations,        Speech recognition
          and while you could do it from Code-behind instead, this would have resulted
          in even more lines of code. Once again the solution is data binding, which
          we'll look into in the next chapters.
Previous Next
                                                              
         
Download
                                                               PDF!
                                                                                         
Back to Top
Home Contact Us
                                                                                                Download as PDF
        TreeView, data binding and multiple
        templates                                                                                      Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
                                                                                                About WPF
          
The WPF TreeView supports data binding, like pretty much all other WPF
                                                                                                 What is WPF?
           controls does, but because the TreeView is hierarchical in nature, a normal
                                                                                                 WPF vs. WinForms
           DataTemplate often won't suffice. Instead, we use the
           HierarchicalDataTemplate, which allows us to template both the tree node
           itself, while controlling
which property to use as a source for child items of the
           node.                                                                                Getting started
                                                                                                 Visual Studio Express
          
A basic data bound TreeView                                                           Hello, WPF!
          
In the following example, I'll show you just how easy it is to get started with
           the HierarchicalDataTemplate:
                                                                                                XAML
                                                                                                 What is XAML?
             <Window
                                                                                                 Basic XAML
             x:Class="WpfTutorialSamples.TreeView_control.TreeViewDataBin
                                                                                                 Events in XAML
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                A WPF application
                                                                                                 Introduction
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                              The Window
             		xmlns:self="clr-                                                                  Working with App.xaml
             namespace:WpfTutorialSamples.TreeView_control"                                      Command-line parameters
                        Title="TreeViewDataBindingSample" Height="150"                           Resources
             Width="200">                                                                        Handling exceptions
                  <Grid Margin="10">
             		<TreeView Name="trvMenu">
             			<TreeView.ItemTemplate>                                                         Basic controls
             				<HierarchicalDataTemplate
                                                                                                 The TextBlock control
             DataType="{x:Type self:MenuItem}" ItemsSource="{Binding
                                                                                                 The TextBlock control - Inline
             Items}">
                                                                                                 formatting
             					<TextBlock Text="
                                                                                                 The Label control
             {Binding Title}" />
                                                                                                 The TextBox control
             				
                                                                                                 The CheckBox control
             </HierarchicalDataTemplate>
                                                                                             Introduction
                                                                                             The
                                                                                              FlowDocumentScrollViewer
                                                                                              control
                                                                                             The
                                                                                              FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
          
In the XAML markup, I have specified a HierarchicalDataTemplate for the            from Code-behind
           ItemTemplate of the TreeView. I instruct it to use the Items property for         Advanced FlowDocument
           finding child items, by setting the ItemsSource property of the template, and      content
           inside of it I define
the actual template, which for now just consists of a       The RichTextBox control
           TextBlock bound to the Title property.
          
This first example was very simple, in fact so simple that we might as well     Misc. controls
           have just added the TreeView items manually, instead of generating a set of
                                                                                             The Border control
           objects and then binding to them. However, as soon as things get a bit more
                                                                                             The Slider control
           complicated, the advantages of using data bindings gets more obvious.
                                                                                             The ProgressBar control
          
Multiple templates for different types                                            The WebBrowser control
                                                                                             The WindowsFormsHost
          
In the next example, I've taken a slightly more complex case, where I want to     control
           show a tree of families and their members. A family should be represented in
           one way, while each of its members should be shown in another way. I
           achieve this by creating two different templates and specifying them as         The TabControl
           resources of
the tree (or the Window or the Application - that's really up to
                                                                                             Using the TabControl
           you), and then allowing the TreeView to pick the correct template based on
                                                                                             Tab positions
           the underlying
type of data.
                                                                                             Styling the TabItems
          
Here's the code - the explanation of it will follow right after:
                                                                                           List controls
             <Window
             x:Class="WpfTutorialSamples.TreeView_control.TreeViewMultipl                    The ItemsControl
                                                                                             The ListBox control
                                                                                             The ComboBox control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                             ListView filtering
             Orientation="Horizontal">
             						<Image
             Source="/WpfTutorialSamples;component/Images/group.png"
                                                                            The TreeView control
             Margin="0,0,5,0" />
             						<TextBlock                                                Introduction
              Text="{Binding Name}" />                                       A simple TreeView
             						<TextBlock                                                TreeView, data binding and
              Text=" [" Foreground="Blue" />                                  multiple templates
             						<TextBlock                                                Handling
              Text="{Binding Members.Count}" Foreground="Blue" />             Selection/Expansion state
             						<TextBlock                                                Lazy loading TreeView items
              Text="]" Foreground="Blue" />
             					</StackPanel>
             				                                                           The DataGrid control
             </HierarchicalDataTemplate>                                     Introduction
             				<DataTemplate DataType="                                    Custom columns
             {x:Type self:FamilyMember}">                                    Details row
             					<StackPanel
             Orientation="Horizontal">
             						<Image                                                   Styles
             Source="/WpfTutorialSamples;component/Images/user.png"
                                                                             Introduction
             Margin="0,0,5,0" />
                                                                             Using styles
             						<TextBlock
                                                                             Triggers
              Text="{Binding Name}" />
                                                                             Multi triggers
             						<TextBlock
                                                                             Trigger animations
              Text=" (" Foreground="Green" />
             						<TextBlock
              Text="{Binding Age}" Foreground="Green" />
             						<TextBlock                                               Misc.
              Text=" years)" Foreground="Green" />                           The DispatcherTimer
             					</StackPanel>
             				</DataTemplate>
             			</TreeView.Resources>                                       Audio & Video
             		</TreeView>
                                                                             Playing audio
             	</Grid>
                                                                             Playing video
             </Window>
                                                                             How-to: Complete media
                                                                             player
                                                                             Speech synthesis
             using System;                                                   Speech recognition
             using System.Collections.Generic;
             using System.Windows;
             using System.Collections.ObjectModel;
             namespace WpfTutorialSamples.TreeView_control
             {
             	          public partial class
             TreeViewMultipleTemplatesSample : Window
             	{
             		public TreeViewMultipleTemplatesSample()
             		{
InitializeComponent();
             			trvFamilies.ItemsSource =
             families;
             		}
             	}
             		public ObservableCollection<FamilyMember>
             Members { get; set; }
             	}
          
As mentioned, the two templates are declared as a part of the TreeView
           resources, allowing the TreeView to select the appropriate template based on
           the
data type that it's about to show. The template defined for the Family
           type is a hierarchical template, using the Members
property to show its
           family members.
          
The template defined for the FamilyMember type is a regular DataTemplate,
           since this type doesn't have any child members. However, if we
had wanted
           each FamilyMember to keep a collection of their children and perhaps their
           children's children, then we would have used a hierarchical template
instead.
          
In both templates, we use an image representing either a family or a family
           member, and then we show some interesting data about it as well, like the
           amount of family members or the person's age.
          
In the code-behind, we simply create two Family instances, fill each of them
           with a set of members, and then add each of the families to a list, which is
           then used as the items source for the TreeView.
          
Summary
          
Using data binding, the TreeView is very customizable and with the ability to
           specify multiple templates for rendering different data types, the
possibilities
           are almost endless.
Previous Next
                                                                        
         
Download
                                                                            PDF!
                                                                            
Back to Top
Home Contact Us
                                                                                              Download as PDF
        TreeView - Selection/Expansion state
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          
In the previous couple of TreeView articles, we used data binding to display       About WPF
           custom objects in a WPF TreeView. This works really well, but it does leave
                                                                                               What is WPF?
           you with one problem: Because each tree node is now represented by your
                                                                                               WPF vs. WinForms
           custom class, for instance FamilyMember as we saw in the previous article,
           you no
longer have direct control over TreeView node specific functionality
           like selection and expansion state. In praxis this means that you can't select
           or
expand/collapse a given node from code-behind.                                  Getting started
                                                                                               Visual Studio Express
          
Lots of solutions exists to handle this, ranging from "hacks" where you use         Hello, WPF!
           the item generators of the TreeView to get the underlying TreeViewItem,
           where
you can control the IsExpanded and IsSelected properties, to much
           more advanced MVVM-inspired implementations. In this article I would like to
                                                                                              XAML
           show you a
solution that lies somewhere in the middle, making it easy to
                                                                                               What is XAML?
           implement and use, while still not being a complete hack.
                                                                                               Basic XAML
          
A TreeView selection/expansion solution                                             Events in XAML
          
The basic principle is to implement two extra properties on your data class:
           IsExpanded and IsSelected. These two properties are then hooked up to the          A WPF application
           TreeView, using a couple of styles targeting the TreeViewItem, inside of the
                                                                                               Introduction
           ItemContainerStyle for the TreeView.
                                                                                               The Window
          
You could easily implement these two properties on all of your objects, but         Working with App.xaml
           it's much easier to inherit them from a base object. If this is not feasible
for    Command-line parameters
           your solution, you could create an interface for it and then implement this         Resources
           instead, to establish a common ground. For this example, I've chosen the            Handling exceptions
           base class method, because it allows me to very easily get the same
           functionality for my other objects. Here's the code:
                                                                                              Basic controls
             <Window                                                                           The TextBlock control
             x:Class="WpfTutorialSamples.TreeView_control.TreeViewSelecti                      The TextBlock control - Inline
                                                                                               formatting
                                                                                               The Label control
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The TextBox control
                                                                                               The CheckBox control
                                                                                   Introduction
             namespace WpfTutorialSamples.TreeView_control
                                                                                   The
             {
                                                                                    FlowDocumentScrollViewer
             	          public partial class
                                                                                    control
             TreeViewSelectionExpansionSample : Window
                                                                                   The
             	{
                                                                                    FlowDocumentPageViewer
             		public TreeViewSelectionExpansionSample()
                                                                                    control
             		{
                                                                                   The FlowDocumentReader
             			InitializeComponent();
                                                                                    control
                                                                                   Creating a FlowDocument
             			                               List<Person> persons = new
                                                                                    from Code-behind
             List<Person>();
                                                                                   Advanced FlowDocument
             			                               Person person1 = new Person() {
                                                                                    content
             Name = "John Doe", Age = 42 };
                                                                                   The RichTextBox control
                                                                                 List controls
             			person2.IsExpanded = true;
                                                                                   The ItemsControl
             			person2.IsSelected = true;
                                                                                   The ListBox control
                                                                                   The ComboBox control
             			trvPersons.ItemsSource = persons;
             		}
             	}                                                                  Styles
                                                                                  Introduction
             	          public class Person : TreeViewItemBase
                                                                                  Using styles
             	{
                                                                                  Triggers
             		public Person()
                                                                                  Multi triggers
             		{
                                                                                  Trigger animations
             			this.Children = new
             ObservableCollection<Person>();
             		}
                                                                                 Misc.
             		                    public string Name { get; set; }               The DispatcherTimer
             value;
             					
             NotifyPropertyChanged("IsSelected");
             				}
             			}
             		}
          
I'm sorry for the rather large amount of code in one place. In a real world
          solution, it would obviously be spread out over multiple files instead and the
          data for the tree would likely come from an actual data source, instead of
          being generated on the fly. Allow me to explain what happens in the
          example.
          
XAML part
          
I have defined a couple of buttons to be placed in the bottom of the dialog, to
           use the two new properties. Then we have the TreeView, for which I have
           defined an ItemTemplate (as demonstrated in a previous chapter) as well as
           an ItemContainerStyle. If you haven't read the chapters on styling yet, you
          
might not completely understand that part, but it's simply a matter of tying
           together the properties on our own custom class with the IsSelected and
           IsExpanded properties on the TreeViewItems, which is done with Style
           setters. You can learn more about
them elsewhere in this tutorial.
          
Code-behind part
          
In the code-behind, I have defined a Person class, with a couple of
           properties, which inherits our extra properties from the TreeViewItemBase
           class. You should be aware that the TreeViewItemBase class implements the
           INotifyPropertyChanged interface and uses it to
notify of changes to these
           two essential properties - without this, selection/expansion changes won't be
           reflected in the UI. The concept of notification
changes are explained in the
           Data binding chapters.
          
In the main Window class I simply create a range of persons, while adding
           children to some of them. I add the persons to a list, which I assign as the
           ItemsSource of the TreeView, which, with a bit of help from the defined
           template, renders them the way they are shown on the screenshot.
          
The most interesting part happens when I set the IsExpanded and IsSelected
           properties on the person2 object. This is what causes the second person
           (Jane Doe) to be initially selected and expanded, as shown on the
           screenshot. We also use these two properties on the Person objects
           (inherited from the
TreeViewItemBase class) in the event handlers for the two
           test buttons (please bear in mind that, to keep the code as small and simple
           as possible, the
selection button only works for the top level items).
          
Summary
          
By creating and implementing a base class for the objects that you wish to
           use and manipulate within a TreeView, and using the gained properties in the
          
ItemContainerStyle, you make it a lot easier to work with selections and
           expansion states. There are many solutions to tackle this problem with, and
           while
this should do the trick, you might be able to find a solution that fits your
           needs better. As always with programming, it's all about using the right tool
           for the job at hand.
Previous Next
                                                                         
         
Download
                                                                          PDF!
                                                                                                    
Back to Top
Home Contact Us
                                                                                              Download as PDF
        Lazy loading TreeView items
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          
The usual process when using the TreeView is to bind to a collection of items      About WPF
           or to manually add each level at the same time. However, in some situations,
                                                                                               What is WPF?
          
you want to delay the loading of a nodes child items until they are actually
                                                                                               WPF vs. WinForms
           needed. This is especially useful if you have a very deep tree, with lots of
           levels and child nodes and a great example of this, is the folder structure of
           your Windows computer.
                                                                                              Getting started
          
Each drive on your Windows computer has a range of child folders, and each          Visual Studio Express
           of those child folders have child folders beneath them and so on. Looping           Hello, WPF!
           through each drive and each drives child folders could become extremely
           time consuming and your TreeView would soon consist of a lot of nodes, with
           a high
percentage of them never being needed. This is the perfect task for a
                                                                                              XAML
           lazy-loaded TreeView, where child folders are only loaded on demand.
                                                                                               What is XAML?
          
To achieve this, we simply add a dummy folder to each drive or child folder,        Basic XAML
           and then when the user expands it, we remove the dummy folder and replace           Events in XAML
           it
with the actual values. This is how our application looks when it starts - by
           that time, we have only obtained a list of available drives on the computer:
                                                                                              A WPF application
                                                                                               Introduction
                                                                                               The Window
                                                                                               Working with App.xaml
                                                                                               Command-line parameters
                                                                                               Resources
                                                                                               Handling exceptions
                                                                                              Basic controls
                                                                                               The TextBlock control
                                                                                               The TextBlock control - Inline
                                                                                               formatting
                                                                                               The Label control
                                                                                               The TextBox control
                                                                                               The CheckBox control
          
You can now start expanding the nodes, and the application will                  The RadioButton control
           automatically load the sub folders. If a folder is empty, it will be shown as    The PasswordBox control
           empty once
you try to expand it, as it can be seen on the next screenshot:
                                                                                           Panels
                                                                                            Introduction to WPF Panels
                                                                                            The Canvas
                                                                                            The WrapPanel
                                                                                            The StackPanel
                                                                                            The DockPanel
                                                                                            The Grid
                                                                                            The Grid - Rows & Columns
                                                                                            The Grid - Units
                                                                                            The Grid - Spanning
                                                                                            The Grid - GridSplitter
                                                                                            Using the Grid: A contact
                                                                                             form
          
So how is it accomplished? Let's have a look at the code:                       Data binding
                                                                                            Introduction
            <Window                                                                         Hello, bound world!
            x:Class="WpfTutorialSamples.TreeView_control.LazyLoadingSamp                    Using the DataContext
                                                                                            The UpdateSourceTrigger
                                                                                             property
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Responding to changes
                                                                                            Value conversion with
                                                                                             IValueConverter
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          The StringFormat property
                       Title="LazyLoadingSample" Height="300"                               Debugging data bindings
            Width="300">
                  <Grid>
                       <TreeView Name="trvStructure"                                       Commands
            TreeViewItem.Expanded="TreeViewItem_Expanded" Margin="10"
                                                                                            Introduction
            />
                                                                                            Using commands
                  </Grid>
                                                                                            Implementing custom
            </Window>
                                                                                             commands
            			InitializeComponent();                                             Introduction
            			DriveInfo[] drives =                                               The
            DriveInfo.GetDrives();                                                 FlowDocumentScrollViewer
            			foreach(DriveInfo driveInfo in                                      control
            drives)                                                               The
            				                                                                   FlowDocumentPageViewer
            trvStructure.Items.Add(CreateTreeItem(driveInfo));                     control
            		}                                                                   The FlowDocumentReader
                                                                                   control
            		                     public void TreeViewItem_Expanded(object       Creating a FlowDocument
            sender, RoutedEventArgs e)                                             from Code-behind
            		{                                                                   Advanced FlowDocument
            			                               TreeViewItem item = e.Source as      content
            TreeViewItem;                                                         The RichTextBox control
            			                               if((item.Items.Count == 1) &&
            (item.Items[0] is string))
            			{                                                                Misc. controls
            				item.Items.Clear();                                               The Border control
                                                                                  The Slider control
            				DirectoryInfo expandedDir                                         The ProgressBar control
            = null;                                                               The WebBrowser control
            				if(item.Tag is DriveInfo)                                         The WindowsFormsHost
            					expandedDir =                                                    control
            (item.Tag as DriveInfo).RootDirectory;
            				if(item.Tag is
            DirectoryInfo)                                                      The TabControl
            					expandedDir =
                                                                                  Using the TabControl
            (item.Tag as DirectoryInfo);
                                                                                  Tab positions
            				try
                                                                                  Styling the TabItems
            				{
            					
            foreach(DirectoryInfo subDir in
            expandedDir.GetDirectories())                                       List controls
            						                                                                The ItemsControl
            item.Items.Add(CreateTreeItem(subDir));                               The ListBox control
            				}                                                                 The ComboBox control
            				catch { }
            			}
            		}                                                                 The ListView control
                                                                                  Introduction
            		                     private TreeViewItem CreateTreeItem(object
                                                                                  A simple ListView
              o)
                                                                                  ListView, data binding and
            		{
                                                                                   ItemTemplate
            			                               TreeViewItem item = new
                                                                                  ListView with a GridView
            TreeViewItem();
                                                                                  How-to: Left aligned column
            			item.Header = o.ToString();
                                                                                   names
            			item.Tag = o;
                                                                                  ListView grouping
            			item.Items.Add("Loading...");
                                                                                  ListView sorting
            			return item;
                                                                                  How-to: ListView with
            		}
                                                                                   column sorting
            	}
                                                                                                ListView filtering
            }
          
The XAML is very simple and only one interesting detail is present: The way         The TreeView control
           we subscribe to the Expanded event of TreeViewItem's. Notice
that this is
                                                                                                Introduction
           indeed the TreeViewItem and not the TreeView itself, but because the event
                                                                                                A simple TreeView
           bubbles up, we are able to just capture it in one place for the
entire
                                                                                                TreeView, data binding and
           TreeView, instead of having to subscribe to it for each item we add to the
                                                                                                 multiple templates
           tree. This event gets called each time an item is expanded, which we need
to
                                                                                                Handling
           be aware of to load its child items on demand.
                                                                                                 Selection/Expansion state
          
In Code-behind, we start by adding each drive found on the computer to the           Lazy loading TreeView items
           TreeView control. We assign the DriveInfo
instance to the Tag property, so
           that we can later retrieve it. Notice that we use a custom method to create
           the TreeViewItem, called CreateTreeItem(), since we can use the exact               The DataGrid control
           same method when we want to dynamically add a child folder later on. Notice          Introduction
           in this method
how we add a child item to the Items collection, in the form of       Custom columns
           a string with the text "Loading...".                                                 Details row
          
Next up is the TreeViewItem_Expanded event. As already mentioned, this
           event is raised each time a TreeView item is expanded, so the first thing we
                                                                                               Styles
           do is
to check whether this item has already been loaded, by checking if the
           child items currently consists of only one item, which is a string - if so, we       Introduction
           have
found the "Loading..." child item, which means that we should now load          Using styles
           the actual contents and replace the placeholder item with it.                        Triggers
                                                                                                Multi triggers
          
We now use the items Tag property to get a reference to the DriveInfo or             Trigger animations
           DirectoryInfo instance that the current item
represents, and then we get a
           list of child directories, which we add to the clicked item, once again using the
           CreateTreeItem() method.
Notice that the loop where we add each child               Misc.
           folder is in a try..catch block - this is important, because some paths might
                                                                                                The DispatcherTimer
           not be accessible, usually for
security reasons. You could grab the exception
           and use it to reflect this in the interface in one way or another.
                                                          
   
Download
                                                           PDF!
                                                                          
Back to Top
Home Contact Us
                                                                                             Download as PDF
        The DataGrid control
                                                                                                    Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
          
The DataGrid control looks a lot like the ListView, when using a GridView, but    About WPF
           it offers a lot of additional functionality. For instance, the DataGrid can
                                                                                              What is WPF?
           automatically generate columns, depending on the data you feed it with. The
                                                                                              WPF vs. WinForms
           DataGrid is also editable by default, allowing the end-user to change the
           values of the underlying data source.
          
The most common usage for the DataGrid is in combination with a database,         Getting started
           but like most WPF controls, it works just as well with an in-memory source,        Visual Studio Express
           like
a list of objects. Since it's a lot easier to demonstrate, we'll mostly be    Hello, WPF!
           using the latter approach in this tutorial.
          
A simple DataGrid                                                                 XAML
          
You can start using the DataGrid without setting any properties, because it        What is XAML?
           supports so much out of the box. In this first example, we'll do just that, and    Basic XAML
           then assign a list of our own User objects as the items source:                    Events in XAML
            <Window
            x:Class="WpfTutorialSamples.DataGrid_control.SimpleDataGridS                     A WPF application
                                                                                              Introduction
                                                                                              The Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Handling exceptions
                        Title="SimpleDataGridSample" Height="180"
            Width="300">
                  <Grid Margin="10">
                                                                                             Basic controls
            		<DataGrid Name="dgSimple"></DataGrid>
            	</Grid>                                                                          The TextBlock control
            </Window>                                                                         The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
            using System;                                                                     The CheckBox control
            namespace WpfTutorialSamples.DataGrid_control
            {                                                                              Panels
            	           public partial class SimpleDataGridSample : Window
                                                                                            Introduction to WPF Panels
            	{
                                                                                            The Canvas
            		public SimpleDataGridSample()
                                                                                            The WrapPanel
            		{
                                                                                            The StackPanel
            			InitializeComponent();
                                                                                            The DockPanel
                                                                                            The Grid
            			                               List<User> users = new List<User>
                                                                                            The Grid - Rows & Columns
            ();
                                                                                            The Grid - Units
            			                               users.Add(new User() { Id = 1,
                                                                                            The Grid - Spanning
            Name = "John Doe", Birthday = new DateTime(1971, 7, 23)
                                                                                            The Grid - GridSplitter
            });
                                                                                            Using the Grid: A contact
            			                               users.Add(new User() { Id = 2,
                                                                                             form
            Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17)
            });
            			                               users.Add(new User() { Id = 3,
            Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2)
                                                                                           Data binding
            });                                                                             Introduction
                                                                                            Hello, bound world!
            			dgSimple.ItemsSource = users;                                                Using the DataContext
            		}                                                                             The UpdateSourceTrigger
            	}                                                                               property
                                                                                            Responding to changes
            	           public class User                                                   Value conversion with
            	{                                                                               IValueConverter
            		                     public int Id { get; set; }                              The StringFormat property
                                                                                            Debugging data bindings
            		                     public string Name { get; set; }
                                                                                           Common interface
                                                                                           controls
                                                                                            The Menu control
                                                                                            The ContextMenu
                                                                                            The ToolBar control
                                                                                            The StatusBar control
                                                                                            The Ribbon Control
          
That's really all you need to start using the DataGrid. The source could just
           as easily have been a database table/view or even an XML file - the DataGrid    Rich Text controls
          
is not picky about where it gets its data from.
                                                                                                 Introduction
          
If you click inside one of the cells, you can see that you're allowed to edit         The
           each of the properties by default. As a nice little bonus, you can try
clicking        FlowDocumentScrollViewer
           one of the column headers - you will see that the DataGrid supports sorting            control
           right out of the box!                                                                 The
                                                                                                  FlowDocumentPageViewer
          
The last and empty row will let you add to the data source, simply by filling          control
           out the cells.                                                                        The FlowDocumentReader
                                                                                                  control
          
Summary                                                                               Creating a FlowDocument
                                                                                                  from Code-behind
          
As you can see, it's extremely easy to get started with the DataGrid, but it's
                                                                                                 Advanced FlowDocument
           also a highly customizable control. In the next chapters, we'll look into
all the
                                                                                                  content
           cool stuff you can do with the DataGrid, so read on.
                                                                                                 The RichTextBox control
                Previous                                                       Next
                                                                                               Misc. controls
                                                                                                 The Border control
                                                                                                 The Slider control
          comments powered by Disqus                                                             The ProgressBar control
                                                                                                 The WebBrowser control
                                                                                                 The WindowsFormsHost
                                                                                                 control
                                                                                               The TabControl
                                                                                                 Using the TabControl
                                                                                                 Tab positions
                                                                                                 Styling the TabItems
                                                                                               List controls
                                                                                                 The ItemsControl
                                                                                                 The ListBox control
                                                                                                 The ComboBox control
ListView filtering
                                                                                    Styles
                                                                                     Introduction
                                                                                     Using styles
                                                                                     Triggers
                                                                                     Multi triggers
                                                                                     Trigger animations
                                                                                    Misc.
                                                                                     The DispatcherTimer
                                                         
         
Download
                                                          PDF!
                                                   
Back to Top
Home Contact Us
                                                                                            Download as PDF
       DataGrid columns
                                                                                                   Download this entire
                                                                                                   tutorial as PDF right
                                                                                            now!
         
In the previous chapter, we had a look at just how easy you could get a WPF       About WPF
          DataGrid up and running. One of the reasons why it was so easy is the fact
                                                                                             What is WPF?
          that
the DataGrid will automatically generate appropriate columns for you,
                                                                                             WPF vs. WinForms
          based on the data source you use.
         
However, in some situations you might want to manually define the columns
          shown, either because you don’t want all the properties/columns of the data       Getting started
          source, or because you want to be in control of which inline editors are used.     Visual Studio Express
                                                                                             Hello, WPF!
         
Manually defined columns
         
Let's try an example that looks a lot like the one in the previous chapter, but
          where we define all the columns manually, for maximum control. You can            XAML
          select the column type based on the data that you wish to display/edit. As of      What is XAML?
          writing, the following column types are available:                                 Basic XAML
                                                                                             Events in XAML
             DataGridTextColumn
             DataGridCheckBoxColumn
             DataGridComboBoxColumn
                                                                                            A WPF application
             DataGridHyperlinkColumn
             DataGridTemplateColumn                                                          Introduction
                                                                                             The Window
         
Especially the last one, the DataGridTemplateColumn, is interesting. It allows     Working with App.xaml
          you to define any kind of content, which opens up the opportunity to use           Command-line parameters
          custom controls, either from the WPF library or even your own or 3rd party         Resources
          controls. Here's an example:                                                       Handling exceptions
            <Window
            x:Class="WpfTutorialSamples.DataGrid_control.DataGridColumns                    Basic controls
                                                                                             The TextBlock control
                                                                                             The TextBlock control - Inline
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     formatting
                                                                                             The Label control
                                                                                             The TextBox control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           The CheckBox control
            using System;
            using System.Collections.Generic;
                                                                                   Commands
            using System.Windows;
                                                                                    Introduction
            namespace WpfTutorialSamples.DataGrid_control                           Using commands
            {                                                                       Implementing custom
            	          public partial class DataGridColumnsSample :                  commands
            Window
            	{
            		public DataGridColumnsSample()                                       Common interface
            		{                                                                    controls
            			InitializeComponent();                                               The Menu control
                                                                                    The ContextMenu
            			                                List<User> users = new List<User>    The ToolBar control
            ();                                                                     The StatusBar control
            			                                users.Add(new User() { Id = 1,       The Ribbon Control
            Name = "John Doe", Birthday = new DateTime(1971, 7, 23)
            });
            			                                users.Add(new User() { Id = 2,
                                                                                   Rich Text controls
                                                                                               The TabControl
                                                                                                 Using the TabControl
                                                                                                 Tab positions
                                                                                                 Styling the TabItems
                                                                                               List controls
                                                                                                 The ItemsControl
                                                                                                 The ListBox control
                                                                                                 The ComboBox control
         
In the markup, I have added the AutoGenerateColumns property on the
          DataGrid, which I have set to false, to get control of the columns used. As
          you can
see, I have left out the ID column, as I decided that I didn't care for it
          for this example. For the Name property, I've used a simple text based               The ListView control
          column,
so the most interesting part of this example comes with the Birthday           Introduction
          column, where I've used a DataGridTemplateColumn with a DatePicker                     A simple ListView
          control inside of
it. This allows the end-user to pick the date from a calendar,       ListView, data binding and
          instead of having to manually enter it, as you can see on the screenshot.               ItemTemplate
                                                                                                 ListView with a GridView
         
Summary                                                                                How-to: Left aligned column
                                                                                                  names
         
By turning off automatically generated columns using the
                                                                                                 ListView grouping
          AutoGenerateColumns property, you get full control of which columns are
                                                                                                 ListView sorting
          shown and how their data
should be viewed and edited. As seen by the
                                                                                                 How-to: ListView with
          example of this article, this opens up for some pretty interesting possibilities,
                                                                                                  column sorting
                                                                                        Styles
                                                                                         Introduction
                                                                                         Using styles
                                                                                         Triggers
                                                                                         Multi triggers
                                                                                         Trigger animations
                                                                                        Misc.
                                                                                         The DispatcherTimer
                                                             
         
Download
                                                              PDF!
                                               
Back to Top
Home Contact Us
                                                                                              Download as PDF
        DataGrid with row details
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          
A very common usage scenario when using a DataGrid control is the ability          About WPF
           to show details about each row, typically right below the row itself. The WPF
                                                                                               What is WPF?
           DataGrid control supports this very well, and fortunately it's also very easy to
                                                                                               WPF vs. WinForms
           use. Let's start off with an example and then we'll discuss how it works
and
           the options it gives you afterwards:
                                                                                              Getting started
             <Window
             x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetails                      Visual Studio Express
                                                                                               Hello, WPF!
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                              XAML
                                                                                               What is XAML?
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                            Basic XAML
                        Title="DataGridDetailsSample" Height="200"                             Events in XAML
             Width="400">
             	          <Grid Margin="10">
             		<DataGrid Name="dgUsers"
                                                                                              A WPF application
             AutoGenerateColumns="False">
                                                                                               Introduction
             			<DataGrid.Columns>
                                                                                               The Window
             				<DataGridTextColumn
                                                                                               Working with App.xaml
             Header="Name" Binding="{Binding Name}" />
                                                                                               Command-line parameters
             				<DataGridTextColumn
                                                                                               Resources
             Header="Birthday" Binding="{Binding Birthday}" />
                                                                                               Handling exceptions
             			</DataGrid.Columns>
             			<DataGrid.RowDetailsTemplate>
             				<DataTemplate>
             					<TextBlock Text="                                                           Basic controls
             {Binding Details}" Margin="10" />                                                 The TextBlock control
             				</DataTemplate>                                                               The TextBlock control - Inline
             			</DataGrid.RowDetailsTemplate>                                                 formatting
             		</DataGrid>                                                                     The Label control
             	</Grid>                                                                          The TextBox control
             </Window>                                                                         The CheckBox control
             using System;
             using System.Collections.Generic;
                                                                                   Panels
             using System.Windows;
                                                                                    Introduction to WPF Panels
             namespace WpfTutorialSamples.DataGrid_control                          The Canvas
             {                                                                      The WrapPanel
             	          public partial class DataGridDetailsSample :                The StackPanel
             Window                                                                 The DockPanel
             	{                                                                     The Grid
             		public DataGridDetailsSample()                                       The Grid - Rows & Columns
             		{                                                                    The Grid - Units
             			InitializeComponent();                                              The Grid - Spanning
             			                               List<User> users = new List<User>    The Grid - GridSplitter
             ();                                                                    Using the Grid: A contact
             			                               users.Add(new User() { Id = 1,        form
             Name = "John Doe", Birthday = new DateTime(1971, 7, 23)
             });
             			                               users.Add(new User() { Id = 2,      Data binding
             Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17)                Introduction
             });                                                                    Hello, bound world!
             			                               users.Add(new User() { Id = 3,       Using the DataContext
             Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2)                The UpdateSourceTrigger
             });                                                                     property
                                                                                    Responding to changes
             			dgUsers.ItemsSource = users;                                        Value conversion with
             		}                                                                     IValueConverter
             	}                                                                     The StringFormat property
                                                                                    Debugging data bindings
             	          public class User
             	{
             		                     public int Id { get; set; }
                                                                                   Commands
             		                     public string Name { get; set; }                Introduction
                                                                                    Using commands
             		                     public DateTime Birthday { get; set; }          Implementing custom
                                                                                     commands
             		                     public string Details
             		{
             			get                                                                Common interface
             			{                                                                  controls
             				return String.Format("{0}                                          The Menu control
             was born on {1} and this is a long description of the                  The ContextMenu
             person.", this.Name, this.Birthday.ToLongDateString());                The ToolBar control
             			}                                                                   The StatusBar control
             		}                                                                    The Ribbon Control
             	}
             }
                                                                                                   Introduction
                                                                                                   The
                                                                                                    FlowDocumentScrollViewer
                                                                                                    control
                                                                                                   The
                                                                                                    FlowDocumentPageViewer
                                                                                                    control
                                                                                                   The FlowDocumentReader
                                                                                                    control
                                                                                                   Creating a FlowDocument
                                                                                                    from Code-behind
                                                                                                   Advanced FlowDocument
                                                                                                    content
          
As you can see, I have expanded the example from previous chapters with a
                                                                                                   The RichTextBox control
           new property on the User class: The Description property. It simply returns a
           bit
of information about the user in question, for our details row.
          
In the markup, I have defined a couple of columns and then I use the                  Misc. controls
           RowDetailsTemplate to specify a template for the row details. As you
can                The Border control
           see, it works much like any other WPF template, where I use a DataTemplate              The Slider control
           with one or several controls inside of it, along with a standard binding
against        The ProgressBar control
           a property on the data source, in this case the Description property.                   The WebBrowser control
                                                                                                   The WindowsFormsHost
          
As you can see from the resulting screenshot, or if you run the sample
                                                                                                   control
           yourself, the details are now shown below the selected row. As soon as you
           select
another row, the details for that row will be shown and the details for
           the previously selected row will be hidden.
                                                                                                 The TabControl
          
Controlling row details visibility                                                      Using the TabControl
                                                                                                   Tab positions
          
Using the RowDetailsVisibilityMode property, you can change the above                   Styling the TabItems
           mentioned behavior though. It defaults toVisibleWhenSelected, where
           details are only visible when its parent row is selected, but you can change it
           to Visible or Collapsed. If you set it to Visible, all details rows will be visible
                                                                                                 List controls
           all the time, like this:
                                                                                                   The ItemsControl
                                                                                                   The ListBox control
                                                                                                   The ComboBox control
          
If you set it to Collapsed, all details will be invisible all the time.           ListView filtering
          
More details
          
The first example of this article might have been a tad boring, using just a     The TreeView control
           single, plain TextBlock control. Of course, with this being a DataTemplate,       Introduction
           you can do pretty much whatever you want, so I decided to extend the              A simple TreeView
           example a bit, to give a better idea of the possibilities. Here's how it looks    TreeView, data binding and
           now:                                                                               multiple templates
                                                                                             Handling
                                                                                              Selection/Expansion state
                                                                                             Lazy loading TreeView items
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
          
As you can see from the code listing, it's mostly about expanding the details     Triggers
           template into using a panel, which in turn can host more panels and/or            Multi triggers
           controls. Using a Grid panel, we can get the tabular look of the user data,       Trigger animations
           and an Image control allows us to show a picture of the user (which you
           should
preferably load from a locale resource and not a remote one, like I do
           in the example - and sorry for being too lazy to find a matching image of Jane   Misc.
           and
Sammy Doe).
                                                                                             The DispatcherTimer
             <Window
             x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetails
                                                                                            Audio & Video
                                                                                             Playing audio
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Playing video
                                                                                             How-to: Complete media
                                                                                             player
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          Speech synthesis
                        Title="DataGridDetailsSample" Height="300"                           Speech recognition
             Width="300">
             	          <Grid Margin="10">
             		<DataGrid Name="dgUsers"
             AutoGenerateColumns="False">
             			<DataGrid.Columns>
             				<DataGridTextColumn
             Header="Name" Binding="{Binding Name}" />
             				<DataGridTextColumn
             Header="Birthday" Binding="{Binding Birthday}" />
             			</DataGrid.Columns>
             			<DataGrid.RowDetailsTemplate>
             				<DataTemplate>
             					<DockPanel
             Background="GhostWhite">
             						<Image
             DockPanel.Dock="Left" Source="{Binding ImageUrl}"
             Height="64" Margin="10" />
             						<Grid
             Margin="0,10">
             							
             <Grid.ColumnDefinitions>
             							
             	          <ColumnDefinition Width="Auto" />
             							
             	          <ColumnDefinition Width="*" />
             							
             </Grid.ColumnDefinitions>
             							
             <Grid.RowDefinitions>
             							
             	          <RowDefinition Height="Auto" />
             							
             	          <RowDefinition Height="Auto" />
             							
             	          <RowDefinition Height="Auto" />
             							
             </Grid.RowDefinitions>
             							
             <TextBlock Text="ID: " FontWeight="Bold" />
             							
             <TextBlock Text="{Binding Id}" Grid.Column="1" />
             							
             <TextBlock Text="Name: " FontWeight="Bold" Grid.Row="1" />
             							
             <TextBlock Text="{Binding Name}" Grid.Column="1"
             Grid.Row="1" />
             							
             <TextBlock Text="Birthday: " FontWeight="Bold"
             Grid.Row="2" />
             							
             <TextBlock Text="{Binding Birthday, StringFormat=d}"
             Grid.Column="1" Grid.Row="2" />
             						</Grid>
             					</DockPanel>
             				</DataTemplate>
             			</DataGrid.RowDetailsTemplate>
             		</DataGrid>
             	</Grid>
             </Window>
             using System;
             using System.Collections.Generic;
             using System.Windows;
             namespace WpfTutorialSamples.DataGrid_control
             {
             	          public partial class DataGridDetailsSample :
             Window
             	{
             		public DataGridDetailsSample()
             		{
             			InitializeComponent();
             			                               List<User> users = new List<User>
             ();
             			                               users.Add(new User() { Id = 1,
             Name = "John Doe", Birthday = new DateTime(1971, 7, 23),
             ImageUrl = "http://www.wpf-
             tutorial.com/images/misc/john_doe.jpg" });
             			                               users.Add(new User() { Id = 2,
             Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17)
             });
             			                               users.Add(new User() { Id = 3,
             Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2)
             });
             			dgUsers.ItemsSource = users;
             		}
             	}
          
Summary
          
Being able to show details for a DataGrid row is extremely useful, and with
           the WPF DataGrid it's both easy and highly customizable, as you can see
           from
the examples provided in this tutorial.
Previous Next
                                                              
         
Download
                                                               PDF!
                                                                                         
Back to Top
Home Contact Us
                                                                                                Download as PDF
        Introduction to WPF styles
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          
If you come from the world of developing for the web, using HTML and CSS,            About WPF
           you'll quickly realize that XAML is much like HTML: Using tags, you define a
                                                                                                 What is WPF?
           structural layout of your application. You can even make your elements look
                                                                                                 WPF vs. WinForms
           a certain way, using inline properties like Foreground, FontSize and so on,
           just like you can locally style your HTML tags.
          
But what happens when you want to use the exact same font size and color             Getting started
           on three different TextBlock controls? You can copy/paste the desired                 Visual Studio Express
           properties
to each of them, but what happens when three controls becomes              Hello, WPF!
           50 controls, spread out over several windows? And what happens when you
           realize that the font
size should be 14 instead of 12?
                                                                                                XAML
          
WPF introduces styling, which is to XAML what CSS is to HTML. Using
           styles, you can group a set of properties and assign them to specific controls        What is XAML?
           or all
controls of a specific type, and just like in CSS, a style can inherit from    Basic XAML
           another style.                                                                        Events in XAML
          
Basic style example
                                                                                                A WPF application
          
We'll talk much more about all the details, but for this introduction chapter, I
           want to show you a very basic example on how to use styling:                          Introduction
                                                                                                 The Window
                                                                                                 Working with App.xaml
             <Window
                                                                                                 Command-line parameters
             x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
                                                                                                 Resources
                                                                                                 Handling exceptions
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                Basic controls
                        Title="SimpleStyleSample" Height="200"                                   The TextBlock control
             Width="250">                                                                        The TextBlock control - Inline
                  <StackPanel Margin="10">                                                       formatting
                        <StackPanel.Resources>                                                   The Label control
                              <Style TargetType="TextBlock">                                     The TextBox control
                                    <Setter Property="Foreground" Value="Gray"                   The CheckBox control
                                                                                               Data binding
                                                                                                Introduction
                                                                                                Hello, bound world!
          
For the resources of my StackPanel, I define a Style. I use the TargetType           Using the DataContext
           property to tell WPF that this style should be applied towards
ALL TextBlock         The UpdateSourceTrigger
           controls within the scope (the StackPanel), and then I add two Setter                 property
           elements to the style. The Setter elements are used to set specific
properties       Responding to changes
           for the target controls, in this case Foreground and FontSize properties.            Value conversion with
           The Property
property tells WPF which property we want to target, and the             IValueConverter
           Value property defines the desired value.                                            The StringFormat property
                                                                                                Debugging data bindings
          
Notice that the last TextBlock is blue instead of gray. I did that to show you
           that while a control might get styling from a designated style, you are
           completely free to override this locally on the control - values defined directly
                                                                                               Commands
           on the control will always take precedence over style values.
                                                                                                Introduction
          
Summary                                                                              Using commands
                                                                                                Implementing custom
          
WPF styles make it very easy to create a specific look and then use it for            commands
           several controls, and while this first example was very local, I will show you
           how to create global styles in the next chapters.
                                                                                               Common interface
                Previous                                                       Next            controls
                                                                                                The Menu control
                                                                                                The ContextMenu
                                                                                                The ToolBar control
          comments powered by Disqus                                                            The StatusBar control
                                                                                                The Ribbon Control
                                                           Introduction
                                                           The
                                                            FlowDocumentScrollViewer
                                                            control
                                                           The
                                                            FlowDocumentPageViewer
                                                            control
                                                           The FlowDocumentReader
                                                            control
                                                           Creating a FlowDocument
                                                            from Code-behind
                                                           Advanced FlowDocument
                                                            content
                                                           The RichTextBox control
                                                         Misc. controls
                                                           The Border control
                                                           The Slider control
                                                           The ProgressBar control
                                                           The WebBrowser control
                                                           The WindowsFormsHost
                                                           control
                                                         The TabControl
                                                           Using the TabControl
                                                           Tab positions
                                                           Styling the TabItems
                                                         List controls
                                                           The ItemsControl
                                                           The ListBox control
                                                           The ComboBox control
ListView filtering
                                                                                          Styles
                                                                                           Introduction
                                                                                           Using styles
                                                                                           Triggers
                                                                                           Multi triggers
                                                                                           Trigger animations
                                                                                          Misc.
                                                                                           The DispatcherTimer
                                                               
         
Download
                                                                PDF!
                                                         
Back to Top
Home Contact Us
                                                                                                Download as PDF
        Using WPF styles
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
         
In the previous chapter, where we introduced the concept of styles, we used           About WPF
          a very basic example of a locally defined style, which targeted a specific type
                                                                                                 What is WPF?
          of controls - the TextBlock. However, styles can be defined in several
                                                                                                 WPF vs. WinForms
          different scopes, depending on where and how you want to use them, and
          you can even
restrict styles to only be used on controls where you explicitly
          want it. In this chapter, I'll show you all the different ways in which a style can
          be
defined.                                                                           Getting started
                                                                                                 Visual Studio Express
         
Local control specific style                                                           Hello, WPF!
         
You can actually define a style directly on a control, like this:
                                                                                                XAML
            <Window
                                                                                                 What is XAML?
            x:Class="WpfTutorialSamples.Styles.ControlSpecificStyleSampl
                                                                                                 Basic XAML
                                                                                                 Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                A WPF application
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                               Introduction
                       Title="ControlSpecificStyleSample" Height="100"                           The Window
            Width="300">                                                                         Working with App.xaml
                  <Grid Margin="10">                                                             Command-line parameters
                       <TextBlock Text="Style test">                                             Resources
                             <TextBlock.Style>                                                   Handling exceptions
                                   <Style>
                                        <Setter Property="TextBlock.FontSize"
            Value="36" />                                                                       Basic controls
                                   </Style>
                                                                                                 The TextBlock control
                             </TextBlock.Style>
                                                                                                 The TextBlock control - Inline
                       </TextBlock>
                                                                                                 formatting
                  </Grid>
                                                                                                 The Label control
            </Window>
                                                                                                 The TextBox control
                                                                                                 The CheckBox control
                                                                                              Panels
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
         
In this example, the style only affects this specific TextBlock control, so why      The WrapPanel
          bother? Well, in this case, it makes no sense at all. I could have replaced
all      The StackPanel
          that extra markup with a single FontSize property on the TextBlock control,          The DockPanel
          but as we'll see later, styles can do a bit more than just set properties,
for       The Grid
          instance, style triggers could make the above example useful in a real life          The Grid - Rows & Columns
          application. However, most of the styles you'll define will likely be in a
higher    The Grid - Units
          scope.                                                                               The Grid - Spanning
                                                                                               The Grid - GridSplitter
         
Local child control style                                                            Using the Grid: A contact
                                                                                                form
         
Using the Resources section of a control, you can target child controls of this
          control (and child controls of those child controls and so
on). This is basically
          what we did in the introduction example in the last chapter, which looked like
                                                                                              Data binding
          this:
                                                                                               Introduction
                                                                                               Hello, bound world!
            <Window
                                                                                               Using the DataContext
            x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
                                                                                               The UpdateSourceTrigger
                                                                                                property
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                               Responding to changes
                                                                                               Value conversion with
                                                                                                IValueConverter
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                               The StringFormat property
                       Title="SimpleStyleSample" Height="200"
                                                                                               Debugging data bindings
            Width="250">
                   <StackPanel Margin="10">
                       <StackPanel.Resources>
                             <Style TargetType="TextBlock">                                   Commands
                                   <Setter Property="Foreground" Value="Gray"                  Introduction
              />                                                                               Using commands
                                   <Setter Property="FontSize" Value="24" />                   Implementing custom
                             </Style>                                                           commands
                       </StackPanel.Resources>
                       <TextBlock>Header 1</TextBlock>
                       <TextBlock>Header 2</TextBlock>                                        Common interface
                       <TextBlock Foreground="Blue">Header 3</TextBlock>                      controls
                   </StackPanel>
                                                                                               The Menu control
            </Window>
                                                                                               The ContextMenu
                                                                                               The ToolBar control
                                                                                               The StatusBar control
                                                                                               The Ribbon Control
                                                                                              Introduction
                                                                                              The
                                                                                               FlowDocumentScrollViewer
                                                                                               control
                                                                                              The
                                                                                               FlowDocumentPageViewer
                                                                                               control
         
This is great for the more local styling needs. For instance, it would make
                                                                                              The FlowDocumentReader
          perfect sense to do this in a dialog where you simply needed a set of controls
                                                                                               control
         
to look the same, instead of setting the individual properties on each of them.
                                                                                              Creating a FlowDocument
                                                                                               from Code-behind
         
Window-wide styles                                                                  Advanced FlowDocument
         
The next step up in the scope hierarchy is to define the style(s) within the         content
          Window resources. This is done in exactly the same way as above for the             The RichTextBox control
          StackPanel, but it's useful in those situations where you want a specific style
          to apply to all controls within a window (or a UserControl for that matter)
and
          not just locally within a specific control. Here's a modified example:            Misc. controls
                                                                                              The Border control
            <Window                                                                           The Slider control
            x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"                         The ProgressBar control
                                                                                              The WebBrowser control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      The WindowsFormsHost
                                                                                              control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="WindowWideStyleSample" Height="200"                           The TabControl
            Width="300">
                                                                                              Using the TabControl
                  <Window.Resources>
                                                                                              Tab positions
                       <Style TargetType="TextBlock">
                                                                                              Styling the TabItems
                             <Setter Property="Foreground" Value="Gray" />
                             <Setter Property="FontSize" Value="24" />
                       </Style>
                                                                                            List controls
                  </Window.Resources>
                  <StackPanel Margin="10">                                                    The ItemsControl
                       <TextBlock>Header 1</TextBlock>                                        The ListBox control
                       <TextBlock>Header 2</TextBlock>                                        The ComboBox control
                       <TextBlock Foreground="Blue">Header 3</TextBlock>
                  </StackPanel>
            </Window>                                                                       The ListView control
                                                                                              Introduction
                                                                                              A simple ListView
                                                                                              ListView, data binding and
                                                                                               ItemTemplate
                                                                                              ListView with a GridView
                                                                                              How-to: Left aligned column
                                                                                              names
                                                                                             ListView grouping
                                                                                             ListView sorting
                                                                                             How-to: ListView with
                                                                                              column sorting
                                                                                             ListView filtering
         
As you can see, the result is exactly the same, but it does mean that you
          could have controls placed everywhere within the window and the style would       The TreeView control
          still
apply.                                                                       Introduction
                                                                                             A simple TreeView
         
Application-wide styles                                                            TreeView, data binding and
                                                                                              multiple templates
         
If you want your styles to be used all over the application, across different
                                                                                             Handling
          windows, you can define it for the entire application. This is done in the
                                                                                              Selection/Expansion state
          App.xaml file that Visual Studio has likely created for you, and it's done just
                                                                                             Lazy loading TreeView items
          like in the window-wide example:
         App.xaml
                                                                                            The DataGrid control
            <Application x:Class="WpfTutorialSamples.App"                                    Introduction
                                                                                             Custom columns
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     Details row
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          Styles
            	            StartupUri="Styles/WindowWideStyleSample.xaml">
                                                                                             Introduction
                  <Application.Resources>
                                                                                             Using styles
                       <Style TargetType="TextBlock">
                                                                                             Triggers
                             <Setter Property="Foreground" Value="Gray" />
                                                                                             Multi triggers
                             <Setter Property="FontSize" Value="24" />
                                                                                             Trigger animations
                       </Style>
                  </Application.Resources>
            </Application>
                                                                                            Misc.
                                                                                             The DispatcherTimer
Window
                  <StackPanel Margin="10">
                       <TextBlock>Header 1</TextBlock>
                       <TextBlock>Header 2</TextBlock>
                       <TextBlock Foreground="Blue">Header 3</TextBlock>
                  </StackPanel>
            </Window>
         
Explicitly using styles
         
You have a lot of control over how and where to apply styling to your
          controls, from local styles and right up to the application-wide styles, that can
          help you get a consistent look all over your application, but so far, all of our
          styles have targeted a specific control type, and then ALL of these
controls
          have used it. This doesn't have to be the case though.
         
By setting the x:Key property on a style, you are telling WPF that you only
          want to use this style when you explicitly reference it on a
specific control.
          Let's try an example where this is the case:
            <Window
            x:Class="WpfTutorialSamples.Styles.ExplicitStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       Title="ExplicitStyleSample" Height="150"
            Width="300">
                  <Window.Resources>
                       <Style x:Key="HeaderStyle" TargetType="TextBlock">
                             <Setter Property="Foreground" Value="Gray" />
                             <Setter Property="FontSize" Value="24" />
                       </Style>
                  </Window.Resources>
                  <StackPanel Margin="10">
                       <TextBlock>Header 1</TextBlock>
                       <TextBlock Style="{StaticResource
            HeaderStyle}">Header 2</TextBlock>
                       <TextBlock>Header 3</TextBlock>
                  </StackPanel>
            </Window>
         
Notice how even though the TargetType is set to TextBlock, and the style is
          defined for the entire window, only the TextBlock in the middle, where I
          explicitly reference the HeaderStyle style, uses the style. This allows you to
          define styles that target a specific control type, but only
use it in the places
          where you need it.
         
Summary
         
WPF styling allows you to easily re-use a certain look for your controls all
          over the application. Using the x:Key property, you can decide whether a
          style
should be explicitly referenced to take effect, or if it should target all
          controls no matter what.
Previous Next
                                                                    
         
Download
                                                                     PDF!
                                                                                               
Back to Top
Home Contact Us
                                                                                              Download as PDF
        Trigger, DataTrigger & EventTrigger
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          
So far, we worked with styles by setting a static value for a specific property.   About WPF
           However, using triggers, you can change the value of a given property,
once
                                                                                               What is WPF?
           a certain condition changes. Triggers come in multiple flavors: Property
                                                                                               WPF vs. WinForms
           triggers, event triggers and data triggers. They allow you to do stuff that
           would normally be done in code-behind completely in markup instead, which
           is all a part of the ongoing process of separating style and code.
                                                                                              Getting started
          
Property trigger                                                                    Visual Studio Express
                                                                                               Hello, WPF!
          
The most common trigger is the property trigger, which in markup is simply
           defined with a <Trigger> element. It watches a specific property on the
owner
           control and when that property has a value that matches the specified value,
                                                                                              XAML
           properties can change. In theory this might sound a bit complicated, but
it's
           actually quite simple once we turn theory into an example:                          What is XAML?
                                                                                               Basic XAML
                                                                                               Events in XAML
            <Window
            x:Class="WpfTutorialSamples.Styles.StyleTriggersSample"
          
In this style, we set the Foreground property to blue, to make it look like a       Data binding
           hyperlink. We then add a trigger, which listens to theIsMouseOver property -         Introduction
           once this property changes to True, we apply two setters: We change the              Hello, bound world!
           Foreground to red and then we make it underlined. This is a great example            Using the DataContext
           on how easy it is to use triggers to apply design changes,
completely without        The UpdateSourceTrigger
           any code-behind code.                                                                 property
                                                                                                Responding to changes
          
We define a local style for this specific TextBlock, but as shown in the             Value conversion with
           previous articles, the style could have been globally defined as well, if we          IValueConverter
           wanted it to apply to all TextBlock controls in the application.                     The StringFormat property
                                                                                                Debugging data bindings
          
Data triggers
          
Data triggers, represented by the <DataTrigger> element, are used for
           properties that are not necessarily dependency properties. They work by             Commands
           creating a binding to a regular property, which is then monitored for changes.       Introduction
           This also opens up for binding your trigger to a property on a different
control.    Using commands
           For instance, consider the following example:                                        Implementing custom
                                                                                                 commands
            <Window
            x:Class="WpfTutorialSamples.Styles.StyleDataTriggerSample"
                                                                                               Common interface
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       controls
                                                                                                The Menu control
                                                                                                The ContextMenu
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                The ToolBar control
                        Title="StyleDataTriggerSample" Height="200"
                                                                                                The StatusBar control
            Width="200">
                                                                                                The Ribbon Control
                  <StackPanel HorizontalAlignment="Center"
            VerticalAlignment="Center">
                        <CheckBox Name="cbSample" Content="Hello, world?"
                                                                                               Rich Text controls
            />
                                                                                           The TabControl
                                                                                             Using the TabControl
                                                                                             Tab positions
                                                                                             Styling the TabItems
                                                                                           List controls
                                                                                             The ItemsControl
                                                                                             The ListBox control
          
In this example, we have a CheckBox and a TextBlock. Using a
                                                                                             The ComboBox control
           DataTrigger, we bind the TextBlock to the IsChecked property of the
           CheckBox. We then supply a default style, where the text is "No" and the
           foreground color is red, and then,
using a DataTrigger, we supply a style for
           when the IsChecked property of the CheckBox is changed to True, in which
                                                                                           The ListView control
           case we make it green with a text
saying "Yes!" (as seen on the screenshot).      Introduction
                                                                                             A simple ListView
          
Event triggers                                                                    ListView, data binding and
                                                                                              ItemTemplate
          
Event triggers, represented by the <EventTrigger> element, are mostly used        ListView with a GridView
           to trigger an animation, in response to an event being called. We haven't         How-to: Left aligned column
           discussed animations yet, but to demonstrate how an event trigger works,           names
           we'll use them anyway. Have a look on the chapter about animations for            ListView grouping
           more
details. Here's the example:                                                 ListView sorting
                                                                                             How-to: ListView with
            <Window                                                                           column sorting
          
The markup might look a bit overwhelming, but if you run this sample and
           look at the result, you'll see that we've actually accomplished a pretty cool
          
animation, going both ways, in ~20 lines of XAML. As you can see, I use an
           EventTrigger to subscribe to two events: MouseEnter and MouseLeave.
           When the mouse enters, I make a smooth and animated transition to a
           FontSize of 28 pixels in 300 milliseconds. When the mouse
leaves, I change
           the FontSize back to 18 pixels but I do it a bit slower, just because it looks
           kind of cool.
          
Summary
          
WPF styles make it easy to get a consistent look, and with triggers, this look
           becomes dynamic. Styles are great in your application, but they're even
           better when used in control templates etc. You can read more about that
           elsewhere in this tutorial.
          
In the next article, we'll look at multi triggers, which allow us to apply styles
           based on multiple properties.
Previous Next
                                                                        
         
Download
                                                                         PDF!
                                                                                                   
Back to Top
Home Contact Us
                                                                                           Download as PDF
       WPF MultiTrigger and
       MultiDataTrigger                                                                           Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
                                                                                           About WPF
         
In the previous chapter, we worked with triggers to get dynamic styles. So far
                                                                                            What is WPF?
          they have all been based on a single property, but WPF also supports multi
                                                                                            WPF vs. WinForms
          triggers, which can monitor two or more property conditions and only trigger
          once all of them are satisfied.
         
There are two types of multi triggers: The MultiTrigger, which just like the     Getting started
          regular Trigger works on dependency properties, and then the                      Visual Studio Express
          MultiDataTrigger, which works by binding to any kind of property. Let's start     Hello, WPF!
          with a quick example on how to use the MultiTrigger.
         
MultiTrigger                                                                     XAML
                                                                                            What is XAML?
            <Window
                                                                                            Basic XAML
            x:Class="WpfTutorialSamples.Styles.StyleMultiTriggerSample"
                                                                                            Events in XAML
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           A WPF application
                                                                                            Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          The Window
                       Title="StyleMultiTriggerSample" Height="100"                         Working with App.xaml
            Width="250">                                                                    Command-line parameters
                  <Grid>                                                                    Resources
                       <TextBox VerticalAlignment="Center"                                  Handling exceptions
            HorizontalAlignment="Center" Text="Hover and focus here"
            Width="150">
                             <TextBox.Style>                                               Basic controls
                                   <Style TargetType="TextBox">
                                                                                            The TextBlock control
                                        <Style.Triggers>
                                                                                            The TextBlock control - Inline
                                             <MultiTrigger>
                                                                                            formatting
                                                   <MultiTrigger.Conditions>
                                                                                            The Label control
                                                        <Condition
                                                                                            The TextBox control
            Property="IsKeyboardFocused" Value="True" />
                                                                                            The CheckBox control
                                                        <Condition
                                                                                           Data binding
                                                                                            Introduction
         
In this example, we use a trigger to change the background color of the           Hello, bound world!
          TextBox once it has keyboard focus AND the mouse cursor is over it, as            Using the DataContext
          seen on the
screenshot. This trigger has two conditions, but we could easily      The UpdateSourceTrigger
          have added more if needed. In the Setters section, we define the properties        property
          we wish to
change when all the conditions are met - in this case, just the one    Responding to changes
          (background color).                                                               Value conversion with
                                                                                             IValueConverter
         
MultiDataTrigger                                                                  The StringFormat property
                                                                                            Debugging data bindings
         
Just like a regular DataTrigger, the MultiDataTrigger is cool because it uses
          bindings to monitor a property. This means that you can use all of the cool
          WPF binding techniques, including binding to the property of another control
          etc. Let me show you how easy it is:
                                                                                           Commands
                                                                                            Introduction
            <Window                                                                         Using commands
            x:Class="WpfTutorialSamples.Styles.StyleMultiDataTriggerSamp                    Implementing custom
                                                                                             commands
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                           Common interface
                                                                                           controls
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          The Menu control
                       Title="StyleMultiDataTriggerSample" Height="150"                     The ContextMenu
            Width="200">                                                                    The ToolBar control
                  <StackPanel HorizontalAlignment="Center"                                  The StatusBar control
            VerticalAlignment="Center">                                                     The Ribbon Control
                       <CheckBox Name="cbSampleYes" Content="Yes" />
                       <CheckBox Name="cbSampleSure" Content="I'm sure"
            />                                                                             Rich Text controls
                       <TextBlock HorizontalAlignment="Center"
                                                                                            Introduction
            Margin="0,20,0,0" FontSize="28">
                                                                                            The
                             <TextBlock.Style>
                                                                                             FlowDocumentScrollViewer
                                   <Style TargetType="TextBlock">
                                                                                             control
                                        <Setter Property="Text"
                                                                                            The
            Value="Unverified" />
                                                                                             FlowDocumentPageViewer
                                        <Setter Property="Foreground"
                                                                                             control
            Value="Red" />
                                                                                            The FlowDocumentReader
                                        <Style.Triggers>
                                                                                             control
                                             <MultiDataTrigger>
                                                                                            Creating a FlowDocument
                                                   <MultiDataTrigger.Conditions>
                                                                                             from Code-behind
                                                        <Condition Binding="
                                                                                            Advanced FlowDocument
            {Binding ElementName=cbSampleYes, Path=IsChecked}"
                                                                                             content
            Value="True" />
                                                                                            The RichTextBox control
                                                        <Condition Binding="
            {Binding ElementName=cbSampleSure, Path=IsChecked}"
            Value="True" />
                                                   </MultiDataTrigger.Conditions>         Misc. controls
                                                   <Setter Property="Text"                  The Border control
            Value="Verified" />                                                             The Slider control
                                                   <Setter Property="Foreground"            The ProgressBar control
            Value="Green" />                                                                The WebBrowser control
                                             </MultiDataTrigger>                            The WindowsFormsHost
                                        </Style.Triggers>                                   control
                                   </Style>
                             </TextBlock.Style>
                       </TextBlock>                                                       The TabControl
                  </StackPanel>
                                                                                            Using the TabControl
            </Window>
                                                                                            Tab positions
                                                                                            Styling the TabItems
                                                                                          List controls
                                                                                            The ItemsControl
                                                                                            The ListBox control
                                                                                            The ComboBox control
                                                                                                 ListView filtering
               Previous                                                            Next
                                                                                                Styles
                                                                                                 Introduction
                                                                                                 Using styles
                                                                                                 Triggers
                                                                                                 Multi triggers
                                                                                                 Trigger animations
                                                                                                Misc.
                                                                                                 The DispatcherTimer
                                                                     
         
Download
                                                                      PDF!
                                                                    
Back to Top
Home Contact Us
                                                                                       Download as PDF
        Trigger animations
                                                                                              Download this entire
                                                                                              tutorial as PDF right
                                                                                       now!
          
One of the things that became a LOT easier with WPF, compared to previous   About WPF
           frameworks like WinForms, is animation. Triggers have direct support for
                                                                                        What is WPF?
           using
animations in response to the trigger being fired, instead of just
                                                                                        WPF vs. WinForms
           switching between two static values.
          
For this, we use the EnterActions and ExitActions
properties, which are
           present in all of the trigger types already discussed (except for the       Getting started
           EventTrigger), both single and multiple. Here's an example:                  Visual Studio Express
                                                                                        Hello, WPF!
            <Window
            x:Class="WpfTutorialSamples.Styles.StyleTriggerEnterExitActi
                                                                                       XAML
                                                                                        What is XAML?
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                        Basic XAML
                                                                                        Events in XAML
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="StyleTriggerEnterExitActions" Height="200"
                                                                                       A WPF application
            Width="200" UseLayoutRounding="True">
                  <Grid>                                                                Introduction
                        <Border Background="LightGreen" Width="100"                     The Window
            Height="100" BorderBrush="Green">                                           Working with App.xaml
                              <Border.Style>                                            Command-line parameters
                                   <Style TargetType="Border">                          Resources
                                         <Style.Triggers>                               Handling exceptions
                                                 <Trigger Property="IsMouseOver"
            Value="True">
                                                     <Trigger.EnterActions>            Basic controls
                                                         <BeginStoryboard>              The TextBlock control
                                                             <Storyboard>               The TextBlock control - Inline
                                                                                        formatting
            <ThicknessAnimation Duration="0:0:0.400" To="3"                             The Label control
            Storyboard.TargetProperty="BorderThickness" />                              The TextBox control
                                                                 <DoubleAnimation       The CheckBox control
            Duration="0:0:0.300" To="125"
                                                                                             Commands
                                                                                              Introduction
                                                                                              Using commands
                                                                                              Implementing custom
                                                                                               commands
                                                                                             Common interface
                                                                                             controls
                                                                                              The Menu control
          
In this example, we have a green square. It has a trigger that fires once the      The ContextMenu
           mouse is over, in which case it fires of several animations, all defined in
the    The ToolBar control
           EnterActions part of the trigger. In there, we animate the thickness of the        The StatusBar control
           border from its default 0 to a thickness of 3, and then we
animate the width       The Ribbon Control
           and height from 100 to 125. This all happens simultaneously, because they
           are a part of the same StoryBoard, and even at
slightly different speeds,
           since we have full control of how long each animation should run.                 Rich Text controls
                                                                                              Introduction
          
We use the ExitActions to reverse the changes we made, with animations
                                                                                              The
           that goes back to the default values. We run the reversing animations slightly
                                                                                               FlowDocumentScrollViewer
          
faster, because we can and because it looks cool.
                                                                                               control
          
The two states are represented on the two screenshots, but to fully                The
           appreciate the effect, you should try running the example on your own               FlowDocumentPageViewer
           machine, using
the source code above.                                               control
                                                                                              The FlowDocumentReader
          
Summary                                                                             control
                                                                                              Creating a FlowDocument
          
Using animations with style triggers is very easy, and while we haven't fully       from Code-behind
           explored all you can do with WPF animations yet, the example used above            Advanced FlowDocument
           should give you an idea on just how flexible both animations and styles are.        content
                                                                                              The RichTextBox control
                Previous                                                    Next
                                                                                            Misc. controls
                                                                                              The Border control
          comments powered by Disqus                                                          The Slider control
                                                                                              The ProgressBar control
                                                                                              The WebBrowser control
                                                                                              The WindowsFormsHost
                                                                                              control
                                                                                            The TabControl
                                                                                              Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
                                                                                            List controls
                                                                                              The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
ListView filtering
                                                                                  Styles
                                                                                   Introduction
                                                                                   Using styles
                                                                                   Triggers
                                                                                   Multi triggers
                                                                                   Trigger animations
                                                                                  Misc.
                                                                                   The DispatcherTimer
                                                       
         
Download
                                                        PDF!
                                                 
Back to Top
Home Contact Us
                                                                                          Download as PDF
        The DispatcherTimer
                                                                                                 Download this entire
                                                                                                 tutorial as PDF right
                                                                                          now!
         
In WinForms, there's a control called the Timer, which can perform an action    About WPF
          repeatedly within a given interval. WPF has this possibility as well, but
                                                                                           What is WPF?
          instead of an invisible control, we have the DispatcherTimer control. It does
                                                                                           WPF vs. WinForms
          pretty much the same thing, but instead of dropping it on
your form, you
          create and use it exclusively from your Code-behind code.
         
The DispatcherTimer class works by specifying an interval and then              Getting started
          subscribing to the Tick event that will occur each time this interval
is met.    Visual Studio Express
          The DispatcherTimer is not started before you call the Start() method or set     Hello, WPF!
          the IsEnabled property to true.
         
Let's try a simple example where we use a DispatcherTimer to create a
                                                                                          XAML
          digital clock:
                                                                                           What is XAML?
                                                                                           Basic XAML
            <Window
                                                                                           Events in XAML
            x:Class="WpfTutorialSamples.Misc.DispatcherTimerSample"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                          A WPF application
                                                                                           Introduction
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                         The Window
                       Title="DispatcherTimerSample" Height="150"                          Working with App.xaml
            Width="250">                                                                   Command-line parameters
                  <Grid>                                                                   Resources
                       <Label Name="lblTime" FontSize="48"                                 Handling exceptions
            HorizontalAlignment="Center" VerticalAlignment="Center" />
                  </Grid>
            </Window>                                                                     Basic controls
                                                                                           The TextBlock control
                                                                                           The TextBlock control - Inline
            using System;                                                                  formatting
            using System.Windows;                                                          The Label control
            using System.Windows.Threading;                                                The TextBox control
                                                                                           The CheckBox control
                                                                                           Commands
         
The XAML part is extremely simple - it's merely a centered label with a large     Introduction
          font size, used to display the current time.                                      Using commands
                                                                                            Implementing custom
         
Code-behind is where the magic happens in this example. In the constructor         commands
          of the window, we create a DispatcherTimer instance. We set the Interval
          property to one second, subscribe to the Tick event and then we start the
          timer. In the Tick event, we simply update the label to
show the current time.
                                                                                           Common interface
         
Of course, the DispatcherTimer can work at smaller or much bigger intervals.     controls
          For instance, you might only want something to happen every 30 seconds or         The Menu control
          5
minutes - just use the TimeSpan.From* methods, like FromSeconds or              The ContextMenu
          FromMinutes, or create a new TimeSpan instance that completely fits your          The ToolBar control
          needs.                                                                            The StatusBar control
                                                                                            The Ribbon Control
         
To show what the DispatcherTimer is capable of, let's try updating more
          frequently... A lot more frequently!
                                                                                           Rich Text controls
            using System;
                                                                                              Introduction
            using System.Windows;
                                                                                              The
            using System.Windows.Threading;
                                                                                               FlowDocumentScrollViewer
                                                                                               control
            namespace WpfTutorialSamples.Misc
                                                                                              The
            {
                                                                                               FlowDocumentPageViewer
            	          public partial class DispatcherTimerSample :
                                                                                               control
            Window
                                                                                              The FlowDocumentReader
            	{
                                                                                               control
            		public DispatcherTimerSample()
                                                                                              Creating a FlowDocument
            		{
                                                                                               from Code-behind
            			InitializeComponent();
                                                                                              Advanced FlowDocument
            			                              DispatcherTimer timer = new
                                                                                               content
            DispatcherTimer();
                                                                                              The RichTextBox control
            			timer.Interval =
            TimeSpan.FromMilliseconds(1);
            			timer.Tick += timer_Tick;
                                                                                            Misc. controls
            			timer.Start();
            		}                                                                               The Border control
                                                                                              The Slider control
            		                     void timer_Tick(object sender, EventArgs                   The ProgressBar control
            e)                                                                                The WebBrowser control
            		{                                                                               The WindowsFormsHost
            			lblTime.Content =                                                              control
            DateTime.Now.ToString("HH:mm:ss.fff");
            		}
            	}                                                                              The TabControl
            }                                                                                 Using the TabControl
                                                                                              Tab positions
                                                                                              Styling the TabItems
                                                                                            List controls
                                                                                              The ItemsControl
                                                                                              The ListBox control
                                                                                              The ComboBox control
         
As you can see, we now ask the DispatcherTimer to fire every millisecond! In
          the Tick event, we use a custom time format string to show the milliseconds       The ListView control
          in
the label as well. Now you have something that could easily be used as a         Introduction
          stopwatch - just add a couple of buttons to the Window and then have them           A simple ListView
          call the Stop(), Start() and Restart() methods on the timer.                        ListView, data binding and
                                                                                               ItemTemplate
         
Summary                                                                             ListView with a GridView
                                                                                              How-to: Left aligned column
         
There are many situations where you would need something in your
                                                                                               names
          application to occur at a given interval, and using the DispatcherTimer, it's
                                                                                              ListView grouping
          quite easy
to accomplish. Just be aware that if you do something complicated
                                                                                              ListView sorting
          in your Tick event, it shouldn't run too often, like in the last example where
                                                                                              How-to: ListView with
          the timer
ticks each millisecond - that will put a heavy strain on the computer
                                                                                               column sorting
          running your application.
                                                                                             ListView filtering
         
Also be aware that the DispatcherTimer is not 100% precise in all situations.
          The tick operations are placed on the Dispatcher queue, so if the computer is
         
under a lot of pressure, your operation might be delayed. The .NET                The TreeView control
          framework promises that the Tick event will never occur too early, but can't       Introduction
          promise
that it won't be slightly delayed. However, for most use cases, the        A simple TreeView
          DispatcherTimer is more than precise enough.                                       TreeView, data binding and
                                                                                              multiple templates
         
If you need your timer to have a higher priority in the queue, you can set the     Handling
          DispatcherPriority by sending one of the values along on the                        Selection/Expansion state
          DispatcherTimer
priority. More information about it can be found on this           Lazy loading TreeView items
          MSDN article.
                                                                                            Styles
                                                                                             Introduction
                                                                                             Using styles
                                                                                             Triggers
                                                                                             Multi triggers
                                                                                             Trigger animations
                                                                                            Misc.
                                                                                             The DispatcherTimer
                                                                 
         
Download
                                                                  PDF!
                                                  
Back to Top
Home Contact Us
                                                                                                Download as PDF
        Playing audio
                                                                                                       Download this entire
                                                                                                       tutorial as PDF right
                                                                                                now!
          
WPF comes with excellent built-in audio and video support, as you'll see in          About WPF
           the next couple of chapters of this tutorial. In this particular article, we'll
be
                                                                                                 What is WPF?
           discussing the ability to play audio, coming from actual audio files, e.g. in the
                                                                                                 WPF vs. WinForms
           MP3 format, but first, let's have a look at couple of simpler
approaches.
          
System sounds and the SoundPlayer
                                                                                                Getting started
          
WPF has a class called SoundPlayer, which will play audio content based
                                                                                                 Visual Studio Express
           on the WAV format for you. WAV is not a very widely used format
today,
                                                                                                 Hello, WPF!
           mainly because it's uncompressed and therefore takes up a LOT of space.
          
So while the SoundPlayer class is simple to use, it's not terribly useful.
           Instead, we'll be focusing on the MediaPlayer and MediaElement classes,              XAML
           which allows the playback of MP3 files, but first, let's have a look at the           What is XAML?
           simplest way of playing a sound in your
WPF application - the SystemSounds            Basic XAML
           class.                                                                                Events in XAML
          
The SystemSounds class offers several different sounds, which corresponds
           to the sound defined for this event by the user in Windows, like Exclamation
                                                                                                A WPF application
           and
Question. You can piggyback on these sounds and settings and play
           them with a single line of code:                                                      Introduction
                                                                                                 The Window
                                                                                                 Working with App.xaml
            SystemSounds.Beep.Play();
                                                                                                 Command-line parameters
                                                                                                 Resources
          
Here's a complete example, where we use all of the currently available                Handling exceptions
           sounds:
            RoutedEventArgs e)                                                                   Introduction
            		{                                                                                  The
            			SystemSounds.Hand.Play();                                                          FlowDocumentScrollViewer
            		}                                                                                   control
                                                                                                 The
            		                     private void btnQuestion_Click(object                          FlowDocumentPageViewer
            sender, RoutedEventArgs e)                                                            control
            		{                                                                                  The FlowDocumentReader
            			SystemSounds.Question.Play();                                                      control
            		}                                                                                  Creating a FlowDocument
            	}                                                                                    from Code-behind
            }                                                                                    Advanced FlowDocument
                                                                                                  content
                                                                                                 The RichTextBox control
                                                                                               Misc. controls
                                                                                                 The Border control
                                                                                                 The Slider control
                                                                                                 The ProgressBar control
                                                                                                 The WebBrowser control
                                                                                                 The WindowsFormsHost
                                                                                                 control
          
There are of course several limitations to using this approach. First of all, you
           only get access to these five sounds, and second of all, the user may
have          The TabControl
           disabled them in Windows, in which case the expected sound will be                    Using the TabControl
           replaced with silence. On the other hand, if you only want to use these               Tab positions
           sounds the
same way that Windows does, it makes it extremely easy to                  Styling the TabItems
           produce a sound for warnings, questions etc. In that case, it's a good thing
           that your
application will respect the user's choice of silence.
                                                                                               List controls
          
The MediaPlayer class
                                                                                                 The ItemsControl
          
The MediaPlayer class uses Windows Media Player technology to play both               The ListBox control
           audio and video in several modern formats, e.g. MP3 and MPEG. In this                 The ComboBox control
           article,
we'll be using it for playing just audio, and then focus on video in the
           next article.
                                                                                               The ListView control
          
Playing an MP3 file with the MediaPlayer class is very simple, as we'll see in
                                                                                                 Introduction
           this next example:
                                                                                                 A simple ListView
                                                                                                 ListView, data binding and
            <Window                                                                               ItemTemplate
            x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerAudio
                                                                                                 ListView with a GridView
                                                                                                 How-to: Left aligned column
                                                                                                  names
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                                 ListView grouping
                                                                                                 ListView sorting
                                                                                                 How-to: ListView with
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                                                                                  column sorting
                        Title="MediaPlayerAudioSample" Height="100"
                                                                                  ListView filtering
            Width="200">
                  <Grid VerticalAlignment="Center"
            HorizontalAlignment="Center">
                                                                                 The TreeView control
                        <Button Name="btnOpenAudioFile"
            Click="btnOpenAudioFile_Click">Open Audio file</Button>               Introduction
                  </Grid>                                                         A simple TreeView
            </Window>                                                             TreeView, data binding and
                                                                                   multiple templates
                                                                                  Handling
                                                                                   Selection/Expansion state
            using System;                                                         Lazy loading TreeView items
            using System.Windows;
            using System.Windows.Media;
            using Microsoft.Win32;                                               The DataGrid control
                                                                                  Introduction
            namespace WpfTutorialSamples.Audio_and_Video
                                                                                  Custom columns
            {
                                                                                  Details row
            	           public partial class MediaPlayerAudioSample :
            Window
            	{
            		                     private MediaPlayer mediaPlayer = new         Styles
            MediaPlayer();                                                        Introduction
                                                                                  Using styles
            		public MediaPlayerAudioSample()                                     Triggers
            		{                                                                   Multi triggers
            			InitializeComponent();                                             Trigger animations
            		}
          
In this example, we just have a single button, which will show an
           OpenFileDialog and let you select an MP3 file. Once that is done, it will use
           the already
created MediaPlayer instance to open and play this file. Notice
           that the MediaPlayer object is created outside of the event handler. This
           makes sure that
the object is not prematurely garbage collected because it
           goes out of scope once the event handler is done, which would result in the
           playback stopping.
          
Please also notice that no exception handling is done for this example, as
           usual to keep the example as compact as possible, but in this case also
           because
the Open() and Play() methods actually doesn't throw any
           exceptions. Instead, you can use the MediaOpened and MediaFailed events
           to act when things go
right or wrong.
          
Controlling the MediaPlayer
          
In our first MediaPlayer example, we just opened and automatically started
           playing a file, without giving the user a chance to control the playback
           process, but obviously, the MediaPlayer control offers you full control of
           playback. Here's an example showing you the most important functions:
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerAudio
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="MediaPlayerAudioControlSample" Height="120"
              Width="300">
                  <StackPanel Margin="10">
                        <Label Name="lblStatus" Content="Not playing..."
            HorizontalContentAlignment="Center" Margin="5" />
                        <WrapPanel HorizontalAlignment="Center">
                              <Button Name="btnPlay"
            Click="btnPlay_Click">Play</Button>
                              <Button Name="btnPause" Margin="5,0"
            Click="btnPause_Click">Pause</Button>
                              <Button Name="btnStop"
            Click="btnStop_Click">Stop</Button>
                        </WrapPanel>
                  </StackPanel>
            </Window>
            using System;
            using System.Windows;
            using System.Windows.Media;
            using System.Windows.Threading;
            using Microsoft.Win32;
            namespace WpfTutorialSamples.Audio_and_Video
            {
            	           public partial class MediaPlayerAudioControlSample
              : Window
            	{
            		                     private MediaPlayer mediaPlayer = new
            MediaPlayer();
            		public MediaPlayerAudioControlSample()
            		{
            			InitializeComponent();
            			OpenFileDialog openFileDialog =
            new OpenFileDialog();
            			                             openFileDialog.Filter = "MP3 files
                (*.mp3)|*.mp3|All files (*.*)|*.*";
            			if(openFileDialog.ShowDialog() ==
            true)
            				mediaPlayer.Open(new
            Uri(openFileDialog.FileName));
            		{
            			mediaPlayer.Play();
            		}
          
In this example, we have expanded our player a bit, so that it now contains a
           Play, Pause and Stop button, as well as a label for showing the current
           playback status. The MP3 file to be played is loaded the same way, but we
           do it as soon as the application starts, to keep the example simple.
          
Right after the MP3 is loaded, we start a timer, which ticks every second. We
           use this event to update the status label, which will show the current
progress
           as well as the entire length of the loaded file.
          
The three buttons each simply call a corresponding method on the
           MediaPlayer object - Play, Pause and Stop.
          
Summary
          
There are several more options that you can let your user control, but I want
           to save that for when we have talked about the video aspects of the
           MediaPlayer class - at that point, I'll do a more complete example of a media
           player capable of playing both audio and video files, with more options.
Previous Next
                                                  
         
Download
                                                   PDF!
                                                                             
Back to Top
Home Contact Us
                                                                                              Download as PDF
        Playing video
                                                                                                     Download this entire
                                                                                                     tutorial as PDF right
                                                                                              now!
          
In the previous article, we used the MediaPlayer class to play an MP3 file,        About WPF
           but the cool part about the MediaPlayer class is that it can
work with video
                                                                                               What is WPF?
           files as well. However, since a video actually needs to be displayed
                                                                                               WPF vs. WinForms
           somewhere in the interface, as opposed to an audio file, we need a
wrapper
           element to visually represent the MediaPlayer instance. This is where the
           MediaElement comes into play.
                                                                                              Getting started
          
The MediaElement                                                                    Visual Studio Express
                                                                                               Hello, WPF!
          
The MediaElement acts as a wrapper around MediaPlayer, so that you can
           display video content at a given place in your application, and because of
           that, it
can play both audio and video files, although the visual representation
                                                                                              XAML
           doesn't really matter in dealing with audio files.
                                                                                               What is XAML?
          
I want to show you just how easy you can show video content in your WPF             Basic XAML
           application, so here's a bare minimum example:                                      Events in XAML
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerVideo                      A WPF application
                                                                                               Introduction
                                                                                               The Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       Working with App.xaml
                                                                                               Command-line parameters
                                                                                               Resources
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             Handling exceptions
                        Title="MediaPlayerVideoSample" Height="300"
            Width="300">
                   <Grid>
                                                                                              Basic controls
                        <MediaElement
            Source="http://hubblesource.stsci.edu/sources/video/clips/de                       The TextBlock control
              />                                                                               The TextBlock control - Inline
                   </Grid>                                                                     formatting
            </Window>                                                                          The Label control
                                                                                               The TextBox control
                                                                                               The CheckBox control
                                                                                              Panels
                                                                                               Introduction to WPF Panels
                                                                                               The Canvas
                                                                                               The WrapPanel
                                                                                               The StackPanel
                                                                                               The DockPanel
                                                                                               The Grid
                                                                                               The Grid - Rows & Columns
                                                                                               The Grid - Units
                                                                                               The Grid - Spanning
                                                                                               The Grid - GridSplitter
                                                                                               Using the Grid: A contact
                                                                                                form
          
And that's it - a single line of XAML inside your window and you're displaying
           video (this specific video is about the Hubble Space Telescope - more
           information can be found at this website) in your WPF application.
                                                                                              Data binding
          
Dealing with video size                                                             Introduction
                                                                                               Hello, bound world!
          
Our examples in this article so far has just used the same size for the             Using the DataContext
           MediaElement, not taking the dimensions of the video into consideration.            The UpdateSourceTrigger
           This is
possible because the MediaElement can stretch/shrink the content to          property
           fit the available width/height and will do so by default. This is caused by the     Responding to changes
           Stretch property, which is set to Uniform by default, meaning that the video        Value conversion with
           will be stretched, while respecting the
aspect ratio.                                IValueConverter
                                                                                               The StringFormat property
          
If your window is larger than your video, this might work just fine, but perhaps
                                                                                               Debugging data bindings
           you don't want any stretching to occur? Or perhaps you want the window to
           adjust to fit your video's dimensions, instead of the other way around?
          
The first thing you need to do is to turn off stretching by setting the Stretch    Commands
           property to None. This will ensure that
the video is rendered in its natural        Introduction
           size. Now if you want the window to adjust to that, it's actually quite simple -    Using commands
           just use the ResizeToContent property on the Window to accomplish this.             Implementing custom
           Here's a full example:                                                               commands
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerVideo                      Common interface
                                                                                              controls
                                                                                               The Menu control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       The ContextMenu
                                                                                               The ToolBar control
                                                                                               The StatusBar control
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             The Ribbon Control
                        Title="MediaPlayerVideoSizeSample" Height="500"
            Width="500" SizeToContent="WidthAndHeight">
                  <Grid>
                                                                                              Rich Text controls
                        <MediaElement
                                                                                             Introduction
            Source="http://hubblesource.stsci.edu/sources/video/clips/de
                                                                                             The
              Name="mePlayer" Stretch="None" />
                                                                                              FlowDocumentScrollViewer
                  </Grid>
                                                                                              control
            </Window>
                                                                                             The
                                                                                              FlowDocumentPageViewer
                                                                                              control
                                                                                             The FlowDocumentReader
                                                                                              control
                                                                                             Creating a FlowDocument
                                                                                              from Code-behind
                                                                                             Advanced FlowDocument
                                                                                              content
                                                                                             The RichTextBox control
                                                                                           Misc. controls
                                                                                             The Border control
                                                                                             The Slider control
                                                                                             The ProgressBar control
                                                                                             The WebBrowser control
                                                                                             The WindowsFormsHost
          
As you can see, despite the initial values of 500 for the Width and Height
                                                                                             control
           properties on the Window, the size is adjusted (down, in this case) to match
           the
resolution of the video.
          
Please notice that this might cause the window to have a size of zero (only     The TabControl
           the title bar and borders will be visible) during startup, while the video is     Using the TabControl
           loaded. To prevent this, you can set the MinWidth and MinHeight properties        Tab positions
           on the Window to something that suits your needs.                                 Styling the TabItems
          
Controlling the MediaElement/MediaPlayer
          
As you can see if you run our previous examples, the video starts playing as
                                                                                           List controls
           soon as the player has buffered enough data, but you can change this              The ItemsControl
           behavior
by using the LoadedBehavior property. We'll do that in the next          The ListBox control
           example, where we'll also add a couple of buttons to control the playback:        The ComboBox control
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerVideo                   The ListView control
                                                                                             Introduction
                                                                                             A simple ListView
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                     ListView, data binding and
                                                                                              ItemTemplate
                                                                                             ListView with a GridView
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                           How-to: Left aligned column
                        Title="MediaPlayerVideoControlSample" Height="300"                    names
              Width="300">                                                                   ListView grouping
                  <Grid Margin="10">                                                         ListView sorting
                        <Grid.RowDefinitions>                                                How-to: ListView with
                              <RowDefinition Height="*" />                                    column sorting
            					lblStatus.Content
            = String.Format("{0} / {1}",
            mePlayer.Position.ToString(@"mm\:ss"),
            mePlayer.NaturalDuration.TimeSpan.ToString(@"mm\:ss"));
            			}
            			else
            				lblStatus.Content = "No
            file selected...";
            		}
          
This example is much like the one we did in the previous article for audio, just
           for video in this case. We have a bottom area with a set of buttons for
           controlling the playback, a label for showing the status, and then a
           MediaElement control in the top area to show the actual video.
          
Upon application start, we create and start a timer, which ticks every second.
           We use this event to update the status label, which will show the current
           progress as well as the entire length of the loaded file, as seen on the
           screenshot.
          
The three buttons each simply call a corresponding method on the
           MediaElement control - Play(), Pause() and Stop().
          
Summary
          
Once again it's clear how easy WPF makes even advanced things like
           playing a video. So far, we've worked with some basic examples, but in the
           next chapter,
I'm going to combine all the stuff we've learned about audio and
           video playback into a single, media player with a lot more functionality than
           we've seen
so far. Read on!
Previous Next
                                                                 
         
Download
                                                                  PDF!
                                                                                            
Back to Top
Home Contact Us
                                                                                             Download as PDF
        How-to: Creating a complete
        Audio/Video player                                                                          Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
                                                                                             About WPF
          
As a conclusion to the last chapters on playing audio and video, I decided to
                                                                                              What is WPF?
           create a more complete sample, where we take advantage of the fact that the
                                                                                              WPF vs. WinForms
          
MediaPlayer/MediaElement classes can handle both audio and video.
          
I will take the concepts used in the articles about playing audio and video and
           combine them with several controls which we have already discussed                Getting started
           previously in this article, and turn it all into a WPF Media Player. The result    Visual Studio Express
           will look something like this:                                                     Hello, WPF!
                                                                                             XAML
                                                                                              What is XAML?
                                                                                              Basic XAML
                                                                                              Events in XAML
          
But that's just when it plays audio/MP3 files. Once a video is loaded, the
           interface automatically expands to show the video content inside the window:
                                                                                             A WPF application
                                                                                              Introduction
                                                                                              The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          
Also notice that we have set the MediaElement Stretch property to None,           Data binding
           and the Window SizeToContentMode
to WidthAndHeight. This is what
                                                                                              Introduction
           keeps the window to the minimum size needed to show the interface as well
                                                                                              Hello, bound world!
           as the video, if one is playing.
                                                                                              Using the DataContext
          
For showing the Volume, we've used a ProgressBar control in the lower, right       The UpdateSourceTrigger
           corner. This doesn't currently let the user control the volume, but merely          property
           reflects the Volume property on the MediaElement control, through a classic        Responding to changes
           data binding. We've implemented a small but neat trick for
letting the user        Value conversion with
           control the volume anyway though - more on that below.                              IValueConverter
                                                                                              The StringFormat property
          
The code                                                                           Debugging data bindings
          
In Code-behind, we re-use several techniques already used in our previous
           examples. For instance, we initiate a DispatcherTimer and let it tick every
                                                                                             Commands
          
second, to show the current playback progress in the interface. In the Tick
                                                                                               Introduction
          event of the timer, we update Slider control, by settingMinimum, Maximum
                                                                                               Using commands
          and current Value according to the file being played, and by hooking up to
                                                                                               Implementing custom
          the ValueChanged event on the slider, we use that to update the label
                                                                                                commands
          showing the current playback progress in hours, minutes and seconds.
          
The Slider control also allows the user to skip to another part of the file,
           simply by dragging the "thumb" to another location. We handle this by             Common interface
          
implementing events for DragStarted and DragCompleted - the first one to          controls
           set a variable ( userIsDraggingSlider) that tells the timer not to update the       The Menu control
           Slider while we drag, and the second one to skip to the designated part when        The ContextMenu
          
the user releases the mouse button.                                                 The ToolBar control
                                                                                               The StatusBar control
          
There are CanExecute and Executed handlers for the four commands we
                                                                                               The Ribbon Control
           use and especially the ones for Pause and Stop are interesting. Since
we
           can't get a current state from the MediaElement control, we have to keep
           track of the current state ourselves. This is done with a local variable called
           mediaPlayerIsPlaying, which we regularly check to see if the Pause and
                                                                                             Rich Text controls
           Stop buttons should be enabled.                                                     Introduction
                                                                                               The
          
The last little detail you should notice is the Grid_MouseWheel event. The           FlowDocumentScrollViewer
           main Grid covers the entire window, so by subscribing to this
event, we get          control
           notified when the user scrolls the wheel. When that happens, as a little            The
           gimmick, we turn the volume up or down, depending on the direction
(we get           FlowDocumentPageViewer
           that by looking at the Delta property, which is negative when scrolling down         control
           and positive when scrolling up). This is immediately reflected in the
user          The FlowDocumentReader
           interface, where a ProgressBar control is bound to the Volume property of            control
           the MediaElement.                                                                   Creating a FlowDocument
                                                                                                from Code-behind
          
The complete source code                                                            Advanced FlowDocument
                                                                                                content
          
With all the theory behind the example described, here's the complete source
                                                                                               The RichTextBox control
           code:
            <Window
                                                                                             Misc. controls
            x:Class="WpfTutorialSamples.Audio_and_Video.AudioVideoPlayer
                                                                                               The Border control
                                                                                               The Slider control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                       The ProgressBar control
                                                                                               The WebBrowser control
                                                                                               The WindowsFormsHost
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             control
                        Title="WPF Media Player" Height="300" Width="300"
                        MinWidth="300" SizeToContent="WidthAndHeight">
                  <Window.CommandBindings>                                                   The TabControl
                        <CommandBinding Command="ApplicationCommands.Open"                     Using the TabControl
              CanExecute="Open_CanExecute" Executed="Open_Executed" />                         Tab positions
                        <CommandBinding Command="MediaCommands.Play"                           Styling the TabItems
            CanExecute="Play_CanExecute" Executed="Play_Executed" />
                        <CommandBinding Command="MediaCommands.Pause"
            CanExecute="Pause_CanExecute" Executed="Pause_Executed" />
                                                                                             List controls
                        <CommandBinding Command="MediaCommands.Stop"
                                                                                               The ItemsControl
            using System;
            using System.Windows;
            using System.Windows.Controls.Primitives;
            using System.Windows.Input;
            using System.Windows.Threading;
            using Microsoft.Win32;
            namespace WpfTutorialSamples.Audio_and_Video
            {
            	           public partial class
            AudioVideoPlayerCompleteSample : Window
            	{
            		                     private bool mediaPlayerIsPlaying = false;
            		                     private bool userIsDraggingSlider = false;
            		public AudioVideoPlayerCompleteSample()
            		{
            			InitializeComponent();
            (mePlayer.NaturalDuration.HasTimeSpan) &&
            (!userIsDraggingSlider))
            			{
            				sliProgress.Minimum = 0;
            				sliProgress.Maximum =
            mePlayer.NaturalDuration.TimeSpan.TotalSeconds;
            				sliProgress.Value =
            mePlayer.Position.TotalSeconds;
            			}
            		}
            		private void
            sliProgress_DragStarted(object sender,
            DragStartedEventArgs e)
            		{
            			userIsDraggingSlider = true;
            		}
            		private void
            sliProgress_DragCompleted(object sender,
            DragCompletedEventArgs e)
            		{
            			userIsDraggingSlider = false;
            			mePlayer.Position =
            TimeSpan.FromSeconds(sliProgress.Value);
            		}
            		private void
            sliProgress_ValueChanged(object sender,
            RoutedPropertyChangedEventArgs<double> e)
            		{
            			lblProgressStatus.Text =
            TimeSpan.FromSeconds(sliProgress.Value).ToString(@"hh\:mm\:s
            	}
            }
          
Summary
          
The code listing might look a bit overwhelming, but as you can see, there's a
           lot of repetition in it. If you take that out of the picture, you will soon
realize
           that creating a pretty capable media player in WPF is really not that hard!
           Feel free to expand on this example for your own projects - how about
           implementing a playlist feature?
Previous Next
                                                                      
         
Download
                                                                       PDF!
                                                                                                 
Back to Top
Home Contact Us
                                                                                           Download as PDF
        Speech synthesis (making WPF talk)
                                                                                                  Download this entire
                                                                                                  tutorial as PDF right
                                                                                           now!
          
In the System.Speech assembly, Microsoft has added something really cool:       About WPF
           Speech Synthesis, the ability to transform text into spoken words, and
                                                                                            What is WPF?
           Speech
Recognition, the ability to translate spoken words into text. We'll be
                                                                                            WPF vs. WinForms
           focusing on the speech synthesis in this article, and then get into speech
           recognition in the next one.
          
To transform text into spoken words, we'll be using the SpeechSynthesizer       Getting started
           class. This class resides in the System.Speech assembly, which
we'll need to     Visual Studio Express
           add to use it in our application. Depending on which version of Visual Studio    Hello, WPF!
           you use, the process looks something like this:
                                                                                           XAML
                                                                                            What is XAML?
                                                                                            Basic XAML
                                                                                            Events in XAML
                                                                                           A WPF application
                                                                                            Introduction
                                                                                            The Window
                                                                                            Working with App.xaml
                                                                                            Command-line parameters
                                                                                            Resources
                                                                                            Handling exceptions
                                                                                           Basic controls
                                                                                            The TextBlock control
                                                                                            The TextBlock control - Inline
                                                                                            formatting
                                                                                            The Label control
                                                                                            The TextBox control
                                                                                            The CheckBox control
                                                                                             Panels
                                                                                              Introduction to WPF Panels
          
With the appropriate assembly added, we can now use the
                                                                                              The Canvas
           SpeechSynthesizer class from the System.Speech.Synthesis namespace.
                                                                                              The WrapPanel
           With that in place, we'll kick
off with yet another very simple "Hello, world!"
                                                                                              The StackPanel
           inspired example, this time in spoken words:
                                                                                              The DockPanel
                                                                                              The Grid
            <Window                                                                           The Grid - Rows & Columns
            x:Class="WpfTutorialSamples.Audio_and_Video.SpeechSynthesisS                      The Grid - Units
                                                                                              The Grid - Spanning
                                                                                              The Grid - GridSplitter
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                      Using the Grid: A contact
                                                                                               form
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="SpeechSynthesisSample" Height="150"
                                                                                             Data binding
            Width="150">
                                                                                              Introduction
                  <Grid>
                                                                                              Hello, bound world!
                        <Button Name="btnSayIt" Click="btnSayHello_Click"
                                                                                              Using the DataContext
            VerticalAlignment="Center"
                                                                                              The UpdateSourceTrigger
            HorizontalAlignment="Center">Say hello!</Button>
                                                                                               property
                  </Grid>
                                                                                              Responding to changes
            </Window>
                                                                                              Value conversion with
                                                                                               IValueConverter
                                                                                              The StringFormat property
            using System;                                                                     Debugging data bindings
            using System.Speech.Synthesis;
            using System.Windows;
                                                                                             Commands
            namespace WpfTutorialSamples.Audio_and_Video
                                                                                              Introduction
            {
                                                                                              Using commands
            	           public partial class SpeechSynthesisSample :
                                                                                              Implementing custom
            Window
                                                                                               commands
            	{
            		public SpeechSynthesisSample()
            		{
                                                                                             Common interface
            			InitializeComponent();
                                                                                          controls
            		}
                                                                                            The Menu control
            		                     private void btnSayHello_Click(object                    The ContextMenu
            sender, RoutedEventArgs e)                                                      The ToolBar control
            		{                                                                             The StatusBar control
            			SpeechSynthesizer                                                            The Ribbon Control
            speechSynthesizer = new SpeechSynthesizer();
            			speechSynthesizer.Speak("Hello,
            world!");                                                                     Rich Text controls
            		}                                                                             Introduction
            	}                                                                              The
            }                                                                                FlowDocumentScrollViewer
                                                                                             control
                                                                                            The
                                                                                             FlowDocumentPageViewer
                                                                                             control
                                                                                            The FlowDocumentReader
                                                                                             control
                                                                                            Creating a FlowDocument
                                                                                             from Code-behind
                                                                                            Advanced FlowDocument
                                                                                             content
          
This is pretty much as simple as it gets, and since the screenshot really        The RichTextBox control
           doesn't help a lot in demonstrating speech synthesis, I suggest that you try
           building the example yourself, to experience it.
                                                                                          Misc. controls
          
Controlling pronunciation
                                                                                            The Border control
          
The SpeechSynthesizer can do more than that though. Through the use of           The Slider control
           the PromptBuilder class, we can get much more control of how a sentence is       The ProgressBar control
           spoken.
This next example, which is an extension of the first example, will      The WebBrowser control
           illustrate that:                                                                 The WindowsFormsHost
                                                                                            control
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.SpeechSynthesisP
                                                                                          The TabControl
                                                                                            Using the TabControl
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta                    Tab positions
                                                                                            Styling the TabItems
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="SpeechSynthesisPromptBuilderSample"
                                                                                          List controls
            Height="150" Width="150">
                  <Grid>                                                                    The ItemsControl
                        <Button Name="btnSayIt" Click="btnSayHello_Click"                   The ListBox control
            VerticalAlignment="Center"                                                      The ComboBox control
            HorizontalAlignment="Center">Say hello!</Button>
                  </Grid>
            </Window>                                                                     The ListView control
                                                                                            Introduction
                                                                                   A simple ListView
                                                                                   ListView, data binding and
            using System;
                                                                                    ItemTemplate
            using System.Speech.Synthesis;
                                                                                   ListView with a GridView
            using System.Windows;
                                                                                   How-to: Left aligned column
                                                                                    names
            namespace WpfTutorialSamples.Audio_and_Video
                                                                                   ListView grouping
            {
                                                                                   ListView sorting
            	           public partial class
                                                                                   How-to: ListView with
            SpeechSynthesisPromptBuilderSample : Window
                                                                                    column sorting
            	{
                                                                                   ListView filtering
            		public
            SpeechSynthesisPromptBuilderSample()
            		{
            			InitializeComponent();
                                                                                  The TreeView control
            		}                                                                    Introduction
                                                                                   A simple TreeView
            		                     private void btnSayHello_Click(object           TreeView, data binding and
            sender, RoutedEventArgs e)                                              multiple templates
            		{                                                                    Handling
            			                               PromptBuilder promptBuilder = new     Selection/Expansion state
            PromptBuilder();                                                       Lazy loading TreeView items
            			promptBuilder.AppendText("Hello
            world");
                                                                                  The DataGrid control
            			                               PromptStyle promptStyle = new
                                                                                   Introduction
            PromptStyle();
                                                                                   Custom columns
            			promptStyle.Volume =
                                                                                   Details row
            PromptVolume.Soft;
            			promptStyle.Rate =
            PromptRate.Slow;
                                                                                  Styles
            			
            promptBuilder.StartStyle(promptStyle);                                 Introduction
            			promptBuilder.AppendText("and                                       Using styles
            hello to the universe too.");                                          Triggers
            			promptBuilder.EndStyle();                                           Multi triggers
                                                                                   Trigger animations
            			promptBuilder.AppendText("On this
            day, ");
            			                                                                   Misc.
            promptBuilder.AppendTextWithHint(DateTime.Now.ToShortDateStr           The DispatcherTimer
              SayAs.Date);
            			promptBuilder.AppendText(", we're
                                                                                  Audio & Video
            gathered here to learn");
                                                                                   Playing audio
            			promptBuilder.AppendText("all",
                                                                                   Playing video
            PromptEmphasis.Strong);
                                                                                   How-to: Complete media
            			promptBuilder.AppendText("about");
                                                                                   player
            			
                                                                                   Speech synthesis
            promptBuilder.AppendTextWithHint("WPF", SayAs.SpellOut);
                                                                                   Speech recognition
            			SpeechSynthesizer
            speechSynthesizer = new SpeechSynthesizer();
            			
            speechSynthesizer.Speak(promptBuilder);
            		}
            	}
            }
          
This is where it gets interesting. Try running the example and see how nicely
           this works. By supplying the SpeechSynthesizer with something more than
           just
a text string, we can get a lot of control of how the various parts of the
           sentence are spoken. In this case, the application will say the following:
          Hello world and hello to the universe too. On this day, <today's date>, we're
          gathered here to learn all about WPF.
          
Now try sending that directly to the SpeechSynthesizer and you'll probably
           giggle a bit of the result. What we do instead is guide the Speak() method
           into
how the various parts of the sentence should be used. First of all, we ask
           WPF to speak the "and hello to the universe too"-part in a lower volume and
           a
slower rate, as if it was whispered.
          
The next part that doesn't just use default pronunciation is the date. We use
           the special SayAs enumeration to specify that the date should be read out as
          
an actual date and not just a set of numbers, spaces and special characters.
          
We also ask that the word "all" is spoken with a stronger emphasis, to make
           the sentence more dynamic, and in the end, we ask that the word "WPF" is
           spelled out (W-P-F) instead of being pronounced as an actual word.
          
All in all, this allows us to make the SpeechSynthesizer a lot easier to
           understand!
          
Summary
          
Making your WPF application speak is very easy, and by using the
           PromptBuilder class, you can even get a lot of control of how your words are
           spoken. This
is a very powerful feature, but it might not be relevant to a lot of
           today's applications. It's still very cool though!
Previous Next
                                                                       
         
Download
                                                                        PDF!
                                                                                                  
Back to Top
Home Contact Us
                                                                                             Download as PDF
        Speech recognition (making WPF
        listen)                                                                                     Download this entire
                                                                                                    tutorial as PDF right
                                                                                             now!
                                                                                             About WPF
          
In the previous article we discussed how we could transform text into spoken
                                                                                              What is WPF?
           words, using the SpeechSynthesizer class. In this article we'll go the other
                                                                                              WPF vs. WinForms
           way around, by turning spoken words into text. To do that, we'll be using the
           SpeechRecognition class, which resides in the System.Speech
assembly.
           This assembly is not a part of your solutions by default, but we can easily add
           it. Depending on which version of Visual Studio you use, the
process looks        Getting started
           something like this:                                                               Visual Studio Express
                                                                                              Hello, WPF!
                                                                                             XAML
                                                                                              What is XAML?
                                                                                              Basic XAML
                                                                                              Events in XAML
                                                                                             A WPF application
                                                                                              Introduction
                                                                                              The Window
                                                                                              Working with App.xaml
                                                                                              Command-line parameters
                                                                                              Resources
                                                                                              Handling exceptions
                                                                                             Basic controls
                                                                                              The TextBlock control
                                                                                              The TextBlock control - Inline
                                                                                              formatting
                                                                                              The Label control
                                                                                              The TextBox control
                                                                                              The CheckBox control
          
With that taken care of, let's start out with an extremely simple speech   Panels
           recognition example:                                                        Introduction to WPF Panels
                                                                                       The Canvas
            <Window                                                                    The WrapPanel
            x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitio               The StackPanel
                                                                                       The DockPanel
                                                                                       The Grid
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta               The Grid - Rows & Columns
                                                                                       The Grid - Units
                                                                                       The Grid - Spanning
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     The Grid - GridSplitter
                        Title="SpeechRecognitionTextSample" Height="200"               Using the Grid: A contact
            Width="300">                                                                form
                  <DockPanel Margin="10">
                        <TextBox Margin="0,10" Name="txtSpeech"
            AcceptsReturn="True" />                                                   Data binding
                  </DockPanel>
                                                                                       Introduction
            </Window>
                                                                                       Hello, bound world!
                                                                                       Using the DataContext
                                                                                       The UpdateSourceTrigger
            using System;                                                               property
            using System.Speech.Recognition;                                           Responding to changes
            using System.Windows;                                                      Value conversion with
                                                                                        IValueConverter
            namespace WpfTutorialSamples.Audio_and_Video                               The StringFormat property
            {                                                                          Debugging data bindings
            	           public partial class SpeechRecognitionTextSample :
              Window
            	{                                                                        Commands
            		public SpeechRecognitionTextSample()                                     Introduction
            		{                                                                        Using commands
            			InitializeComponent();                                                  Implementing custom
            			SpeechRecognizer speechRecognizer                                        commands
            = new SpeechRecognizer();
            		}
            	}                                                                               Common interface
            }
                                                                                             controls
                                                                                               The Menu control
                                                                                               The ContextMenu
                                                                                               The ToolBar control
                                                                                               The StatusBar control
                                                                                               The Ribbon Control
          
This first example will allow you to dictate text to your application, which is
                                                                                             Misc. controls
           great, but what about commands? Windows and WPF will actually work
                                                                                               The Border control
           together
here and turn your buttons into commands, reachable through
                                                                                               The Slider control
           speech, without any extra work. Here's an example:
                                                                                               The ProgressBar control
                                                                                               The WebBrowser control
            <Window
                                                                                               The WindowsFormsHost
            x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitio
                                                                                               control
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
                                                                                             The TabControl
                                                                                               Using the TabControl
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                             Tab positions
                        Title="SpeechRecognitionTextCommandsSample"                            Styling the TabItems
            Height="200" Width="300">
                  <DockPanel Margin="10">
                        <WrapPanel DockPanel.Dock="Top">                                     List controls
                             <Button Name="btnNew"                                             The ItemsControl
            Click="btnNew_Click">New</Button>                                                  The ListBox control
                             <Button Name="btnOpen"                                            The ComboBox control
            Click="btnOpen_Click">Open</Button>
                             <Button Name="btnSave"
            Click="btnSave_Click">Save</Button>
                                                                                             The ListView control
                        </WrapPanel>
          
You can try running the example and then speaking out one of the
           commands, e.g. "New" or "Open". This actually allows you to dictate text to
           the TextBox,
while at the same time invoking commands from the user
           interface - pretty cool indeed!
          
Specific commands
          
In the above example, Windows will automatically go into dictation mode as
           soon as focus is given to a text box. Windows will then try to distinguish
           between dictation and commands, but this can of course be difficult in certain
           situations.
          
So while the above examples have been focusing on dictation and interaction
           with UI elements, this next example will focus on the ability to listen for and
           interpret specific commands only. This also means that dictation will be
           ignored completely, even though text input fields have focus.
          
For this purpose, we will use the SpeechRecognitionEngine class instead
           of the SpeechRecognizer class. A huge difference
between the two is that
           the SpeechRecognitionEngine class doesn't require the Windows speech
           recognition to be running and won't take you
through the voice recognition
           guide. Instead, it will use basic voice recognition and listen only for grammar
           which you feed into the class.
          
In the next example, we'll feed a set of commands into the recognition
           engine. The idea is that it should listen for two words: A command/property
           and a
value, which in this case will be used to change the color, size and
           weight of the text in a Label control, solely based on your voice commands.
           Before I
show you the entire code sample, I want to focus on the way we add
           the commands to the engine. Here's the code:
grammarBuilder.Append(valueChoices);
speechRecognizer.LoadGrammar(new Grammar(grammarBuilder));
          
We use a GrammarBuilder to build a set of grammar rules which we can
           load into the SpeechRecognitionEngine. It has several append methods,
with
           the simplest one being Append(). This method takes a list of choices. We
           create a Choices instance, with the first part of the
instruction - the
           command/property which we want to access. These choices are added to the
           builder with the Append() method.
          
Now, each time you call an append method on the GrammarBuilder, you
           instruct it to listen for a word. In our case, we want it to listen for two words,
           so
we create a secondary set of choices, which will hold the value for the
           designated command/property. We add a range of values for each of the
           possible
commands - one set of values for the weight command, one set of
           values for the color command and one set of values for the size command.
           They're all added
to the same Choices instance and then appended to the
           builder.
          
In the end, we load it into the SpeechRecognitionEngine instance by calling
           the LoadGrammer() method, which takes a Grammar instance as
parameter
           - in this case based on our GrammarBuilder instance.
          
So, with that explained, let's take a look at the entire example:
            <Window
            x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitio
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="SpeechRecognitionCommandsSample"
            Height="200" Width="325"
                        Closing="Window_Closing">
                  <DockPanel>
                        <WrapPanel DockPanel.Dock="Bottom"
            HorizontalAlignment="Center" Margin="0,10">
                             <ToggleButton Name="btnToggleListening"
            Click="btnToggleListening_Click">Listen</ToggleButton>
                        </WrapPanel>
                        <Label Name="lblDemo" HorizontalAlignment="Center"
              VerticalAlignment="Center" FontSize="48">Hello, world!
            </Label>
                  </DockPanel>
            </Window>
using System;
            using System.Globalization;
            using System.Speech.Recognition;
            using System.Windows;
            using System.Windows.Media;
            namespace WpfTutorialSamples.Audio_and_Video
            {
            	           public partial class
            SpeechRecognitionCommandsSample : Window
            	{
            		private SpeechRecognitionEngine
            speechRecognizer = new SpeechRecognitionEngine();
            		public SpeechRecognitionCommandsSample()
            		{
            			InitializeComponent();
            			speechRecognizer.SpeechRecognized
            += speechRecognizer_SpeechRecognized;
            			GrammarBuilder grammarBuilder =
            new GrammarBuilder();
            			                               Choices commandChoices = new
            Choices("weight", "color", "size");
            			
            grammarBuilder.Append(commandChoices);
            			speechRecognizer.LoadGrammar(new
            Grammar(grammarBuilder));
            			
            speechRecognizer.SetInputToDefaultAudioDevice();
            		}
            		private void
            btnToggleListening_Click(object sender, RoutedEventArgs e)
            		{
            			if(btnToggleListening.IsChecked ==
              true)
            				
            speechRecognizer.RecognizeAsync(RecognizeMode.Multiple);
            			else
            				
            speechRecognizer.RecognizeAsyncStop();
            		}
            		private void
            speechRecognizer_SpeechRecognized(object sender,
            SpeechRecognizedEventArgs e)
            		{
            			lblDemo.Content = e.Result.Text;
            			if(e.Result.Words.Count == 2)
            			{
            				string command =
            e.Result.Words[0].Text.ToLower();
            				string value =
            e.Result.Words[1].Text.ToLower();
            				switch(command)
            				{
            					case "weight":
            						
            FontWeightConverter weightConverter = new
            FontWeightConverter();
            						
            lblDemo.FontWeight =
            (FontWeight)weightConverter.ConvertFromString(value);
            						break;
            					case "color":
            						
            lblDemo.Foreground = new
            SolidColorBrush((Color)ColorConverter.ConvertFromString(valu
            						break;
            					case "size":
            						
            switch(value)
            						{
            							
            case "small":
            							
            	           lblDemo.FontSize = 12;
            							
            	break;
            							
            case "medium":
            							
            	           lblDemo.FontSize = 24;
            							
            	break;
            							
            case "large":
            							
            	           lblDemo.FontSize = 48;
            							
            	break;
            						}
            						break;
            				}
            			}
            		}
          
On the screenshot, you see the resulting application, after I've used the voice
           commands "weight bold" and "color blue" - pretty cool, right?
          
The grammar aspects of the example has already been explained and the
           interface is very simple, so let's focus on the rest of the Code-behind.
          
We use a ToggleButton to enable or disable listening, using the
           RecognizeAsync() and RecognizeAsyncStop() methods. The
           RecognizeAsync()
takes a parameter which informs the recognition engine if
           it should do a single recognition or multiple recognitions. For our example, we
           want to give
several commands, so Multiple is used. So, to enable listening,
           just click the button, and to disable it, just click it again. The state is visually
           represented by the button, which will be "down" when enabled and normal
           when disabled.
          
Now, besides building the Grammar, the most interesting part is where we
           interpret the command. This is done in the SpeechRecognized
event, which
           we hook up to in the constructor. We use the fully recognized text to update
           the demo label, to show the latest command, and then we use the
Words
           property to dig deeper into the actual command.
          
First off, we check that it has exactly two words - a command/property and a
           value. If that is the case, we check the command part first, and for each
          
For the weight and color commands, we can convert the value into
           something the label can understand automatically, using a converter, but for
           the sizes, we
interpret the given values manually, since the values I've
           chosen for this example can't be converted automatically. Please be aware
           that you should handle
exceptions in all cases, since a command like "weight
           blue" will try to assign the value blue to the FontWeight, which will naturally
           result in an
exception.
          
Summary
          
As you can hopefully see, speech recognition with WPF is both easy and
           very powerful - especially the last example should give you a good idea just
           how
powerful! With the ability to use dictation and/or specific voice
           commands, you can really provide excellent means for alternative input in
           your
applications.
Previous
                                                                       
         
Download
                                                                        PDF!
                                                                                                  
Back to Top