Category Archives: Programming

Creating custom tooltips in WPF

I needed to display a tooltip and wanted it to look a little fancier than the standard one.

First off, here’s how we might create a standard tooltip

<StackPanel Orientation="Horizontal" ToolTip="{Binding ItemName}">
</StackPanel>

Ofcourse we can also expand a ToolTip to allow us to define more interesting content than just the string, like this

<StackPanel Orientation="Horizontal">
   <StackPanel.ToolTip>
      <ToolTip>
         <!-- UI Elements and Bindings -->
      </ToolTip>
   </StackPanel.ToolTip>
</StackPanel>

That’s all there is to it.

Active Patterns in F#

Active patterns have been causing me a few headaches, trying to understand the syntax. Let’s take a look at how we might declare an active pattern.

Note: I will be using the sample from Active Patterns (F#)

So, this is the syntax for declaring an active pattern. The Microsoft documentation states the (| .. |) brackets are known as banana clips. So we declare the types within the banana clips and separated by the | operator, such as

let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd

So you’ll notice that the syntax does not include a function name, but only declares the type that the code can be matched against. Here’s an example of using this code within a pattern match

let test input =
   match input with
   | Even -> printfn "%d is even" input
   | Odd -> printfn "%d is odd" input

Now what happens is – when the function test is called with an input, for example

test 2     // this will output 2 is even

The line below the match tells F# to find the code which matches against a type Even or type Odd and run it. So in this case it will output 2 is even if we had executed the same code with the int 3 Odd would be returned from the active pattern and obvious 3 is odd will be output.

An extremely useful post on how the code can be viewed is on F Sharp Programming/Active Patterns.

To save time I’ll recreate the code here – so the declaration for the active patterns can be viewed as

type oddOrEven =
    | Even
    | Odd
 
let getChoice input = if input % 2 = 0 then Even else Odd

Thread.CurrentPrincipal keeps getting reset in WPF

I’m porting an app. to WPF from Windows Forms. In the Windows Forms application we used to store our own IPrincipal implementation object which stored info. about the user and a security token.

For example

Thread.CurrentPrincipal = 
    new UserPrincipal("username", token);

Whilst porting the code I noticed that the CurrentPrincipal kept getting reset to a GenericPrincipal object.

Long story short, in WPF we need to call the SetThreadPrincipal on the current app domain to set the principal instead of via the CurrentPrincipal property, for example

AppDomain.CurrentDomain.SetThreadPrincipal(
    new UserPrincipal("username", token));

Function overloading in F#

F# doesn’t support function overloads, so you cannot write the following

let add a b = a + b
let add a b c = a  b + c

However one thing we could do is implement a discriminated union, for example

type Addition =
    | Two of int * int
    | Three of int * int * int

let add param =
    match param with
    | Two (a, b) -> a + b
    | Three (a, b, c) -> a + b + c

Now to call the function using this code we’d write

let a = add <| Three(1, 2, 3)

// or

let a = add (Three(1, 2, 3))

in C# we would use

var a = Dsl.add(Dsl.Addition.NewThree(1, 2, 3));

Binding to the TabControl’s ItemsSource (and more)

I couldn’t come up with a good title for this post but what I really want to cover is this…

I want to create view models and have a TabControl dynamically create the TabItems for the view models and then automatically assign/associate the corresponding view to the tab’s visual tree for each view model.

Often when we create a TabControl (by the way the concepts listed here work equally well for ItemsControl types), we usually declare everything in XAML, each TabItem is bound to our ViewModel, we supply the header etc. But what I require is a more dynamic way of creating the TabControl’s TabItems via the view model.

Let’s use an example. I’m going to create a TabControl with TabItems similar to the sections within an Outlook Contact details view. So we’ll have a tab for the Contact Details, the Internet Details, the Phone Numbers and the Addresses. In this example we will supply each of the relevant ViewModels via an ObservableCollection and bind this to the TabControls ItemsSource, but before that let’s see the example view models

public class ContactDetailsViewModel
{
   public static string Name
   {
      get { return "Contact Details"; }
   }

   public string Content
   {
      get { return "Contact Details Content"; }
   }
}

The other view models will all take the same form as this one (I’ll still list them for completeness). In these example view models we’ll assume the Content property may be one of many properties that the corresponding view will bind to. i.e. we’ll end up creating many properties which in turn will get bound to a view.

As we want the TabControl to dynamically create TabItems, we’ll also need to supply the TabItem Header via the view model (or some other mechanism), so this is where the Name property comes in.

Before we look at the “outer” view model that the TabControl itself binds to, I’ll list those other view models as mentioned previously

public class InternetViewModel
{
   public static string Name
   {
      get { return "Internet"; }
   }

   public string Content
   {
      get { return "Internet Content"; }
   }
}

public class PhoneNumbersViewModel
{
   public static string Name
   {
      get { return "Phone Numbers"; }
   }

   public string Content
   {
      get { return "Phone Numbers Content"; }
   }
}

public class AddressesViewModel
{
   public static string Name
   {
      get { return "Addresses"; }
   }

   public string Content
   {
      get { return "Addresses Content"; }
   }		
}

Now let’s look at the view model which supplies the TabControl with the ItemsSource data, i.e. it encapsulates the child view models.

public class ContactViewModel
{
   public ContactViewModel()
   {
      Details = new ObservableCollection<object>
      {
         new ContactDetailsViewModel(),
         new InternetViewModel(),
         new PhoneNumbersViewModel(),
         new AddressesViewModel()
      };
   }

   public ObservableCollection<object> Details { get; private set; }
}

As you can see, we create a collection of the view models which will be used to populate the ItemsSource on the TabControl.

Let’s take a look at how we might use this view model within the view (we’ll assume the view’s DataContext has been assigned a ContactViewModel instance by whatever means you like). So this first example of our view is very basic mainly to demonstrate the ItemsSource binding, this will simply display the correct number of TabItems and set the header to the Name property from our view models

<TabControl ItemsSource="{Binding Details}">
   <TabControl.ItemContainerStyle>
      <Style TargetType="{x:Type TabItem}">
         <Setter Property="Header" Value="{Binding Name}" />
      </Style>
   </TabControl.ItemContainerStyle>
</TabControl>

Pretty minimalist, but it’s a good starting point. If you were to run the code thus far, you’ll notice that initially no tab is selected, so we could add a SelectedIndex or SelectedItem property to the TabControl and the relevant binding and view model properties to enable the selected item to be set and tracked. But for now, just click on a tab yourself. When you select a tab you’ll notice the TabItem’s content is the TypeName of the selected view model. This is good as it tells us our view model’s are connected to the TabItems, but ofcourse it’s of no use in our end application, so let’s create four UserControls, named ContactDetailsView, InternetView, PhoneNumbersView and AddessesView and simply give each of them the following

<Grid>
   <TextBlock Text="{Binding Content}" />
</Grid>

Again, in our real world app. each view would differ as would the view model’s properties, but hopefully you get the idea.

We now need to associate the view with the selected view model, a simple way to do this is as follows. Add the following to the TabControl code that we wrote earlier

<TabControl.Resources>
   <DataTemplate DataType="{x:Type tabControlViewModel:ContactDetailsViewModel}">
      <tabControlViewModel:ContactDetailsView />
   </DataTemplate>
   <DataTemplate DataType="{x:Type tabControlViewModel:InternetViewModel}">
      <tabControlViewModel:InternetView/>
   </DataTemplate>
   <DataTemplate DataType="{x:Type tabControlViewModel:PhoneNumbersViewModel}">
      <tabControlViewModel:ContactDetailsView/>
   </DataTemplate>
   <DataTemplate DataType="{x:Type tabControlViewModel:AddressesViewModel}">
      <tabControlViewModel:ContactDetailsView/>
   </DataTemplate>
</TabControl.Resources>

Now if you run the code each selected TabItem will display the corresponding view for the selected view model, using the DataTemplate to select the correct view. If you’re not convinced, for each of the views, change the TextBlock’s ForeGround colour to see that each view is different and thus a different view is display for each view model.

This is a massive step forward and we could stop at this point and be happy but…

Taking it a stage further

Note: This has not been thoroughly tested so use at your own discretion

Using the resources and DataTemplates is a good solution, but I’d rather like something like Caliburn Micro etc. where a view locator creates the view automatically for me. So let’s have a go at producing something like this.

First off our TabControl now looks like this

<TabControl ItemsSource="{Binding Details}" 
      ContentTemplateSelector="{StaticResource Selector}">
   <TabControl.ItemContainerStyle>
      <Style TargetType="{x:Type TabItem}">
         <Setter Property="Header" Value="{Binding Name}" />
      </Style>
   </TabControl.ItemContainerStyle>
</TabControl>

The change from our first version is the ContentTemplateSelector. Obviously we’ll need to add the following to the Resource section of our Window or UserControl

   <tabControlViewModel:ViewTemplateSelector x:Key="Selector"/>

Now let’s write the ViewTemplateSelector. Basically the ViewTemplateSelector is derived from the DataTemplateSelector and what will happen is – when a tab is selected, the ContentTemplateSelector will be used to call our ViewTemplateSelector’s SelectTemplate method. Our ViewTemplateSelector will handle the calls to SelectTemplate and try to locate a view in the same assembly as the view model currently associated with a tab. We try to find a view with matches the name of the view model type but without the Model suffix. So for example for our InternetViewModel, we’ll try to find an InternetView type in the same assembly as the view model. We’ll then create an instance of this and attach to a DataTemplate before returning this to the TabControl.

One thing we need to be aware of is that unless we wish to instantiate a new instance of the view every time an item is selected, we’ll need to cache the data templates.

Anyway here’s the code as I currently have it

public class ViewTemplateSelector : DataTemplateSelector
{
   private readonly Dictionary<string, DataTemplate> dataTemplates = 
                 new Dictionary<string, DataTemplate>();

   public override DataTemplate SelectTemplate(object item, DependencyObject container)
   {
      var contentPresent = container as ContentPresenter;
      if (contentPresent != null)
      {
         const string VIEWMODEL = "ViewModel";
         const string MODEL = "Model";

         if (item != null)
         {
            var type = item.GetType();
            var name = type.Name;
            if (name.EndsWith(VIEWMODEL))
            {
               name = name.Substring(0, name.Length - MODEL.Length);
               if (dataTemplates.ContainsKey(name))
                  return dataTemplates[name];

               var match = type.Assembly.GetTypes().
                      FirstOrDefault(t => t.Name == name);
               if (match != null)
               {
                  var view = Activator.CreateInstance(match) as DependencyObject;
                  if (view != null)
                  {
                     var factory = new FrameworkElementFactory(match);
                     var dataTemplate = new DataTemplate(type)
                     {
                        VisualTree = factory
                     };
                     dataTemplates.Add(name, dataTemplate);
                     return dataTemplate;
                  }
               }
            }
         }
      }
      return base.SelectTemplate(item, container);
   }
}

Now we should have a TabControl whose TabItems are generated based upon the ItemsSource collection of view models. A view is now created based upon the view name and automatically inserted into corresponding TabItem.

Unit testing native C++ code using Visual Studio

Before I begin with this post, let me state that Unit testing native code with Test Explorer explains this topic very well. So why am I writing a post on this? Well I did encounter a couple of issues and felt it worth documenting those along with the “steps” I took to when using the Microsoft unit testing solution for C++ in Visual Studio.

Let’s jump straight in – my intention is to create a simple class which has some setter and getter methods (nothing special) and test the implementations, obviously this is just a simple example but it will cover some of the fundamentals (I hope).

Here’s the steps to get a couple of Visual Studio projects up and running, one being the code we want to test, the second being for the unit tests.

  • Let’s start by creating a DLL for our library/code.
  • Open Visual Studio and create a New Project
  • Select Visual C++ Win32 Project and give it a name (mine’s named MotorController), then press OK
  • When the Win32 Application Wizard appears, press next then select DLL for Application Type, uncheck Security Development Lifecycle and check Export Symbols. I’m not going to use MFC or ATL for this so leave them unchecked, then press Finish
  • Now let’s create the unit test project
  • Select Add | New Project from the solution context menu
  • Select the Visual C++ | Test section and click on Native Unit Test Project
  • Give the unit test project a name (mine’s MotorControllerTests), then press OK
  • Before we can test anything in the MotorController project we need to reference the project
  • Right mouse click on your unit test project and select Properties
  • Select Common Properties | Framework and References
  • Press the Add New Reference button and check the project with code to be tested (i.e. my MotorController project), press OK and OK again on Properties dialog

At this point you should have two projects, one for your code and one for your unit tests. Both are DLL’s and the unit test project includes the code to run the tests via the Test Explorer.

So before we write any code and to ensure all is working, feel free to run the tests…

Select the menu item – Test | Run | Run All Tests. If all goes well, within Test Explorer, you’ll see a single test class named UnitTest1 (unless you renamed this) and a single method TestMethod1 (unless you changed this).

Now let’s go ahead and write some tests. I’m going to assume you’ve used the same names as I have for the objects etc. but feel free to change the code to suit your object names etc.

  • Rename the TEST_CLASS from UnitTest1 to MotorControllerTest and change the file name of the unit test to match (i.e. MotorControllerTest.cpp)
  • We’re going to need access to the header file for the MotorController class so add an include to the MotorControllerTest.cpp file to include the “MotorController.h” header, I’m going to simply use the following for now (i.e. I’m not going to set up the include folders in VC++)
    #include "../MotorController/MotorController.h"
    
  • We’re going to implement a couple of simple setter and getter methods to demonstrate the concepts of unit testing with Visual Studio. So to begin with let’s rename the current TEST_METHOD to getSpeed, then add another TEST_METHOD named getDirection, so your code should like like this
    TEST_CLASS(MotorControllerTest)
    {
    public:
       TEST_METHOD(getSpeed)
       {
       }
    
       TEST_METHOD(getDirection)
       {
       }    
    };
    
  • Now if we run these tests we’ll see our newly named class and two test methods are green, as we’ve not implement the code this might be a little off putting so you can always insert the Assert::Fail line into your unit test method until it’s implemented, for example
    TEST_METHOD(getSpeed)
    {
       Assert::Fail();
    }
    

    If you now run your tests (assuming you placed the Assert::Fail into your methods) they will both fail, which is as expected until such time as we implement the code to make them pass.

  • To save going through each step in creating the code, I’ll now supply the unit test code for the final tests
    TEST_CLASS(MotorControllerTest)
    {
    public:
    		
       TEST_METHOD(getSpeed)
       {
          CMotorController motor;
          motor.setSpeed(123);
    
          Assert::AreEqual(123, motor.getSpeed());
       }
    
       TEST_METHOD(getDirection)
       {
          CMotorController motor;
          motor.setDirection(Forward);
    
          Assert::AreEqual(Forward, motor.getDirection());
       }    
    };
    
  • Next let’s implement some code in the MotorController.h and MotorController.cpp
    // MotorController.h
    
    enum Direction
    {
        Forward,
        Reverse
    };
    
    // This class is exported from the MotorController.dll
    class MOTORCONTROLLER_API CMotorController {
    private:
        int speed;
        Direction direction;
    public:
    	CMotorController(void);
    
        void setSpeed(int speed);
        int getSpeed();
    
        void setDirection(Direction direction);
        Direction getDirection();
    };
    
    

    and

    // MotorController.cpp
    
    CMotorController::CMotorController()
    {
    }
    
    void CMotorController::setSpeed(int speed)
    {
        this->speed = speed;
    }
    
    int CMotorController::getSpeed()
    {
        return speed;
    }
    
    void CMotorController::setDirection(Direction direction)
    {
        this->direction = direction;
    }
    
    Direction CMotorController::getDirection()
    {
        return direction;
    }
    
  • If you run these tests you’ll find a compiler error, something along the lines of

    Error 1 error C2338: Test writer must define specialization of ToString for your class class std::basic_string,class std::allocator > __cdecl Microsoft::VisualStudio::CppUnitTestFramework::ToString(const enum Direction &). c:\program files (x86)\microsoft visual studio 11.0\vc\unittest\include\cppunittestassert.h 66 1 MotorControllerTests

    The problem here is that we’ve introduced a type which we have no ToString method for within the CppUnitTestAssert.h header, so we need to add one. Simply insert the following code before your TEST_CLASS

    namespace Microsoft{ namespace VisualStudio {namespace CppUnitTestFramework 
    {
        template<> static std::wstring ToString<Direction>(const Direction& direction) 
        { 
           return direction == Forward ? L"F" : L"R"; 
        };
    }}}
    

    The concatenation of the namespace on a single line is obviously not neccesary, I just copied the way the CppUnitTestAssert.h file had their namespace and also it ensures I can easily show you the main code for this. What does matter though is that we’ve implemented a new ToString which understands the Direction type/enum.

  • Finally, run the tests and see what the outcome is – both tests should pass, feel free to break the getter code to prove the SUT is really being tested

That should be enough to get your unit testing in VC++ up and running.

WPF Controls and Virtualization

Some of the built-in WPF control can be virtualized and some are virtualized by default. See Optimizing Performance: Controls.

I’m working on migrating a WinForm application to WPF, in doing so I happily recreated the code to load a ComboBox with a fairly large amount of data from a web service call. In the Windows Forms ComboBox this seemed to be have fairly good performance. Not so in the WPF ComboBox!

Some WPF controls, such as the ComboBox create their list control/dropdown to accommodate all items, therefore all items are rendered to the popup associated with it. It then uses a ScrollViewer to handle the scrolling of this large view object. Obviously when we’re talking about something like 10,000+ items (as I’m populating it with), clicking the dropdown button results in a very slow display of the associated popup whilst it’s busy rendering non-visible items.

What would be preferably is if we could load only the items to fit the dropdown space into the popup and have the scrollbar “think” that there’s more data, then we can “virtualize” our loading of data into the UI control.

We do this using the following code

<ComboBox ItemsSource="{Binding}">
   <ComboBox.ItemsPanel>
      <ItemsPanelTemplate>
         <VirtualizingStackPanel />
      </ItemsPanelTemplate>
   </ComboBox.ItemsPanel>
</ComboBox>

Other ItemsControl objects

In the case of the WPF ListView and ListBox, both are virtualized by default.

However, to paraphrase “Optimizing Performance: Controls”

By default WPF ListBoxes use UI virtualization when used with databinding, however if you add ListBoxItem’s explicitly the ListBox does not virtualize.

The TreeView can be enabled using the following code

<TreeView ItemsSource={Binding} VirtualizingStackPanel.IsVirtualizing="True" />

The ContextMenu can also be virtualized.

Scrolling

We might find that an ItemsControl, for example a ListBox, is slow when scrolling. In this case we can use the attached property VirtualizingStackPanel.VirtualizationMode as per

<ListBox ItemsSource={Binding} VirtualizingStackPanel.VirtualizationMode="Recycling" />

Automatically update a WPF Popup position

I wanted a means to automatically reposition a popup in relation to it’s placement target – for example I created a popup that was displayed to the right of another control (the placement target), but when the control’s parent window moved the popup (by default) does not move with it – I needed it to reposition in relation to the placement target.

So I’ve implemented the following behavior to automatically reposition the popup when the parent window is moved

public class AutoRepositionPopupBehavior : Behavior<Popup>
{
   private const int WM_MOVING = 0x0216;

   // should be moved to a helper class
   private DependencyObject GetTopmostParent(DependencyObject element)
   {
      var current = element;
      var result = element;

      while (current != null)
      {
         result = current;
         current = (current is Visual || current is Visual3D) ? 
            VisualTreeHelper.GetParent(current) :
            LogicalTreeHelper.GetParent(current);
      }
      return result;
   }

   protected override void OnAttached()
   {
      base.OnAttached();

      AssociatedObject.Loaded += (sender, e) =>
      {
         var root = GetTopmostParent(AssociatedObject.PlacementTarget) as Window;
         if (root != null)
         {
            var helper = new WindowInteropHelper(root);
            var hwndSource = HwndSource.FromHwnd(helper.Handle);
            if (hwndSource != null)
            {
               hwndSource.AddHook(HwndMessageHook);
            }
         }
      };
   }

   private IntPtr HwndMessageHook(IntPtr hWnd, 
           int msg, IntPtr wParam, 
           IntPtr lParam, ref bool bHandled)
   {
      if (msg == WM_MOVING)
      {
         Update();				
      }
      return IntPtr.Zero;
   }

   public void Update()
   {
      // force the popup to update it's position
      var mode = AssociatedObject.Placement;
      AssociatedObject.Placement = PlacementMode.Relative;
      AssociatedObject.Placement = mode;
   }
}

So to use the above code we simple use the following XAML within a popup element

<i:Interaction.Behaviors>
   <behaviors:AutoRepositionPopupBehavior />
</i:Interaction.Behaviors>

When the AssociatedObject is loaded we locate the topmost window hosting the AssociatedObject and then we hook into the message queue watching for the Window WM_MOVEING message. On each WM_MOVEING message, we update the placement of the popup. To get the Popup to recalculate its position we need to change the placement to something other than what it’s set as, i.e. it needs to change. Then when we reset the placement to our original placement, the Popup position is recalculated.

This code could be improved by checking the Placement and ensuring it changes – in the code above I simply set to PlacementMode.Relative because I know my code a different PlacementMode. Also the above code does not handle the Popup repositioning in the PlacementRectangle is used. Also my requirement doesn’t include the resizing of the PlacementTarget.

I’ll leave those changes until I need them…

Update

Seems I did need to handle resizing of the PlacementTarget so I’ve now added the following to the OnAttached method

AssociatedObject.LayoutUpdated += (sender, e) => Update();

and that appears to solve that problem.

WPF Adorners

An Adorner is a way of extending controls, generally by adding visual cues (or extra functionality). For example a visual cue might be adding drag and drop visuals when users try to drag and drop data onto a control or maybe we want to add resizing handles to controls within some form of UI design surface.

We can implement much of the same sort of visual cues and/or functionality by override the ControlTemplate or subclassing a control, but the Adorner offers a way to associate these cues/functionality to any type of control.

One example Adorner you may have seen is the validation UI whereby we see a red border around a control when validation fails and ofcourse we can extend this UI further if we wish.

Let’s take a look at how we might implement such an Adorner and use it.

Adorner

We’re going to start with a very simple Adorner which simply displays a little red triangle on a control – similar to the way Excel would when a note is attached to a cell.

Firstly, we need to create an Adorner. We subclass the Adorner class and supply a constructor which takes a UIElement, which is the element to be adorned.

public class NoteAdorner : Adorner
{
   public NoteAdorner(UIElement adornedElement) : 
      base(adornedElement)
   {
   }
}

This Adorner isn’t of much use. There’s nothing to see. So let’s write some code so that the Adorner displays our little red triangle over the AdornedElement. Remember that this is a layer on top of the AdorndedElement, in this case we’ll not do anything directly to the AdornedElement directly such as you might when handling drag and drop or the likes.

So add the following to the above class

protected override void OnRender(DrawingContext drawingContext)
{
   var adornedElementRect = new Rect(AdornedElement.RenderSize);

   const int SIZE = 10;

   var right = adornedElementRect.Right;
   var left = right - SIZE;
   var top = adornedElementRect.Top;
   var bottom = adornedElementRect.Bottom - SIZE;

   var segments = new[]
   {
      new LineSegment(new Point(left, top), true), 
      new LineSegment(new Point(right, bottom), true),
      new LineSegment(new Point(right, top), true)
   };

   var figure = new PathFigure(new Point(left, top), segments, true);
   var geometry = new PathGeometry(new[] { figure });
   drawingContext.DrawGeometry(Brushes.Red, null, geometry);
}

To apply an Adorner we need to write some code.

If you create a simple WPF application with a TextBox within it, and assuming the TextBox is named NoteTextBox, then we might write in the code behind of the Window class hosting the TextBox control

public MainWindow()
{
   InitializeComponent();

   Loaded += (sender, args) =>
   {
      var adorner = AdornerLayer.GetAdornerLayer(NoteTextBox);
      adorner.Add(new NoteAdorner(NoteTextBox));
   };
}

Note: It’s important to note that if you try and call the GetAdornerLayer on the TextBox before the controls are loaded you will get a null returned and thus cannot apply the adorner. So we need to apply it after the controls are loaded

In the above code we get the AdornerLayer for a control, in this case the TextBox named NoteTextBox, we then add the adorner to it.

If you run the above code you’ll get the triangle displayed over the top of the TextBox control.

One thing you may notice is that, if click on and the Adorned control it will not get focus. The Adorner ofcourse sits atop the AdornedControl and by default will not give focus to the underlying control. Basically we’ve added this control as an overlay to the AdornedElement, so ofcourse its higher in the z-order.

To change this behaviour we can alter the constructor of the NoteAdorner to the following

public NoteAdorner(UIElement adornedElement) : 
   base(adornedElement)
{
   IsHitTestVisible = false;
}

With the IsHitTestVisible set to false you can click on the Adorner UI and the AdornedElement will take focus.

As you’ll have noticed, the way to attach an Adorner is using code, this doesn’t fit so well with the idea of using XAML for such things, i.e. for a designer to handle such adornments. There are several examples on the web of ways to make adorners XAML friendly.

I’m going to implement a very simple attached property class to handle this. Which I’ve listed below

public class AttachedAdorner
{
   public static readonly DependencyProperty AdornerProperty = 
      DependencyProperty.RegisterAttached(
         "Adorner", typeof (Type), typeof (AttachedAdorner), 
         new FrameworkPropertyMetadata(default(Type), PropertyChangedCallback));

   private static void PropertyChangedCallback(
      DependencyObject dependencyObject, 
      DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
   {
      var frameworkElement = dependencyObject as FrameworkElement;
      if (frameworkElement != null)
      {
         frameworkElement.Loaded += Loaded;
      }
   }

   private static void Loaded(object sender, RoutedEventArgs e)
   {
      var frameworkElement = sender as FrameworkElement;
      if (frameworkElement != null)
      {
         var adorner = Activator.CreateInstance(
            GetAdorner(frameworkElement), 
            frameworkElement) as Adorner;
         if(adorner != null)
         {
            var adornerLayer = AdornerLayer.GetAdornerLayer(frameworkElement);
            adornerLayer.Add(adorner);
         }
      }
   }

   public static void SetAdorner(DependencyObject element, Type value)
   {
      element.SetValue(AdornerProperty, value);
   }

   public static Type GetAdorner(DependencyObject element)
   {
      return (Type)element.GetValue(AdornerProperty);
   }
}

And now let’s see how this might be used

<TextBox Text="Hello World" local:AttachedAdorner.Adorner="{x:Type local:NoteAdorner}" />

AdornerLayer and the AdornerDecorator

As discussed (above) – we need to get the get the adorner layer for example AdornerLayer.GetAdornerLayer(NoteTextBox) to add our adorner to. When GetAdornerLayer is called on a Visual object, the code traverses up the visual tree (starting with the supplied UIElement) looking for an Adorner layer. Then returns the first one it finds. Hence if you write your own custom control you will need to explcitly add a place holder on the ControlTemplate denoting where any adorner should be displayed – in other words where you want the adorner layer is.

So for writing our own custom control we need to put in a place holder, the place holder is an AdornerDecorator object

<AdornerDecorator>
   <ContentControl x:Name="PART_Input" />
</AdornerDecorator>

This can only contain a single child element, although ofcourse this element can contain multiple elements that can be adorned. The AdornerDecorator specifies the position of the AdornerLayer within the visual tree.

Custom Binding MarkupExtension

In my previous post MarkupExtension revisited I looked at creating a replacement “Binding” MarkupExtension.

As usual, after posting that I decided to make some changes.

Basically I wanted to create a base class which will allow me to easily create a Binding style MarkupExtension and then the subclass need only worry about the specifics for what it’s going to do. So I present the BindingBaseExtension class.

[MarkupExtensionReturnType(typeof(object))]
public abstract class BindingBaseExtension : MarkupExtension
{
   protected BindingBaseExtension()
   {			
   }

   protected BindingBaseExtension(PropertyPath path)
   {
      Path = path;
   }

   [ConstructorArgument("path")]
   public PropertyPath Path { get; set; }

   public IValueConverter Converter { get; set; }
   public object ConverterParameter { get; set; }
   public string ElementName { get; set; }
   public RelativeSource RelativeSource { get; set; }
   public object Source { get; set; }
   public bool ValidatesOnDataErrors { get; set; }  
   public bool ValidatesOnExceptions { get; set; }
   [TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
   public CultureInfo ConverterCulture { get; set; }

   public override object ProvideValue(IServiceProvider serviceProvider)
   {
      var pvt = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
      if (pvt == null)
         return null;

      var targetObject = pvt.TargetObject as DependencyObject;
      if (targetObject == null)
         return null;

      var targetProperty = pvt.TargetProperty as DependencyProperty;
      if (targetProperty == null)
         return null;

      var binding = new Binding
      {
         Path = Path,
         Converter = Converter,
         ConverterCulture = ConverterCulture,
         ConverterParameter = ConverterParameter,
         ValidatesOnDataErrors = ValidatesOnDataErrors,
         ValidatesOnExceptions = ValidatesOnExceptions,
         Mode = BindingMode.TwoWay,
         UpdateSourceTrigger = UpdateSourceTrigger.Explicit
      };

      if (ElementName != null)
         binding.ElementName = ElementName;
      if (RelativeSource != null)
         binding.RelativeSource = RelativeSource;
      if (Source != null)
         binding.Source = Source;

      var expression = BindingOperations.SetBinding(targetObject, targetProperty, binding);

      PostBinding(targetObject, targetProperty, binding, expression);

      return targetObject.GetValue(targetProperty);
   }

   protected abstract void PostBinding(DependencyObject targetObject, 
      DependencyProperty targetProperty, Binding binding,
      BindingExpressionBase expression);
}

Now I’m not going to go over the code as you can read all about it in the MarkupExtension revisited post, but suffice to say we now inherit from this class and add our extension’s code to an implementation of the PostBinding method (I’m not mad on the method name but for now it’s the best I could think of).

So our DelayBindingExtension will now look like this

public class DelayBindingExtension : BindingBaseExtension
{
   private IDisposable disposable;

   public DelayBindingExtension()
   {			
   }

   public DelayBindingExtension(PropertyPath path) 
      : base(path)
   {
   }

   public int Delay { get; set; }

   protected override void PostBinding(DependencyObject targetObject, 
      DependencyProperty targetProperty, Binding binding,
      BindingExpressionBase expression)
   {
      var subject = new Subject<EventArgs>();

      var descriptor = DependencyPropertyDescriptor.FromProperty(
                          targetProperty, 
                          targetObject.GetType());
      descriptor.AddValueChanged(targetObject, (sender, args) => subject.OnNext(args));

      subject.Throttle(TimeSpan.FromMilliseconds(Delay)).
         ObserveOn(SynchronizationContext.Current).
         Subscribe(_ => expression.UpdateSource());
   }
}

Note: Please be aware that this implementation of the delay binding extension has a possible memory leak. Basically we’re rooting the object with the call to AddValueChanged and not calling RemoveValueChanged the remove this link.