Tuesday, January 27, 2009

Hide a window instead of closing it in WPF

Hiding a window instead of closing it is especially useful when the window is a singleton. This is a typical situation for "options" windows which store application settings. Balaji Ramesh proposed solution to this problem, which can be found here.

    1 
    2 // Handle closing event to hide window instead of closing it
    3 Closing += delegate(object sender, CancelEventArgs e)
    4 {
    5     e.Cancel = true;
    6 
    7     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
    8         (DispatcherOperationCallback)(arg =>
    9     {
   10         Hide();
   11         return null;
   12     }), null);
   13 };

As you can see, the code is extremely simple. Everything it does is to subscribe to Window's Closing event (which is not a routed one), suppress the close action and invoke Window's Hide() method in the UI thread to actually hide the window. We could augment this code with Hiding and Hidden routed events to inform interested entities the window is hiding and when the window is hidden. Using Hiding event it's very easy to cancel window hiding as well.

But what would you do if you had dozens of windows which you would hide instead of close? Typing this code into every window constructor is by no means an option. The neat solution (at least in my opinion) is to implement this functionality as an Attached Behavior.

    1 public static readonly DependencyProperty HideInsteadCloseProperty =
    2     DependencyProperty.RegisterAttached("HideInsteadClose", 
    3     typeof(bool), typeof(WindowBehavior), new FrameworkPropertyMetadata(
    4         new PropertyChangedCallback(OnHideInsteadClose)));
    5 
    6 
    7 private static void OnHideInsteadClose(DependencyObject d,
    8     DependencyPropertyChangedEventArgs e)
    9 {
   10     var window = d as Window;
   11     if (window != null)
   12     {
   13         if ((bool)e.NewValue)
   14         {
   15             // Handle closing event to hide window instead of closing it
   16             window.Closing += delegate(object sender, CancelEventArgs args)
   17             {
   18                 args.Cancel = true;
   19 
   20                 window.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
   21                     (DispatcherOperationCallback)delegate
   22                 {
   23                     var cancelArgs = new CancelRoutedEventArgs(HidingEvent, window);
   24                     window.RaiseEvent(cancelArgs);
   25 
   26                     if (!cancelArgs.Cancel)
   27                     {
   28                         window.Hide();
   29                         window.RaiseEvent(new RoutedEventArgs(HiddenEvent, window)); 
   30                     }
   31 
   32                     return null;
   33                 }, null);
   34             };
   35         }
   36     }
   37 }


The core concept behind the above implementation is to subscribe to the Window's Close event inside HideInsteadClose attached property's change callback. Besides, we can implement Hiding and Hidden attached routed events. (this has been omitted for clarity). Using this code is as simple as adding appropriate code as Window's attribute in XAML as follows:

Common:WindowBehavior.HideInsteadClose="True" Common:WindowBehavior.Hidden="HiddenHandler"


The code is available for download from my Code Gallery here.

Monday, January 19, 2009

Mammoth Pattern Miner - cool WPF application from AGH Department of Computer Science

I'm very excited to announce that a few days ago my university's Department of Computer Science has released the first version of Mammoth Pattern Miner 2009 (MPM), an application I'm currently actively developing (not alone of course :) ). The MPM is a data mining application that is able to analyze large amount of data and discover frequent sets and sequences, partial frequent sets and some user defined patterns. It uses some well known data mining algorithms as well as some custom implementations. Of course, it provides rich visualization capabilities, many filters and extensible application architecture (by the way, which application is not extensible nowadays :P ).

Here are some screen shots from the current release (click image to enlarge it). I'll try to post a video showing the system in action when I have a little free time.

Main view


Visualization and undocked Project Explorer (yes, every window is dockable)


Yet another visualization, tree this time :)

Mammoth Pattern Miner begun as an application that accompanied my master's thesis which has been developed during my stay at UTBM in France in 2008. After I graduated, I was given the opportunity to continue working on this project at my university. To cut the long story short, I simply accepted it.

Now, Mammoth is a mature software product which provides quite big functionality. Nevertheless, there's still much work to do ;)

Just in case you are curious, Mammoth uses Microsoft's .NET Framework 3.5 SP1, WPF and SQL Server 2005. It runs pretty fast on my Lenovo T61p laptop. However, big data sets require lots of ram.

Mammoth official site, for now available in polish only, is located at http://caribou.iisg.agh.edu.pl/proj/mammoth/. If you think you or your work might benefit from using this software, please email me.

Hope you liked it!