Routed Event in WPF using F#

Routed events can be defined as event that navigate up or down the tree like their RoutingPolicy. Events are not a new part to Know. The important thing to notice in the Routed Events is about the Hierarchy of the controls you are using in the Events. Routed Events are a new Infrastructure given by WPF that permit events to tunnel down the tree to the target elements or Bubble up to the Root element. Routed Events are just like normal events.

RoutedEvent

Types of Routed Events

Routed Events are of Three types, which are as follows.

  • Bubbling Events

  • Tunneling Events

  • Direct Events

Tunneling Events: Tunneling events are the reverse of the Bubbling events. Tunneling Events raised first in the controls hierarchy. These events are raised by the Root elements. This allows events to tunnel down the tree.

Tunneling

Bubbling Events: Bubbling Events are those Events which are first raised by the control than raised by the other controls in the control hierarchy. It allows Bubble up to the tree till the Root Element.  First Tunneling events are raised than bubbling events raised.

Bubbling

Direct Event: Direct Event is generally raised by the control itself. The behavior of this event is same as the .net general event.

Getting Started

Step 1: Firstly open a new Project in F# using Visual Studio 2010, then select a F# WPF application template and name it like below image.

New Project Dialog Box

Step 2: Now add the below define reference.

  • PresentationCore

  • PresentationFramework

  • System

  • System.Xaml

  • UIAutomationTypes

  • WindowsBase

Step 3: When you will add all these references, your solution explorer will look like below.

Solution Explorer

Step 4: Then click on Program.fs file in Solution Explorer, Write below code in Program.fs window. Your window will look like below.

Routed Event Example 1

RoutedEvent Example1.1

RoutedEvent Example 1.1.1

RoutedEvents Example 1.1.1.1

#light
 
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Documents
open System.Windows.Input
open System.Windows.Media 
 
let fntfamily = new FontFamily("Vardana")
 
type ExmnRutdEvnts()  = class
   inherit Application() 
  
   let result = new StackPanel()
   let mutable lastDate = DateTime.Now
 
   let TypeWithoutNamespace (obj:Object) =
      let fstring = obj.GetType().ToString().Split([|'.'|])
      let rvrsvlu = List.head (List.rev (Array.toList fstring) )
      rvrsvlu.ToString()
 
   let AlPrpsEvntHndlr sender (args : RoutedEventArgs) =
      // this will Add blank line if time gap present
      let nowDate = DateTime.Now
      if ((nowDate - lastDate) > TimeSpan.FromMilliseconds(100.0)) then
         result.Children.Add(new TextBlock(new Run(" "))) |> ignore
      lastDate <- nowDate
     
      // this will display event information
      let ftxt = new TextBlock()
      ftxt.FontFamily <- fntfamily
      ftxt.Text <- Printf.sprintf "%60s %40s %40s %40s"
                                  args.RoutedEvent.Name
                                  (TypeWithoutNamespace(sender))
                                  (TypeWithoutNamespace(args.Source))
                                  (TypeWithoutNamespace(args.OriginalSource))
      result.Children.Add(ftxt) |> ignore
      let viewer = result.Parent :?> ScrollViewer
      viewer.ScrollToBottom()
  
   override this.OnStartup (args:StartupEventArgs ) =
      base.OnStartup(args)
     
      // for Creating the Window
      let wnds = new Window()
      wnds.Title <- "Wpf Routed Events Using F#"
     
      // for Creating the Grid and making it Window content
      let fgrid = new Grid()
      wnds.Content <- fgrid
     
      // this will create three rows
      let rowdef = new RowDefinition()
      rowdef.Height <- GridLength.Auto
      fgrid.RowDefinitions.Add(rowdef)
     
      let rowdef = new RowDefinition()
      rowdef.Height <- GridLength.Auto
      fgrid.RowDefinitions.Add(rowdef)
     
      let rowdef = new RowDefinition()
      rowdef.Height <- new GridLength(100.0,GridUnitType.Star)
      fgrid.RowDefinitions.Add(rowdef)
     
      // Creating Button & adding Button to the Grid
      let btn = new Button()
      btn.HorizontalAlignment <- HorizontalAlignment.Center
      btn.Margin <- new Thickness(24.0)
      btn.Padding <- new Thickness(24.0)
      fgrid.Children.Add(btn) |> ignore
 
      // Creating TextBlock & adding TextBlock to the Button.
      let text = new TextBlock()
      text.FontSize <- 24.0
      text.Text <- wnds.Title
      btn.Content <- text
     
      // Create headings to display above the ScrollViewer.
      let textHeadings = new TextBlock()
      textHeadings.FontFamily <- fntfamily
      let msg = Printf.sprintf "%60s %40s %40s %40s" "Name of Routed Event"  "Event's sender"  "Event's source"  "FinalSource"
      textHeadings.Inlines.Add(new Underline(new Run(msg)))
      fgrid.Children.Add(textHeadings) |> ignore
      Grid.SetRow(textHeadings, 1)
 
      // Create the ScrollViewer.
      let scroll = new ScrollViewer()
      fgrid.Children.Add(scroll) |> ignore
      Grid.SetRow(scroll, 2)
      // Create the StackPanel for displaying events.
      scroll.Content <- result
     
      // add event handlers
      let addHandlers (el:UIElement) =
    
         let handler sender args = AlPrpsEvntHndlr (box sender) (args:>RoutedEventArgs)
         //Keyboard
         el.PreviewKeyDown.Add(fun args -> handler el args)
         el.PreviewKeyUp.Add(fun args -> handler el args)
         el.PreviewKeyUp.Add(fun args -> handler el args)
         el.KeyDown.Add(fun args -> handler el args)
         el.KeyUp.Add(fun args -> handler el args)
 
         el.PreviewTextInput.Add(fun args -> handler el args)
         el.TextInput.Add(fun args -> handler el args)
         // Mouse
         el.MouseDown.Add(fun args -> handler el args)
         el.MouseUp.Add(fun args -> handler el args)
         el.PreviewMouseDown.Add(fun args -> handler el args)
         el.PreviewMouseUp.Add(fun args -> handler el args)
         // Stylus
         el.StylusDown.Add(fun args -> handler el args)
         el.StylusUp.Add(fun args -> handler el args)
         el.PreviewStylusDown.Add(fun args -> handler el args)
         el.PreviewStylusUp.Add(fun args -> handler el args)
         // Click
         el.AddHandler(Button.ClickEvent, new RoutedEventHandler(AlPrpsEvntHndlr))     
      let els = [ (wnds :> UIElement); (fgrid :> UIElement); (btn :> UIElement); (text:> UIElement) ]
      List.iter addHandlers els
      wnds.Show()
           
end
 
#if COMPILED
[<STAThread()>]
do
    let app =  ExmnRutdEvnts() in
    app.Run() |> ignore
#endif

Step 5: Now press F5 to execute the code.

Output

RoutedEvent Output1

RoutedEvent Output2

RoutedEvent Output 3

Summary

In this article I have discussed that how to implement the Routed Events in WPF using F#.

Up Next
    Ebook Download
    View all
    Learn
    View all