ObservableCollection – Extension Methods

When you ever used the CollectionView of the ObservableCollection and wanted to get or set the CurrentItem you might have noticed that it requires much more typing than expected.

For that purpose I created the following extension methods for the ObservableCollection.

 

  public static class CollectionExtensions
  {
    /// <summary>
    /// This method returns the current item of the given collection.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static T GetCurrentItem<T>(this IEnumerable<T> source)
    {
      if (source == null)
        return default(T);
      var collectionView = CollectionViewSource.GetDefaultView(source);
      return (T)collectionView.CurrentItem;
    }

    /// <summary>
    /// This method returns the current position within the given collection.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static int GetCurrentPosition<T>(this IEnumerable<T> source)
    {
      if (source == null)
        return -1;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      return collectionView.CurrentPosition;
    }

    /// <summary>
    /// This method sets the current item of the given collection.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    /// <param name="item">The item which should be set as the current one.</param>
    public static void SetCurrentItem<T>(this IEnumerable<T> source, T item)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentTo(item);
    }

    /// <summary>
    /// This method moves the current item to the first.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static void MoveCurrentToFirst<T>(this IEnumerable<T> source)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentToFirst();
    }

    /// <summary>
    /// This method moves the current item to the previous.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static void MoveCurrentToPrevious<T>(this IEnumerable<T> source)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentToPrevious();
    }

    /// <summary>
    /// This method moves the current item to the next.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static void MoveCurrentToNext<T>(this IEnumerable<T> source)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentToNext();
    }

    /// <summary>
    /// This method moves the current item to the last.
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection.</typeparam>
    /// <param name="source">The collection.</param>
    public static void MoveCurrentToLast<T>(this IEnumerable<T> source)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentToLast();
    }

    /// <summary>
    /// This method sets the current position withing the given collection
    /// </summary>
    /// <typeparam name="T">The type of the elements in the collection</typeparam>
    /// <param name="source">The collection</param>
    /// <param name="index">The new position</param>
    public static void SetCurrentPosition<T>(this IEnumerable<T> source, int index)
    {
      if (source == null) return;
      var collectionView = CollectionViewSource.GetDefaultView(source);
      collectionView.MoveCurrentToPosition(index);
    }

    /// <summary>
    /// Removes the items from the collection according to the predicate.
    /// </summary>
    /// <param name="source">The source.</param>
    /// <param name="predicate">The predicate.</param>
    public static void Remove<T>(this ICollection<T> source, Func<T, bool> predicate)
    {
      if (source == null) return;
      var itemsToRemove = source.Where(predicate).ToList();
      foreach (var item in itemsToRemove)
        source.Remove(item);
    }
}

WPF – Send keys

Hi guys,

if you come from the WinForms age you might know the SendKeys class and the SendKeys.Send method, which allows you to send keys to the keyboard.
Meaning that you can simulate the pressing of a key.

But in WPF this class is no longer present. Instead of this class you can use the InputManager and feed it with the KeyEventArgs which will then be processed.
I created a small class which simplyfies this process.

public static class SendKeys
  {
    /// <summary>
    ///   Sends the specified key.
    /// </summary>
    /// <param name="key">The key.</param>
    public static void Send(Key key)
    {
      if (Keyboard.PrimaryDevice != null)
      {
        if (Keyboard.PrimaryDevice.ActiveSource != null)
        {
          var e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Down) {RoutedEvent = Keyboard.KeyDownEvent};
          InputManager.Current.ProcessInput(e1);
        }
      }
    }
  }

You can simply call the SendKeys.Send method like you did it in WinForms.

Have fun!

WPF – Custom IsSynchronizedWithCurrentItem implementation

Hi guys,

if you ever missed the IsSynchronizedWithCurrentItem property in one of your controls you might need this.
Well basically you can enable a feature using this property which is synchronizing the selected item of your Control (ListBox, ComboBox, etc.) with the current item of the collection to which you bind to.

In my case I needed this feature in the Telerik RadListBox. Therefore I created an attached property which simulates this feature.
Basically what I’m doing is the following:

  • When the SelectedItem in the ListBox was changed => update the CurrentItem in the Collection
  • When the CurrentItem in the Collection was changed => update the SelectedItem of the ListBox

The tricky part here is that the user might bind a new collection to the control. Such that you have to notice that the collection was changed and register the events for the new collection.
Therefore I used this ListBoxSources-Dictionary which contains the key value pairs of the listboxes and their corresponding collections.
If the collection is different from the one it has before we know that it was changed and have to unregister the events in the old collection and register then in the new collection.

Here is the code I was talking about:

 /// <summary>
  ///   This class contains a few useful extenders for the ListBox.
  /// </summary>
  public class RadListBoxExtensions : DependencyObject
  {
    private static readonly Dictionary<RadListBox, object> ListBoxSources = new Dictionary<RadListBox, object>();

    public static readonly DependencyProperty IsSynchronizedWithCurrentItemProperty = DependencyProperty.RegisterAttached("IsSynchronizedWithCurrentItem", typeof (bool), typeof (RadListBoxExtensions), new UIPropertyMetadata(default(bool), OnIsSynchronizedWithCurrentItemChanged));

    /// <summary>
    ///   Returns the value of the IsSynchronizedWithCurrentItemProperty
    /// </summary>
    /// <param name="obj">The dependency-object whichs value should be returned</param>
    /// <returns>The value of the given property</returns>
    public static bool GetIsSynchronizedWithCurrentItem(DependencyObject obj)
    {
      return (bool) obj.GetValue(IsSynchronizedWithCurrentItemProperty);
    }

    /// <summary>
    ///   Sets the value of the IsSynchronizedWithCurrentItemProperty
    /// </summary>
    /// <param name="obj">The dependency-object whichs value should be set</param>
    /// <param name="value">The value which should be assigned to the AutoScrollToCurrentItemProperty</param>
    public static void SetIsSynchronizedWithCurrentItem(DependencyObject obj, bool value)
    {
      obj.SetValue(IsSynchronizedWithCurrentItemProperty, value);
    }

    /// <summary>
    ///   This method will be called when the IsSynchronizedWithCurrentItem property was changed
    /// </summary>
    /// <param name="s">The sender (the RadListBox)</param>
    /// <param name="e">Some additional information</param>
    public static void OnIsSynchronizedWithCurrentItemChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
    {
      var listBox = s as RadListBox;
      if (listBox != null)
      {
        var newValue = (bool) e.NewValue;
        var selectionChangedWorker = new SelectionChangedEventHandler((s1, e2) => OnSelectionChanged(listBox, listBox.SelectedItem));
        if (newValue)
        {
          listBox.Loaded += OnLoaded;
          listBox.SelectionChanged += selectionChangedWorker;
        }
        else
        {
          listBox.Loaded -= OnLoaded;
          listBox.SelectionChanged -= selectionChangedWorker;
        }
      }
    }

    /// <summary>
    ///   Called when when the listbox was loaded.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">
    ///   The <see cref="DependencyPropertyChangedEventArgs" /> instance containing the event data.
    /// </param>
    private static void OnLoaded(object sender, RoutedEventArgs e)
    {
      var listBox = sender as RadListBox;
      if (listBox == null)
        return;
      var collection = listBox.ItemsSource;
      ActivateCollectionIfNecessary(listBox, collection);
    }

    /// <summary>
    ///   Called when the selection was changed.
    /// </summary>
    /// <param name="listBox">The list box.</param>
    /// <param name="selectedItem">The selected item.</param>
    private static void OnSelectionChanged(RadListBox listBox, object selectedItem)
    {
      var collection = listBox.ItemsSource;
      ActivateCollectionIfNecessary(listBox, collection);
      var defaultView = CollectionViewSource.GetDefaultView(collection);
      if (defaultView != null)
        defaultView.MoveCurrentTo(selectedItem);
    }

    /// <summary>
    ///   Activates the collection if necessary.
    /// </summary>
    /// <param name="listBox">The listbox.</param>
    /// <param name="collection">The collection.</param>
    private static void ActivateCollectionIfNecessary(RadListBox listBox, object collection)
    {
      if (!ListBoxSources.ContainsKey(listBox))
        ListBoxSources.Add(listBox, collection);
      else if (ListBoxSources[listBox] == collection)
        return;
      var oldCollection = ListBoxSources[listBox];
      var newView = CollectionViewSource.GetDefaultView(collection);
      var currentChangedWorker = new EventHandler((s1, e2) => listBox.SelectedItem = newView.CurrentItem);

      if (oldCollection != null)
      {
        var oldView = CollectionViewSource.GetDefaultView(oldCollection);
        if (oldView != null)
          oldView.CurrentChanged -= currentChangedWorker;
      }
      ListBoxSources[listBox] = collection;

      if (newView != null)
      {
        newView.CurrentChanged += currentChangedWorker;
        listBox.SelectedItem = newView.CurrentItem;
      }
    }
}

Have fun!

WPF MouseDown / MouseUp Command

Maybe you wanted to bind a command to the MouseDown Event of the Button.
But there is just the Command for the Click Event. Therefore it is necessary to do a little bit of coding.

I usually need the MouseDown / MouseUp Events of the Button for several use cases.
Therefore I just created a simple behavior which contains two command properties (on for the MouseUp and one for the MouseDown event).

The MouseCommandBehavior class looks like this

public static class MouseCommandBehavior
  {
    #region Commands

    ///
    /// The comamnd which should be executed when the mouse is down
    ///
    public static readonly DependencyProperty MouseDownCommandProperty =
        DependencyProperty.RegisterAttached("MouseDownCommand",
            typeof(ICommand),
            typeof(MouseCommandBehavior),
            new FrameworkPropertyMetadata(null, (obj, e) => OnMouseCommandChanged(obj, (ICommand)e.NewValue, false)));

    ///
    /// Gets the MouseDownCommand property
    ///
    public static ICommand GetMouseDownCommand(DependencyObject d)
    {
      return (ICommand)d.GetValue(MouseDownCommandProperty);
    }

    ///
    /// Sets the MouseDownCommand property
    ///
    public static void SetMouseDownCommand(DependencyObject d, ICommand value)
    {
      d.SetValue(MouseDownCommandProperty, value);
    }

    ///
    /// The comamnd which should be executed when the mouse is up
    ///
    public static readonly DependencyProperty MouseUpCommandProperty =
        DependencyProperty.RegisterAttached("MouseUpCommand",
            typeof(ICommand),
            typeof(MouseCommandBehavior),
            new FrameworkPropertyMetadata(null, new PropertyChangedCallback((obj, e) => OnMouseCommandChanged(obj, (ICommand)e.NewValue, true))));

    ///
    /// Gets the MouseUpCommand property
    ///
    public static ICommand GetMouseUpCommand(DependencyObject d)
    {
      return (ICommand)d.GetValue(MouseUpCommandProperty);
    }

    ///
    /// Sets the MouseUpCommand property
    ///
    public static void SetMouseUpCommand(DependencyObject d, ICommand value)
    {
      d.SetValue(MouseUpCommandProperty, value);
    }

    #endregion

    ///
    /// Registeres the event and calls the command when it gets fired
    ///
    private static void OnMouseCommandChanged(DependencyObject d, ICommand command, bool isMouseUp)
    {
      if (command == null) return;

      var element = (FrameworkElement)d;

      if(isMouseUp)
          element.PreviewMouseUp += (obj, e) => command.Execute(null);
      else
          element.PreviewMouseDown += (obj, e) => command.Execute(null);
      }
    }
  }

I hardcoded in this class these two events. But you could even add your own ones 🙂

In the XAML-Code you can use it like that

        <button>


If you want a even more flexible approach where you can register just one Command then you can use the behavior of Sacha Barber.
Check this out WPF : Attached Commands

I attached a zip file (remove the .doc extension) which contains a complete project. It is slightly different then what I explained above but the idea is the same.

WpfApplication2.zip

Task Parallel Library (Tasks) and the GUI thread

With .Net 4 we have a very nice feature called the task parallel library.
Especially in long running applications (like database accesses, mathematical computations…) you have to run them on a different thread.

Before .Net 4 we either used the BackgroundWorker or a Thread (from the ThreadPool).

In the good old days we have even been happy with them but when you see the new tasks then you will not like them anymore 😉
With the tasks you can do much more than just running a piece of code in a worker thread but it does not guarantee that the task is not run in the GUI thread.

If that happens it can block the application which could be really annoying for us and also for the user.

In order to guarantee that the task is run in a non GUI thread we have to build our own TaskScheduler.
In the samples for the parallel programming with .net 4 is already a custom TaskScheduler (called StaTaskScheduler) http://code.msdn.microsoft.com/ParExtSamples

Usually you start your task like in this example

Task.Factory.StartNew(() => DoLongRunningOperation());

If you want to use the custom TaskScheduler (called StaTaskScheduler) then you have to start the task like in the following example

var scheduler = new StaTaskScheduler(5);
Task.Factory.StartNew(() => DoLongRunningOperation(),
                                        CancellationToken.None,
                                        TaskCreationOptions.None,
                                        scheduler);

Now we have a way in which we can be sure that our tasks are not run in the GUI thread.

With the number (5 in my example) we can define how much threads should be used by the TaskScheduler to execute our actions.

If there are not enough threads (ex. if we have 5 tasks and just 2 threads) then the tasks will automatically wait until a thread is free.

The type reference cannot find a public type named ‘MyType’

Today I had a strange problem when I wanted to define a DataTemplate of a specific type which is located in the same assembly as I wanted to use it.
The problem was that if I wrote the assembly-name in the import of the Namespace then I got the following Exception:

The type reference cannot find a public type named ‘MyType’

So after a few hours of testing and searching I finally found the solution. I just had to remove the assembly from the import of the namespace.

Now lets have a look at a simple demonstration of the problem

This is the type I want to assign to the DataTemplate

namespace MyWpfApp
{
    public class MyType
    {
        private string _description;

        public MyType(string description)
        {
            _description= description;
        }

        public string Description
        {
            get { return _description; }
        }
    }
}

In the UI I defined a DataTemplate for this type

<Window x:Class="MyWpfApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:me="clr-namespace:MyWpfApp;assembly=MyWpfApp"
    Title="MainWindow">    
    <Window.Resources>
        <DataTemplate DataType="{x:Type me:MyType}"> <!-- Here it displays the error message -->
            <StackPanel Orientation="Vertical">
                <TextBlock Text="Description" FontWeight="Bold" Margin="5"/>
                <TextBlock Text="{Binding Description}" Margin="5"/>
            </StackPanel>
        </DataTemplate>
......

This code results in the error message I talked about before.

But if you change the import of the MyWpfApp namespace then it works without problems.

<Window x:Class="MyWpfApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:me="clr-namespace:MyWpfApp" <!-- REMOVED the assembly in the namespace import to fix the problem -->
    Title="MainWindow">    
    <Window.Resources>
        <DataTemplate DataType="{x:Type me:MyType}">
            <StackPanel Orientation="Vertical">
                <TextBlock Text="Description" FontWeight="Bold" Margin="5"/>
                <TextBlock Text="{Binding Description}" Margin="5"/>
            </StackPanel>
        </DataTemplate>
......

Have fun

.NET Framework Offline Installers

A few days ago I had to install my .NET program on a PC without internet connection.
The problem was that more than 99% of the links regarding the .NET framework are these online installers.

But I found a wonderful blog post which contains the links to offline installers of all framework version.
Here it is: .NET offline installers

Have fun!