Author Archive

Hello Open Rasta

So Ryan, the apostle of everything on the web, has been spreading the gospel of Open Rasta for months. Tonight I decided that finally, I should download and give this fantastical framework a shot.

For an explanation on what OpenRasta is and is not, I shall direct you to their sites:

  1. Open Rasta Documentation
  2. Open Rasta Download Home

What I am going to do is just describe my experience trying their framework for the first time.

I am a person that likes to learn by trying so I immediately jumped to the ‘creating your first OpenRasta website’ (here). I have looked at some of Ryan’s code and have survived several conversations with Ryan over the framework. ;) I believe that is enough preparation for at least a simple tutorial.

Well I go to the modifying the web.config section and was left with a broken solution. Apparently from the time the tutorial was written and the time I downloaded the version 2.0.2039.312, the handlers and modules all moved to another assembly. I had a gut feeling it moved and when I talked to Ryan, he confirmed my suspicions. Supposedly he is going to try and update the tutorial.

In the meantime, just change …."OpenRasta.Web.OpenRastaHandler, OpenRasta"

to… "OpenRasta.Hosting.AspNet.OpenRastaHandler, OpenRasta.Hosting.AspNet"

So change the assembly reference from the OpenRasta.dll to the OpenRasta.Hosting.AspNet.dll

I assume if you are reading this you have the skill set to modify said correction for the other references.

After that I breezed through the creation of the ‘Home’ resource and the ‘Home’ handler. No duh? Any programmer can make a couple of classes. :)

I’m at the configuration section and I have to say, I love the fluent interface. Anyone who has talked to me in the past 6 months knows I love the pattern. It instantly makes any framework extremely approachable.

The tutorial has you making a manual configuration. I tried to find an auto configuration just using some intellisense with no luck. I will investigate this further. If I was going to use OpenRasta I would definitely want a convention based solution. Even with a nice fluent interface, I really don’t want to manually create all my mappings by hand.

But there is something to be said for simply creating a mapping like :

ResourceSpace.Has
    .ResourcesOfType<Home>()
    .AtUri("/home")
    .HandledBy<HomeHandler>();


I ran the app expecting the 405 method error as the tutorial predicts.. and got an empty page. I was using FireFox, so I jumped over to IE and was then greeted by the 405 error. I assume FireFox is either handling the problem gracefully or I don’t have some settings setup to display these errors. /shrug

So then I created my ‘Get’ method on my HomeHandler. One of the things that did attract me to OpenRasta was the POCO handlers. I’ve grown to appreciate very clean code with some acceptable conventions. Just makes life easier. I can focus on the domain problem and not the intricacies of any given framework.

Most of this seemingly new re-invention of HTTP as ESB, REST, Atom.. etc is interesting in that its a reexamining of a technology we use all the time. I haven’t done web development in roughly 3 years. The majority of my experience is in smart client apps. That is just the way my career and projects played out for me. The websites I created were always very basic and probably crap if judged by web developer gurus.

Anyway.

We click links and magically we get a web page. We don’t really think much about it. Sort of like turning on a light switch or starting your car. We just expect things to work and don’t really worry about it. How many drivers can actually explain a combustion engine?

There is a lot going on in the background to make the web work. This new (new to me at least) area of development is leveraging the tech the way it was supposed to be used (if I am to believe the pioneers in this arena). A lot of this is a change of perspective. And with any change of perspective it can take awhile to make the transition.

After that side trip down my ramblings, we come back to me having a handler with a Get method. Now I have graduated to a 406 error (as expected by the tutorial).

I then created my view as the tutorial suggested. Now upon trying to fluently configure.. I ran into a snag. Again the tutorial is out dated (which is fine for an open source and still growing framework).

I had to add the “OpenRasta.Codecs.WebForms.dll” to the solution.

Also the fluent configuration suggested is…

ResourceSpace.Has.ResourcesOfType<Home>()
        .AtUri("/home")
        .HandledBy<HomeHandler>()
        .AndRendededByAspx("~/Views/HomeView.aspx");

But since the AndRendededByAspx is obselete, the code should now be:

ResourceSpace.Has.ResourcesOfType<Home>()
                    .AtUri("/home")
                    .HandledBy<HomeHandler>()
                    .RenderedByAspx("~/Views/HomeView.aspx");

I then continued the tutorial until I had my Home View that displayed my lovely welcome message.

Yay! I got my first Open Rasta page to work. :)

Feel free to investigate my project at my Git Hub repository:

http://github.com/RookieOne/OpenRastaExperiment/tree/TutorialCompletion

I’m going to be continuing to change the master branch but the TutorialCompletion branch should remain unchanged.

SO check out OpenRasta and their (and my) tutorial. Its short and is a great window into viewing the web in a slightly different manner.

Thanks for your time!

Acase().for(patternType.FluentInterfaces).create()

When I was first exposed to the idea of fluent interfaces my response was… big flipping deal.

It wasn’t until I actively started using fluent interfaces in my code did I begin to see their power and elegance.

What is a fluent interface? Here is the obligatory link to wikipedia ;)

In simple terms, its returning a type instead of void in order to achieve method chaining.

The end goal of the method chaining is to provide a more readable interface and code.

First, does it break the Law of Demeter?

Law of Demeter doesn’t equal the number of periods. I am of the opinion fluent interfaces do not violate the Law of Demeter.

What is LoD? Another link to wiki and here is a link to a stack overflow on this very subject! :)

To me, Law of Demeter is about restricting communication between objects.

A common violation of LoD (imho) is the exposure of a list property on an object. I believe this serves as a good example of LoD as well as being an example on how to make a fluent interface. :)

A Person object has a name and a list of friends.

   1:      public class Person
   2:      {
   3:          public string Name { get; set; }
   4:          public List<Person> Friends { get; set; }
   5:   
   6:          public Person()
   7:          {
   8:              Friends = new List<Person>();
   9:          }
  10:      }

I could then add friends by…

 
   1:  var roger = new Person{ Name="Roger" };
   2:  roger.Friends.Add(new Person { Name = "Eddie" });
   3:  roger.Friends.Add(new Person { Name = "Freddie" });
   4:  roger.Friends.Add(new Person { Name = "Gordie" });

Now this is pretty typical, so what’s the problem?

Well my code knows WAY too much about Person. I know it has a list of friends and if they change that list to say a dictionary, I am hosed.

Not only that, but poor Person class… people can add friends to his collection without him every knowing. What if some additional logic needs to be done when adding a friend?

What if the person wants to record the birth date of every friend so they can send out birthday cards? Person is SOL.

As for Law of Demeter, my code is using the Person object to communicate through to the List<Person>. I am exposing my code to changes in Person.

Let’s change Person to eliminate this problem.

   1:      public class Person2
   2:      {
   3:          public string Name { get; set; }
   4:          private readonly List<Person2> _friends;
   5:   
   6:          public Person2()
   7:          {
   8:              _friends = new List<Person2>();
   9:          }
  10:   
  11:          public void AddFriend(Person2 friend)
  12:          {
  13:              _friends.Add(friend);
  14:          }
  15:      }

Now the only way to add a friend is through Person. Yippie!

 

   1:  var roger2 = new Person2 {Name = "Roger"};
   2:  roger2.AddFriend(new Person2 { Name = "Eddie" });
   3:  roger2.AddFriend(new Person2 { Name = "Freddie" });
   4:  roger2.AddFriend(new Person2 { Name = "Gordie" });

 

If I wanted to make this a fluent interface all I would need to do is instead of returning void, return the Person class.

   1:      public class Person3
   2:      {
   3:          public string Name { get; set; }
   4:          private readonly List<Person3> _friends;
   5:   
   6:          public Person3()
   7:          {
   8:              _friends = new List<Person3>();
   9:          }
  10:   
  11:          public Person3 AddFriend(Person3 friend)
  12:          {
  13:              _friends.Add(friend);
  14:              return this;
  15:          }
  16:      }

Now I can do the same logic like…

   1:  var roger3 = new Person3 { Name = "Roger" }
   2:                              .AddFriend(new Person3 { Name = "Eddie" })
   3:                              .AddFriend(new Person3 { Name = "Freddie" })
   4:                              .AddFriend(new Person3 { Name = "Gordie" });

That is pretty cool, but fluent interfaces really shine with the builder pattern.

This time around I want to force construction of a person through a builder and have the builder use a fluent interface. Notice my Person’s constructor and fields are private. I embed the builder class within the Person class so the builder has access to the constructor and fields. In this manner only my builder class has access to constructing a person. My builder can now act as an anti-corruption layer for Person.

   1:      public class Person4
   2:      {
   3:          private string _name;
   4:          private List<Person4> _friends;
   5:   
   6:          private Person4()
   7:          {
   8:              _friends = new List<Person4>();
   9:          }
  10:   
  11:          public Person4 AddFriend(Person4 friend)
  12:          {
  13:              _friends.Add(friend);
  14:              return this;
  15:          }
  16:   
  17:          public static PersonBuilder createAPerson()
  18:          {
  19:              return new PersonBuilder();
  20:          }
  21:   
  22:          public class PersonBuilder
  23:          {
  24:              private Person4 _person;
  25:              public PersonBuilder()
  26:              {
  27:                  _person = new Person4();
  28:              }
  29:   
  30:              public PersonBuilder named(string name)
  31:              {
  32:                  _person._name = name;
  33:                  return this;
  34:              }
  35:   
  36:              public PersonBuilder withFriend(Person4 friend)
  37:              {
  38:                  _person.AddFriend(friend);
  39:                  return this;
  40:              }
  41:   
  42:              public PersonBuilder withaFriendNamed(string name)
  43:              {
  44:                  var friend = createAPerson().named(name).finish();
  45:                  _person.AddFriend(friend);
  46:                  return this;
  47:              }
  48:   
  49:              public Person4 finish()
  50:              {
  51:                  return _person;
  52:              }
  53:          }
  54:      }

Now to create Roger and his friends I do..

 
   1:  var roger4 = Person4.createAPerson()
   2:                      .named("Roger")
   3:                      .withaFriendNamed("Eddie")
   4:                      .withaFriendNamed("Freddie")
   5:                      .withaFriendNamed("Gordie")
   6:                      .finish();       

It’s a simple example but maybe it sparked some ideas on how to use fluent interfaces to chain methods and make your code more approachable to people without Computer Science degrees. :D

JB

Coding, Blink, and the Smell Test

I’ve recently been assigned a complicated use case and have been heads down working on finishing it up.

Mostly its been a great exercise in BDD requirements / story construction. I’ve stumbled, made mistakes, corrected mistakes, etc

I am still excited about BDD stories. I think with DDD and BDD and insert jargon here… there is a drive to pass the infamous smell test.

There are the developers that just code. They apply a technology and just swing code around to solve a problem. Comments and best practices and solid design be damned. It works! So what’s the problem?

Then there are the developers that have that passion and instinct to know something is wrong. The idea is similar to Gladwell’s Blink principle. These developers first just code and refactor in solo. I relate it to a ronin samurai. Maybe a Luke Skywalker before his time with Yoda. ;)

They then discover patterns and OMG.. the lights go on and you have an epiphany. There is a great book on font design by Robin Williams called The Non-Designer’s Design & Type Books. Chapter one is called The Joshua Tree Epiphany. Here is the quick summary. She picked up a tree book and the first tree was the Joshua Tree. She said to herself, “Oh, we don’t have that kind of tree in Northern California. That is a weird-looking tree. I would know if I saw that tree, and I’ve never seen one before.” She then went outside and immediately saw that her neighbors had Joshua trees. Yet she never ‘saw’ one before because she didn’t know what they were. This principle she describes simply saying :

*Once you can name something, you’re conscious of it. You have power over it. You own it. You’re in control.*

Once developers are exposed to patterns and understand patterns, a new world is opened up to them. And beyond patterns, there are principles. I recently listened to the Hansel Minutes with ‘Uncle Bob’ on the SOLID principles. I found myself saying.. exactly! a lot. The principles just resonate ‘rightness’.

Anyway, what I am trying to say is that on the road to becoming the best developer I can be, I am at the mastering DDD / BDD / TDD stage. I know they are right because when I execute them correctly, it feels right. When I mess things up, it feels wrong. In lots of ways it feels like I am on an intellectual adventure. Maybe like Lord of the Rings. Instead of the ring weighing down Frodo the closer he got to Mount Doom… the closer I get to mastery of these concepts the better I feel about development.

So anyway.. those are some random thoughts I’ve been having lately. Hence the low number of blog posts. I’ve been using the time to read (because I need to catch up!) and to practice the esoteric art of BDD stories. My current reference is Dan North’s site.

I will update Greek Fire soon with documents mostly. I want to have a readme file about setting up the database. I also want to have BDD stories to document the requirements for the domain, etc.

How do I hide columns with a Wpf GridView?

In my current project we ran across a problem where we wanted to hide certain columns in a grid view based on domain criteria.

We looked into custom grid headers, attached properties, custom controls, etc. Every path lead to a very complex and more importantly custom solution.

I spent an afternoon playing around and came up with this solution which we are using today.

It’s simple, easy to follow, and doesn’t require any custom code. All it uses is the power of style and triggers. The biggest knock is OH NOES! you have a bit of duplication in your xaml.

What is it?

Well, you set the ‘View’ property in your style. Then you utilize style triggers to swap out the View.

Yup.. easy.. simple… no mess.

Example :

<style x:Key="listViewStyle" TargetType="ListView">
    <setter Property="View">
        </setter><setter .Value>

            <gridview>
                <gridviewcolumn Header="Name"
                                DisplayMemberBinding="{Binding Name}" />
                <gridviewcolumn Header="Salary"
                                DisplayMemberBinding="{Binding Salary}" />
            </gridview>

        </setter>

    </style><style .Triggers>
        <datatrigger Binding="{Binding HideCols}" Value="True">

            <setter Property="View">
                </setter><setter .Value>

                    <gridview>
                        <gridviewcolumn Header="Name"
                                        DisplayMemberBinding="{Binding Name}" />
                    </gridview>

                </setter>

        </datatrigger>
    </style>

Double Click Command Behavior

I recently posted how to bind an ICommand on a ViewModel to an Input binding.

I thought I would also add a post sharing an attached dependency property I use to binding ‘double click’ to an ICommand.

The xaml to use the behavior looks like : (naturally where Behaviors is my xml namespace, etc)

&lt;ListBox Style=&quot;{StaticResource ListBoxStyle}&quot;
 SelectedItem=&quot;{Binding SelectedItem}&quot;

Behaviors:DoubleClickCommandBehavior.DoubleClickCommand=&quot;{Binding EditCommand}&quot;

ItemsSource=&quot;{Binding Items}&quot;
 ItemTemplate=&quot;{StaticResource Template}&quot;&gt;
&lt;/ListBox&gt;

What follows is the code. Enjoy! – JB

   1: /// <summary>
   2: /// Double Click Command Behavior.
   3: /// Is a attached dependency property where you attach a command to execute upon the dependency object
   4: /// (control) being 'double clicked'
   5: /// </summary>
   6: /// <remarks>created by Jonathan Birkholz 7/21/08</remarks>
   7: public static class DoubleClickCommandBehavior
   8: {
   9:     #region Double Click Command Property
  10:
  11:     public static readonly DependencyProperty DoubleClickCommandProperty =
  12:         DependencyProperty.RegisterAttached("DoubleClickCommand",
  13:                                             typeof(ICommand), typeof(DoubleClickCommandBehavior),
  14:                                             new PropertyMetadata(null, DoubleClickCommandChanged));
  15:
  16:     public static ICommand GetDoubleClickCommand(DependencyObject obj)
  17:     {
  18:         return (ICommand)obj.GetValue(DoubleClickCommandProperty);
  19:     }
  20:
  21:     public static void SetDoubleClickCommand(DependencyObject obj, ICommand value)
  22:     {
  23:         obj.SetValue(DoubleClickCommandProperty, value);
  24:     }
  25:
  26:     #endregion
  27:
  28:     #region Double Click Command Parameter Property
  29:
  30:     public static readonly DependencyProperty DoubleClickCommandParameterProperty =
  31:         DependencyProperty.RegisterAttached("DoubleClickCommandParameter",
  32:                                             typeof(object), typeof(DoubleClickCommandBehavior),
  33:                                             new PropertyMetadata(null));
  34:
  35:     public static object GetDoubleClickCommandParameter(DependencyObject obj)
  36:     {
  37:         return (object)obj.GetValue(DoubleClickCommandParameterProperty);
  38:     }
  39:
  40:     public static void SetDoubleClickCommandParameter(DependencyObject obj, object value)
  41:     {
  42:         obj.SetValue(DoubleClickCommandParameterProperty, value);
  43:     }
  44:
  45:     #endregion
  46:
  47:     #region Double Click Command Changed
  48:
  49:     private static void DoubleClickCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  50:     {
  51:         Selector selector = obj as Selector;
  52:
  53:         if (selector != null)
  54:             selector.PreviewMouseLeftButtonDown += HandlePreviewMouseLeftButtonDown;
  55:     }
  56:
  57:     private static void HandlePreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseEventArgs)
  58:     {
  59:         if (mouseEventArgs.ClickCount == 2)
  60:         {
  61:             DependencyObject depObj = sender as DependencyObject;
  62:
  63:             if (depObj != null)
  64:             {
  65:                 Selector selector = depObj as Selector;
  66:
  67:                 if (selector != null)
  68:                 {
  69:                     if (selector.SelectedItem != null)
  70:                     {
  71:                         ICommand command = GetDoubleClickCommand(depObj);
  72:                         object commandParameter = GetDoubleClickCommandParameter(depObj);
  73:
  74:                         command.Execute(commandParameter);
  75:                     }
  76:                 }
  77:
  78:             }
  79:         }
  80:     }
  81:
  82:     #endregion
  83: }

How to bind custom ICommands to Input Bindings

If you are developing using any sort of V-VM-M pattern, you are already loving the awesome binding powers of Wpf.

And you should also be loving ICommand and binding buttons to ICommand properties on your VM.

What you might have discovered is that binding ICommands to Keys and other input gestures is not as easy as it was with vanilla Routed Commands.

But have no fear! There is a solution.

By utilizing Josh Smith’s Element Spy trick and creating a custom InputBinding, we can gain the functionality of binding an ICommand to a Key, etc.

Here is my custom input binding :

 

   1: public class MyInputBinding : KeyBinding
   2: {
   3:     #region Fields
   4:  
   5:     private static readonly DependencyProperty BoundCommandProperty = 
   6:                     DependencyProperty.Register("BoundCommand",
   7:                                                 typeof (ICommand),
   8:                                                 typeof (MyInputBinding),
   9:                                                 new PropertyMetadata(OnBoundCommandChanged));
  10:  
  11:     #endregion
  12:  
  13:     #region Properties
  14:  
  15:     public ICommand BoundCommand
  16:     {
  17:         get { return GetValue(BoundCommandProperty) as ICommand; }
  18:         set { SetValue(BoundCommandProperty, value);}
  19:     }
  20:  
  21:     #endregion
  22:  
  23:     #region Methods
  24:  
  25:     private static void OnBoundCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  26:     {
  27:         MyInputBinding binding = obj as MyInputBinding;
  28:  
  29:         if (binding == null) return;
  30:  
  31:         binding.Command = e.NewValue as ICommand;
  32:     }
  33:  
  34:     #endregion
  35: }

Then when you combine the use of the ElementSpy, your xaml looks like:

<Window.Resources>

    <InputBindingSandbox:ElementSpy x:Key="spy" />

</Window.Resources>


<Window.InputBindings>

    <InputBindingSandbox:MyInputBinding BoundCommand="{Binding Source={StaticResource spy},

                                                               Path=Element.DataContext.MyCommand}"

                                        Key="Enter" />

</Window.InputBindings>

Naturally the custom input binding is very simple and does not expose the Command Parameter nor the Command Target, etc. But the basic pattern is there so feel free to utilize and extend.

Happy coding!

JB

GreekFire Updates – Hello, M and Entity Framework

This update contains some big changes. You can get this source code here.

The first deployment of the source was very basic.

It didn’t really show anything new or flashy. I did dabble a bit into writing tests in a BDD fashion (or at least attempt to).

I am going to detail out some of the new changes in this source. Naturally there are tests for all the new classes and functionality.

 

IChangeSet

IChangeSet now only has the GetInserts, GetDeletes, and GetUpdates methods. My thoughts are that the ChangeSet is supposed to only be a readonly entity allowing for investigation into the Unity Of Work. Having the Add methods and Reset exposed too much functionality. A DataContext will just be coupled to its ChangeSet for now. I don’t see any harm in that coupling.

 

M Model

I created an M file to start building up my domain. I think M is fantastic! I am not a database guru by any stretch so being able to write out a domain in a very readable and manageable syntax is awesome.

module GreekFireExpense
{
    type Expense
    {
        Id : Integer64 = AutoNumber();
        Description : Text;
        Title : Text;
        Amount : Decimal28;
    } where identity Id;
    ExpenseTable : Expense*;
}

I haven’t found a sufficient manner to run the SQL scripts or the M compiler with specific arguments from VS right now. So I am still using IntelliPad to generate the SQL (I am also not a command line guru).

 

Entity Framework

After creating the database, I created an Entity Framework project. I am created a new DataContext to work with the EntityFramework.

Also the Entities from the Entity Framework do not ‘live’ past the DataContext. The DataContext manages the mapping between my Data Entities and my Domain Entities.

Greek Fire at CodePlex

The Greek Fire experiment is also being shared for all to see at CodePlex.

You can get the source code here.

The Greek Fire Experiment


ItemsSourceChanged Event using Attached Dependency Properties

If you stumble across this blog, you might have been searching for the non-existant ItemsSourceChanged event on a ListBox or ListView in Wpf.

Yeah… it isn’t there and it sucks.

But, there is a workable that I wouldn’t define as a hack. More of a Wpf extension. :D

I am a huge fan of Attached Dependency Properties. They are a perfect tool to extend the functionality of closed controls. Attached Dependency Properties also circumvent the pain of created your own custom control.

I am going to use an attached dependency property to mimic an ItemsSource Changed event.

The full code :

   1: /// <summary>
   2: /// ItemsSourceChanged Behavior uses an Attached Dependency Property
   3: /// to add and raise a rotued event whenever an ItemsControl's ItemsSource property
   4: /// changes. Also looks for INotifyCollectionChanged on the ItemsSource and raises the
   5: /// event on every collection changed event
   6: /// </summary>
   7: public static  class ItemsSourceChangedBehavior
   8: {
   9:     #region ItemsSourceChanged Property
  10:  
  11:     /// <summary>
  12:     /// ItemsSourceChanged Attached Dependency Property with Callback method
  13:     /// </summary>
  14:     public static readonly DependencyProperty ItemsSourceChangedProperty =
  15:                                               DependencyProperty.RegisterAttached("ItemsSourceChanged",
  16:                                               typeof(bool), typeof(ItemsSourceChangedBehavior),
  17:                                               new FrameworkPropertyMetadata(false, OnItemsSourceChanged));
  18:  
  19:     /// <summary>
  20:     /// Static Get method allowing easy Xaml usage and to simplify the
  21:     /// GetValue process
  22:     /// </summary>
  23:     /// <param name="obj">The dependency obj.</param>
  24:     /// <returns>True or False</returns>
  25:     public static bool GetItemsSourceChanged(DependencyObject obj)
  26:     {
  27:         return (bool)obj.GetValue(ItemsSourceChangedProperty);
  28:     }
  29:  
  30:     /// <summary>
  31:     /// Static Set method allowing easy Xaml usage and to simplify the
  32:     /// Setvalue process
  33:     /// </summary>
  34:     /// <param name="obj">The obj.</param>
  35:     /// <param name="value">if set to <c>true</c> [value].</param>
  36:     public static void SetItemsSourceChanged(DependencyObject obj, bool value)
  37:     {
  38:         obj.SetValue(ItemsSourceChangedProperty, value);
  39:     }
  40:  
  41:     /// <summary>
  42:     /// Dependency Property Changed Call Back method. This will be called anytime
  43:     /// the ItemsSourceChangedProperty value changes on a Dependency Object
  44:     /// </summary>
  45:     /// <param name="obj">The obj.</param>
  46:     /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
  47:     private static void OnItemsSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  48:     {
  49:         ItemsControl itemsControl = obj as ItemsControl;
  50:  
  51:         if (itemsControl == null)
  52:             return;
  53:  
  54:         bool oldValue = (bool)e.OldValue;
  55:         bool newValue = (bool)e.NewValue;
  56:  
  57:         if (!oldValue && newValue) // If changed from false to true
  58:         {           
  59:             // Create a binding to the ItemsSourceProperty on the ItemsControl
  60:             Binding b = new Binding
  61:                             {
  62:                                 Source = itemsControl,
  63:                                 Path = new PropertyPath(ItemsControl.ItemsSourceProperty)
  64:                             };
  65:  
  66:             // Since the ItemsSourceListenerProperty is now bound to the
  67:             // ItemsSourceProperty on the ItemsControl, whenever the 
  68:             // ItemsSourceProperty changes the ItemsSourceListenerProperty
  69:             // callback method will execute
  70:             itemsControl.SetBinding(ItemsSourceListenerProperty, b);
  71:         }
  72:         else if (oldValue && !newValue) // If changed from true to false
  73:         {
  74:             // Clear Binding on the ItemsSourceListenerProperty
  75:             BindingOperations.ClearBinding(itemsControl, ItemsSourceListenerProperty);
  76:         }
  77:     }
  78:  
  79:     #endregion
  80:  
  81:     #region Items Source Listener Property
  82:  
  83:     /// <summary>
  84:     /// The ItemsSourceListener Attached Dependency Property is a private property
  85:     /// the ItemsSourceChangedBehavior will use silently to bind to the ItemsControl
  86:     /// ItemsSourceProperty.
  87:     /// Once bound, the callback method will execute anytime the ItemsSource property changes
  88:     /// </summary>
  89:     private static readonly DependencyProperty ItemsSourceListenerProperty =
  90:         DependencyProperty.RegisterAttached("ItemsSourceListener",
  91:                                             typeof(object), typeof(ItemsSourceChangedBehavior),
  92:                                             new FrameworkPropertyMetadata(null, OnItemsSourceListenerChanged));
  93:  
  94:  
  95:     /// <summary>
  96:     /// Dependency Property Changed Call Back method. This will be called anytime
  97:     /// the ItemsSourceListenerProperty value changes on a Dependency Object
  98:     /// </summary>
  99:     /// <param name="obj">The obj.</param>
 100:     /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
 101:     private static void OnItemsSourceListenerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
 102:     {
 103:         ItemsControl itemsControl = obj as ItemsControl;
 104:         
 105:         if (itemsControl == null)
 106:             return;
 107:  
 108:         INotifyCollectionChanged collection = e.NewValue as INotifyCollectionChanged;
 109:  
 110:         if (collection != null)
 111:         {
 112:             collection.CollectionChanged += delegate
 113:                                                 {
 114:                                                     itemsControl.RaiseEvent(new RoutedEventArgs(ItemsSourceChangedEvent));
 115:                                                 };
 116:  
 117:         }
 118:  
 119:         if (GetItemsSourceChanged(itemsControl))
 120:             itemsControl.RaiseEvent(new RoutedEventArgs(ItemsSourceChangedEvent));
 121:     }
 122:  
 123:     #endregion
 124:  
 125:     #region Items Source Changed Event
 126:  
 127:     /// <summary>
 128:     /// Routed Event to raise whenever the ItemsSource changes on an ItemsControl
 129:     /// </summary>
 130:     public static readonly RoutedEvent ItemsSourceChangedEvent =
 131:         EventManager.RegisterRoutedEvent("ItemsSourceChanged", 
 132:                                          RoutingStrategy.Bubble, 
 133:                                          typeof(RoutedEventHandler),
 134:                                          typeof(ItemsControl));
 135:  
 136:     #endregion
 137: }

 

By setting the ItemsSourceChanged property on any ItemsControl to true, the ItemsSourceListener property will be bound to the ItemsSource property. The ItemsSourceListener callback will be executed anytime the ItemsSource changes and therefore can raise the ItemsSourceChanged routed event.

Also if the ItemsSource implements INotifyCollectionChanged, I added a delegate so that on the CollectionChanged event, the ItemsSourceChanged event will also be raised.

Feel free to use the code and adapt it to your needs.

Peace out!

JB