WPF – Exception Handling ”; Previous Next An exception is any error condition or an unexpected behavior that is encountered during the execution of a program. Exceptions can be raised due to many reasons, some of them are as follows − Fault in your code or in code that you call (such as a shared library), Unavailable operating system resources, Unexpected conditions that a common language runtime encounters (such as code that cannot be verified) Syntax Exceptions have the ability to transfer the flow of a program from one part to another. In .NET framework, exception handling has the following four keywords − try − In this block, the program identifies a certain condition which raises some exception. catch − The catch keyword indicates the catching of an exception. A try block is followed by one or more catch blocks to catch an exception with an exception handler at the place in a program where you want to handle the problem. finally − The finally block is used to execute a given set of statements, whether an exception is thrown or not thrown. For example, if you open a file, it must be closed whether an exception is raised or not. throw − A program throws an exception when a problem shows up. This is done using a throw keyword. The syntax to use these four keywords goes as follows − try { ///This will still trigger the exception } catch (ExceptionClassName e) { // error handling code } catch (ExceptionClassName e) { // error handling code } catch (ExceptionClassName e) { // error handling code } finally { // statements to be executed } Multiple catch statements are used in those cases where a try block can raise more than one exception depending on the situation of a program flow. Hierarchy Almost all the exception classes in the .NET framework are directly or indirectly derived from the Exception class. The most important exception classes derived from the Exception class are − ApplicationException class − It supports exceptions which are generated by programs. When developer want to define exception then class should be derived from this class. SystemException class − It is the base class for all predefined runtime system exceptions. The following hierarchy shows the standard exceptions provided by the runtime. The following table lists the standard exceptions provided by the runtime and the conditions under which you should create a derived class. Exception type Base type Description Exception Object Base class for all exceptions. SystemException Exception Base class for all runtime-generated errors. IndexOutOfRangeException SystemException Thrown by the runtime only when an array is indexed improperly. NullReferenceException SystemException Thrown by the runtime only when a null object is referenced. AccessViolationException SystemException Thrown by the runtime only when invalid memory is accessed. InvalidOperationException SystemException Thrown by methods when in an invalid state. ArgumentException SystemException Base class for all argument exceptions. ArgumentNullException ArgumentException Thrown by methods that do not allow an argument to be null. ArgumentOutOfRangeException ArgumentException Thrown by methods that verify that arguments are in a given range. ExternalException SystemException Base class for exceptions that occur or are targeted at environments outside the runtime. SEHException ExternalException Exception encapsulating Win32 structured exception handling information. Example Let’s take a simple example to understand the concept better. Start by creating a new WPF project with the name WPFExceptionHandling. Drag one textbox from the toolbox to the design window. The following XAML code creates a textbox and initializes it with some properties. <Window x:Class = “WPFExceptionHandling.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” xmlns:d = “http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = “http://schemas.openxmlformats.org/markup-compatibility/2006” xmlns:local = “clr-namespace:WPFExceptionHandling” mc:Ignorable = “d” Title = “MainWindow” Height = “350” Width = “604”> <Grid> <TextBox x:Name = “textBox” HorizontalAlignment = “Left” Height = “241” Margin = “70,39,0,0” TextWrapping = “Wrap” VerticalAlignment = “Top” Width = “453”/> </Grid> </Window> Here is the file reading with exception handling in C#. using System; using System.IO; using System.Windows; namespace WPFExceptionHandling { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ReadFile(0); } void ReadFile(int index) { string path = @”D:Test.txt”; StreamReader file = new StreamReader(path); char[] buffer = new char[80]; try { file.ReadBlock(buffer, index, buffer.Length); string str = new string(buffer); str.Trim(); textBox.Text = str; } catch (Exception e) { MessageBox.Show(“Error reading from “+ path + “nMessage = “+ e.Message); } finally { if (file != null) { file.Close(); } } } } } When you compile and execute the above code, it will produce the following window in which a text is displayed inside the textbox. When there is an exception raised or you throw it manually (as in the following code), then it will show a message box with error. using System; using System.IO; using System.Windows; namespace WPFExceptionHandling { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ReadFile(0); } void ReadFile(int index) { string path = @”D:Test.txt”; StreamReader file = new StreamReader(path); char[] buffer = new char[80]; try { file.ReadBlock(buffer, index, buffer.Length); string str = new string(buffer); throw new Exception(); str.Trim(); textBox.Text = str; } catch (Exception e) { MessageBox.Show(“Error reading from “+ path + “nMessage = “+ e.Message); } finally { if (file != null) { file.Close(); } } } } } When an exception is raised while executing the above code, it will display the following message. We recommend that you execute the above code and experiment with its features. Print Page Previous Next Advertisements ”;
Category: wpf
WPF – Debugging
WPF – Debugging ”; Previous Next It is a systematic mechanism of identifying and fixing the bugs or defects in a piece of code which are not behaving the same as you are expecting. Debugging a complex application where the subsystems are tightly coupled are not that easy, because fixing bugs in one subsystem can create bugs in another subsystem. Debugging in C# In WPF applications, programmers deal with two languages such as C# and XAML. If you are familiar with debugging in any procedural language such as C# or C/C++ and you also know the usage of break points, then you can debug the C# part of your application easily. Let’s take a simple example to demonstrate how to debug a C# code. Create a new WPF project with the name WPFDebuggingDemo. Drag four labels, three textboxes, and one button from the toolbox. Take a look at the following XAML code. <Window x:Class = “WPFDebuggingDemo.Window1” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” Title = “Window1” Height = “400” Width = “604”> <Grid> <TextBox Height = “23” Margin = “0,44,169,0” Name = “textBox1” VerticalAlignment = “Top” HorizontalAlignment = “Right” Width = “120” /> <TextBox Height = “23” Margin = “0,99,169,0” Name = “textBox2” VerticalAlignment = “Top” HorizontalAlignment = “Right” Width = “120” /> <TextBox HorizontalAlignment = “Right” Margin = “0,153,169,0” Name = “textBox3” Width = “120” Height = “23” VerticalAlignment = “Top” /> <Label Height = “28” Margin = “117,42,0,0” Name = “label1” VerticalAlignment = “Top” HorizontalAlignment = “Left” Width = “120”> Item 1</Label> <Label Height = “28” HorizontalAlignment = “Left” Margin = “117,99,0,0” Name = “label2” VerticalAlignment = “Top” Width = “120”> Item 2</Label> <Label HorizontalAlignment = “Left” Margin = “117,153,0,181” Name = “label3” Width = “120”>Item 3</Label> <Button Height = “23” HorizontalAlignment = “Right” Margin = “0,0,214,127” Name = “button1” VerticalAlignment = “Bottom” Width = “75” Click = “button1_Click”>Total</Button> <Label Height = “28” HorizontalAlignment = “Right” Margin = “0,0,169,66” Name = “label4” VerticalAlignment = “Bottom” Width = “120”/> </Grid> </Window> Given below is the C# code in which a button click event is implemented. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFDebuggingDemo { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { if (textBox1.Text.Length > 0 && textBox2.Text.Length > 0 && textBox2.Text.Length > 0) { double total = Convert.ToDouble(textBox1.Text) + Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text); label4.Content = total.ToString(); } else { MessageBox.Show(“Enter the value in all field.”); } } } } When you compile and execute the above code, it will produce the following window. Now enter values in the textboxes and press the Total button. You will get the total value after summation of all the values entered in the textboxes. If you try to enter values other than real values, then the above application will crash. To find and resolve the issue (why it is crashing), you can insert break points in the button click event. Let’s write “abc” in item 1 as shown below. Upon clicking the Total button, you will see that the program stops at the break point. Now move the cursor towards the textbox1.Text and you will see that the program is trying to add abc value with the other values which is why the program is crashing. Debugging in XAML If you are expecting the same kind of debugging in XAML, then you will be surprised to know that it is not possible yet to debug the XAML code like debugging any other procedural language code. When you hear the term debugging in XAML code, it means try and find an error. In data binding, your data doesn”t show up on screen and you don”t know why Or an issue is related to complex layouts. Or an alignment issue or issues in margin color, overlays, etc. with some extensive templates like ListBox and combo box. Debugging an XAML program is something you typically do to check if your bindings work; and if it is not working, then to check what”s wrong. Unfortunately setting breakpoints in XAML bindings isn”t possible except in Silverlight, but we can use the Output window to check for data binding errors. Let”s take a look at the following XAML code to find the error in data binding. <Window x:Class = “DataBindingOneWay.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” Title = “MainWindow” Height = “350” Width = “604”> <Grid> <StackPanel Name = “Display”> <StackPanel Orientation = “Horizontal” Margin = “50, 50, 0, 0”> <TextBlock Text = “Name: ” Margin = “10” Width = “100”/> <TextBlock Margin = “10” Width = “100” Text = “{Binding FirstName}”/> </StackPanel> <StackPanel Orientation = “Horizontal” Margin = “50,0,50,0”> <TextBlock Text = “Title: ” Margin = “10” Width = “100”/> <TextBlock Margin = “10” Width = “100” Text = “{Binding Title}” /> </StackPanel> </StackPanel> </Grid> </Window> Text properties of two text blocks are set to “Name” and “Title” statically, while other two text blocks Text properties are bind to “FirstName” and “Title” but class variables are Name and Title in Employee class which is shown below. We have intentionally written an incorrect variable name so as to understand where can we find this type of a mistake when the desired output is not shown. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DataBindingOneWay { public class Employee { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee() { Name = “Ali Ahmed”, Title = “Developer” }; return emp; } } } Here is the implementation of MainWindow class in C# code. using System; using System.Windows; using System.Windows.Controls; namespace DataBindingOneWay { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = Employee.GetEmployee(); } } } Let”s
WPF – Command Line
WPF – Command Line ”; Previous Next Command line argument is a mechanism where a user can pass a set of parameters or values to a WPF application when it is executed. These arguments are very important to control an application from outside, for example, if you want to open a Word document from the command prompt, then you can use this command “C:> start winword word1.docx” and it will open word1.docx document. Command line arguments are handled in Startup function. Following is a simple example which shows how to pass command line arguments to a WPF application. Let’s create a new WPF application with the name WPFCommandLine. Drag one textbox from the toolbox to the design window. In this example, we will pass a txt file path to our application as command line parameter. The program will read the txt file and then write all the text on the text box. The following XAML code creates a textbox and initializes it with some properties. <Window x:Class = “WPFCommandLine.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” xmlns:d = “http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = “http://schemas.openxmlformats.org/markup-compatibility/2006” xmlns:local = “clr-namespace:WPFCommandLine” mc:Ignorable = “d” Title = “MainWindow” Height = “350” Width = “525”> <Grid> <TextBox x:Name = “textBox” HorizontalAlignment = “Left” Height = “180” Margin = “100” TextWrapping = “Wrap” VerticalAlignment = “Top” Width = “300”/> </Grid> </Window> Now subscribe the Startup event in App.xaml file as shown below. <Application x:Class = “WPFCommandLine.App” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = “clr-namespace:WPFCommandLine” StartupUri = “MainWindow.xaml” Startup = “app_Startup”> <Application.Resources> </Application.Resources> </Application> Given below is the implementation of the app_Startup event in App.xaml.cs which will get the command line arguments. using System.Windows; namespace WPFCommandLine { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { public static string[] Args; void app_Startup(object sender, StartupEventArgs e) { // If no command line arguments were provided, don”t process them if (e.Args.Length == 0) return; if (e.Args.Length > 0) { Args = e.Args; } } } } Now, in the MainWindow class, the program will open the txt file and write all the text on textbox. If there is some error found, then the program will display an error message on textbox. using System; using System.IO; using System.Windows; namespace WPFCommandLine { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); String[] args = App.Args; try { // Open the text file using a stream reader. using (StreamReader sr = new StreamReader(args[0])) { // Read the stream to a string, and write // the string to the text box String line = sr.ReadToEnd(); textBox.AppendText(line.ToString()); textBox.AppendText(“n”); } } catch (Exception e) { textBox.AppendText(“The file could not be read:”); textBox.AppendText(“n”); textBox.AppendText(e.Message); } } } } When the above code is compiled and executed, it will produce a blank window with a textbox because this program needs a command line argument. So Visual Studio provides an easy way to execute your application with command line parameters. Right click on your WPF project in the solution explorer and select properties, it will display the following window. Select Debug option and write the file path in the Command line argument. Create a txt file with Test.txt and write some text in that file and save it on any location. In this case, the txt file is saved on “D:” hard drive. Save the changes in your project and compile and execute your application now. You will see the text in TextBox which the program reads from the Text.txt file. Now let’s try and change the file name on your machine from Test.txt to Test1.txt and execute your program again, then you will see that error message in the text box. We recommend that you execute the above code and follow all the steps to execute your application successfully. Print Page Previous Next Advertisements ”;
WPF – Localization
WPF – Localization ”; Previous Next Localization is the translation of application resources into localized versions for the specific cultures that the application supports. When you develop your application and your application is available in only one language, then you are limiting the number of your customers and the size of your business. If you want to increase your customer base which will also increase your business, then your product must be available and reachable to a global audience. Cost-effective localization of your product is one of the best and most economical ways to reach out to more customers. In WPF, localizable applications are very easy to create with resx file which is the simplest solution for localization. Let’s take a simple example to understand how it works − Create a new WPF project with the name WPFLocalization. In your solution explorer, you will see the Resources.resx file under Properties folder. Change the access modifier from internal to public so that it can be accessible in XAML file. Now add the following string’s name and values which we will be using in our application. Make two copies of Resources.resx file with the names Resources.en.resx and Resources.ru-RU.resx. These are naming conventions specific to language and country/region name, and it can be found on National Language Support (NLS) API Reference ( https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx ) page. Change the values in Resources.ru-RU.resx to Russian words, as shown below. Let’s go to the design window and drag three textboxes, three labels, and three buttons. In the XAML file, first add the namespace declaration to use localize resources xmlns:p = “clr-namespace:WPFLocalization.Properties” Set the properties of all the controls as shown below. In this example, we will not use hardcoded strings for the content of labels, buttons, and Title of the window in XAML file. We will be using the strings which are defined in *.resx files. For example, for the Title of window, we use the Title string which is defined in *.resx file like this “Title = “{x:Static p:Resources.Title}”” Here is the XAML file in which controls are created and initialized with different properties. <Window x:Class = “WPFLocalization.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = “clr-namespace:WPFLocalization” xmlns:p = “clr-namespace:WPFLocalization.Properties” Title = “{x:Static p:Resources.Title}” Height = “350” Width = “604”> <Grid> <TextBox x:Name = “textBox” HorizontalAlignment = “Left” Height = “23” Margin = “128,45,0,0” TextWrapping = “Wrap” VerticalAlignment = “Top” Width = “304”/> <Label x:Name = “label” Content = “{x:Static p:Resources.Name}” HorizontalAlignment = “Left” Margin = “52,45,0,0” VerticalAlignment = “Top” Width = “86”/> <TextBox x:Name = “textBox1” HorizontalAlignment = “Left” Height = “23” Margin = “128,102,0,0” TextWrapping = “Wrap” VerticalAlignment = “Top” Width = “304”/> <Label x:Name = “label1” Content = “{x:Static p:Resources.Address}” HorizontalAlignment = “Left” Margin = “52,102,0,0” VerticalAlignment = “Top” Width = “86”/> <TextBox x:Name = “textBox2” HorizontalAlignment = “Left” Height = “23” Margin = “128,157,0,0” TextWrapping = “Wrap” VerticalAlignment = “Top” Width = “80”/> <Label x:Name = “label2” Content = “{x:Static p:Resources.Age}” HorizontalAlignment = “Left” Margin = “52,157,0,0” VerticalAlignment = “Top” Width = “86”/> <Button x:Name = “button” Content = “{x:Static p:Resources.OK_Button}” HorizontalAlignment = “Left” Margin = “163,241,0,0” VerticalAlignment = “Top” Width = “75”/> <Button x:Name = “button1” Content = “{x:Static p:Resources.Cancel_Button}” HorizontalAlignment = “Left” Margin = “282,241,0,0” VerticalAlignment = “Top” Width = “75”/> <Button x:Name = “button2” Content = “{x:Static p:Resources.Help_Button}” HorizontalAlignment = “Left” Margin = “392,241,0,0” VerticalAlignment = “Top” Width = “75”/> </Grid> </Window> When the above code is compiled and executed you will see the following window which contains different controls. By default, the program uses the default Resources.resx. If you want to show the text in Russian language which are defined in Resources.ru-RU.resx file, then you will need to set the culture explicitly when the program starts in App.xaml file as shown below. using System.Windows; namespace WPFLocalization { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { App() { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(“ru-RU”); //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(“en”); } } } When you run your application, you will see all the text in Russian language. We recommend that you execute the above code and create resx files for other cultures as well. Print Page Previous Next Advertisements ”;
WPF – Home
WPF Tutorial PDF Version Quick Guide Resources Job Search Discussion WPF stands for Windows Presentation Foundation. It is a powerful framework for building Windows applications. This tutorial explains the features that you need to understand to build WPF applications and how it brings a fundamental change in Windows applications. Audience This tutorial has been designed for all those readers who want to learn WPF and to apply it instantaneously in different type of applications. Prerequisites Before proceeding with this tutorial, you should have a basic understanding of XML, Web Technologies and HTML. Print Page Previous Next Advertisements ”;
WPF – Environment Setup
WPF – Environment Setup ”; Previous Next Microsoft provides two important tools for WPF application development. Visual Studio Expression Blend Both the tools can create WPF projects, but the fact is that Visual Studio is used more by developers, while Blend is used more often by designers. For this tutorial, we will mostly be using Visual Studio. Installation Microsoft provides a free version of Visual Studio which can be downloaded from VisualStudio. Download the files and follow the steps given below to set up WPF application development environment on your system. After the download is complete, run the installer. The following dialog will be displayed. Click the Install button and it will start the installation process. Once the installation process is completed successfully, you will get to see the following dialog box. Close this dialog box and restart your computer if required. Now open Visual Studio from the Start Menu which will open the following dialog box. Once all is done, you will see the main window of Visual Studio. You are now ready to build your first WPF application. Print Page Previous Next Advertisements ”;
WPF – Hello World
WPF – Hello World ”; Previous Next In this chapter, we will develop a simple Hello World WPF application. So let’s start the simple implementation by following the steps given below. Click on File > New > Project menu option. The following dialog box will be displayed. Under Templates, select Visual C# and in the middle panel, select WPF Application. Give the project a name. Type HelloWorld in the name field and click the OK button. By default, two files are created, one is the XAML file (mainwindow.xaml) and the other one is the CS file (mainwindow.cs) On mainwindow.xaml, you will see two sub-windows, one is the design window and the other one is the source (XAML) window. In WPF application, there are two ways to design an UI for your application. One is to simply drag and drop UI elements from the toolbox to the Design Window. The second way is to design your UI by writing XAML tags for UI elements. Visual Studio handles XAML tags when drag and drop feature is used for UI designing. In mainwindow.xaml file, the following XAML tags are written by default. <Window x:Class = “HelloWorld.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” Title = “MainWindow” Height = “350” Width = “604”> <Grid> </Grid> </Window> By default, a Grid is set as the first element after page. Let’s go to the toolbox and drag a TextBlock to the design window. You will see the TextBlock on the design window. When you look at the source window, you will see that Visual Studio has generated the XAML code of the TextBlock for you. Let’s change the Text property of TextBlock in XAML code from TextBlock to Hello World. <Window x:Class = “HelloWorld.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” Title = “MainWindow” Height = “350” Width = “604”> <Grid> <TextBlock x:Name = “textBlock” HorizontalAlignment = “Left” Margin = “235,143,0,0” TextWrapping = “Wrap” Text = “Hello World!” VerticalAlignment = “Top” Height = “44” Width = “102” /> </Grid> </Window> Now, you will see the change on the Design Window as well. When the above code is compiled and executed, you will see the following window. Congratulations! You have designed and created your first WPF application. Print Page Previous Next Advertisements ”;
WPF – Layouts
WPF – Layouts ”; Previous Next The layout of controls is very important and critical for application usability. It is used to arrange a group of GUI elements in your application. There are certain important things to consider while selecting layout panels − Positions of the child elements Sizes of the child elements Layering of overlapping child elements on top of each other Fixed pixel arrangement of controls doesn’t work when the application is to be sed on different screen resolutions. XAML provides a rich set of built-in layout panels to arrange GUI elements in an appropriate way. Some of the most commonly used and popular layout panels are as follows − Sr. No. Panels & Description 1 Stack Panel Stack panel is a simple and useful layout panel in XAML. In stack panel, child elements can be arranged in a single line, either horizontally or vertically, based on the orientation property. 2 Wrap Panel In WrapPanel, child elements are positioned in sequential order, from left to right or from top to bottom based on the orientation property. 3 Dock Panel DockPanel defines an area to arrange child elements relative to each other, either horizontally or vertically. With DockPanel you can easily dock child elements to top, bottom, right, left and center using the Dock property. 4 Canvas Panel Canvas panel is the basic layout panel in which the child elements can be positioned explicitly using coordinates that are relative to the Canvas any side such as left, right, top and bottom. 5 Grid Panel A Grid Panel provides a flexible area which consists of rows and columns. In a Grid, child elements can be arranged in tabular form. Print Page Previous Next Advertisements ”;
WPF – Routed Events
WPF – Routed Events ”; Previous Next A routed event is a type of event that can invoke handlers on multiple listeners in an element tree rather than just the object that raised the event. It is basically a CLR event that is supported by an instance of the Routed Event class. It is registered with the WPF event system. RoutedEvents have three main routing strategies which are as follows − Direct Event Bubbling Event Tunnel Event Direct Event A direct event is similar to events in Windows forms which are raised by the element in which the event is originated. Unlike a standard CLR event, direct routed events support class handling and they can be used in Event Setters and Event Triggers within your style of your Custom Control. A good example of a direct event would be the MouseEnter event. Bubbling Event A bubbling event begins with the element where the event is originated. Then it travels up the visual tree to the topmost element in the visual tree. So, in WPF, the topmost element is most likely a window. Tunnel Event Event handlers on the element tree root are invoked and then the event travels down the visual tree to all the children nodes until it reaches the element in which the event originated. The difference between a bubbling and a tunneling event is that a tunneling event will always start with a preview. In a WPF application, events are often implemented as a tunneling/bubbling pair. So, you”ll have a preview MouseDown and then a MouseDown event. Given below is a simple example of a Routed event in which a button and three text blocks are created with some properties and events. <Window x:Class = “WPFRoutedEvents.MainWindow” xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” Title = “MainWindow” Height = “450” Width = “604” ButtonBase.Click = “Window_Click” > <Grid> <StackPanel Margin = “20” ButtonBase.Click = “StackPanel_Click”> <StackPanel Margin = “10”> <TextBlock Name = “txt1” FontSize = “18” Margin = “5” Text = “This is a TextBlock 1” /> <TextBlock Name = “txt2” FontSize = “18” Margin = “5” Text = “This is a TextBlock 2” /> <TextBlock Name = “txt3” FontSize = “18” Margin = “5” Text = “This is a TextBlock 3” /> </StackPanel> <Button Margin = “10” Content = “Click me” Click = “Button_Click” Width = “80”/> </StackPanel> </Grid> </Window> Here is the C# code for the Click events implementation for Button, StackPanel, and Window. using System.Windows; namespace WPFRoutedEvents { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { txt1.Text = “Button is Clicked”; } private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = “Click event is bubbled to Stack Panel”; } private void Window_Click(object sender, RoutedEventArgs e) { txt3.Text = “Click event is bubbled to Window”; } } } When you compile and execute the above code, it will produce the following window − When you click on the button, the text blocks will get updated, as shown below. If you want to stop the routed event at any particular level, then you will need to set the e.Handled = true; Let’s change the StackPanel_Click event as shown below − private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = “Click event is bubbled to Stack Panel”; e.Handled = true; } When you click on the button, you will observe that the click event will not be routed to the window and will stop at the stackpanel and the 3rd text block will not be updated. Custom Routed Events In .NET framework, custom routed event can also be defined. You need to follow the steps given below to define a custom routed event in C#. Declare and register your routed event with system call RegisterRoutedEvent. Specify the Routing Strategy, i.e. Bubble, Tunnel, or Direct. Provide the event handler. Let’s take an example to understand more about custom routed events. Follow the steps given below − Create a new WPF project with WPFCustomRoutedEvent Right click on your solution and select Add > New Item… The following dialog will open, now select Custom Control (WPF) and name it MyCustomControl. Click the Add button and you will see that two new files (Themes/Generic.xaml and MyCustomControl.cs) will be added in your solution. The following XAML code sets the style for the custom control in Generic.xaml file. <ResourceDictionary xmlns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = “http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = “clr-namespace:WPFCustomRoutedEvent”> <Style TargetType = “{x:Type local:MyCustomControl}”> <Setter Property = “Margin” Value = “50”/> <Setter Property = “Template”> <Setter.Value> <ControlTemplate TargetType = “{x:Type local:MyCustomControl}”> <Border Background = “{TemplateBinding Background}” BorderBrush = “{TemplateBinding BorderBrush}” BorderThickness = “{TemplateBinding BorderThickness}”> <Button x:Name = “PART_Button” Content = “Click Me” /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> Given below is the C# code for the MyCustomControl class which inherits from the Control class in which a custom routed event Click is created for the custom control. using System.Windows; using System.Windows.Controls; namespace WPFCustomRoutedEvent { public class MyCustomControl : Control { static MyCustomControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); //demo purpose only, check for previous instances and remove the handler first var button = GetTemplateChild(“PART_Button”) as Button; if (button ! = null) button.Click + = Button_Click; } void Button_Click(object sender, RoutedEventArgs e) { RaiseClickEvent(); } public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(“Click”, RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyCustomControl)); public event RoutedEventHandler Click { add { AddHandler(ClickEvent, value); } remove { RemoveHandler(ClickEvent, value); } } protected virtual void RaiseClickEvent() { RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); RaiseEvent(args); } } } Here is the custom routed event implementation in C# which will display a message box when the user clicks it. using System.Windows; namespace WPFCustomRoutedEvent { // <summary> // Interaction logic for MainWindow.xaml // </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void MyCustomControl_Click(object sender, RoutedEventArgs e) { MessageBox.Show(“It is the custom routed event of your custom control”); } } } Here is the implementation in MainWindow.xaml