Hi there,

 

Although this post is very informative, it didn’t quite fulfill my needs.

I needed to start an asynchronous method, lazy loading some data, when a property bound to a WPF control was updated.

This is what I came up with:

 

public void UpdateInformation(string propertyValue)
{
	System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(new Action(async () =>
	{
		_cancellationTokens.ForEach(c => c.Cancel());
		using (CancellationTokenSource cancellationToken = new CancellationTokenSource())
		{
			try
			{
				_cancellationTokens.Add(cancellationToken);
				var dataResponse = await service.LoadData(propertyValue, cancellationToken);
				...
			}
			finally
			{
				_cancellationTokens.Remove(cancellationToken);
			}
		}
	}));
}

As always, feel free to ask or comment.


Cancel an async task

Published 12/20/2018 by Christian in Code
Tags: , , ,

So, I wanted to do asynchronously database search that could take a long time. But if the user refine her search criteria, the async should restart, and whatever already found records be disregarded.

Using the following Microsoft article as a template, this is what I came up with as a proof of concept.

 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/cancel-an-async-task-or-a-list-of-tasks

 

This WPF program has 3 buttons. 

Start - will cancel all already started jobs, waits for 5 sec. and then download some content from a msdn site.

Cancel All - will simply cancel all started jobs.

Clear - will cancel all started jobs, and clear any messages.

 

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;

// Add a using directive and a reference for System.Net.Http.
using System.Net.Http;

// Add the following using directive for System.Threading.
using System.Threading;

namespace CancelATask
{
    public partial class MainWindow : Window
    {
        // ***Declare a System.Threading.CancellationTokenSource.
        List<CancellationTokenSource> cts = new List<CancellationTokenSource>();

        public MainWindow()
        {
            InitializeComponent();
        }


        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
            // ***Instantiate the CancellationTokenSource.
            using (CancellationTokenSource c = new CancellationTokenSource())
            {
                cts.Add(c);

                try
                {
                    // ***Send a token to carry the message if cancellation is requested.
                    int contentLength = await AccessTheWebAsync(c.Token);
                    resultsTextBox.Text += $"\r\nLength of the downloaded string: {contentLength}.\r\n";
                }
                // *** If cancellation is requested, an OperationCanceledException results.
                catch (OperationCanceledException)
                {
                    resultsTextBox.Text += $"\r\nDownload canceled. Current no of jobs: {cts.Count}\r\n";
                }
                catch (Exception)
                {
                    resultsTextBox.Text += "\r\nDownload failed.\r\n";
                }
                cts.Remove(c);
            }
        }


        // ***Add an event handler for the Cancel button.
        private void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
        }

        private void clearButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
            resultsTextBox.Clear();
        }

        // ***Provide a parameter for the CancellationToken.
        async Task<int> AccessTheWebAsync(CancellationToken c)
        {
            HttpClient client = new HttpClient();

            resultsTextBox.Text += "Waiting for download to commence.\r\n";

            // You might need to slow things down to have a chance to cancel.
            await Task.Delay(5000, c);

            resultsTextBox.Text += "Commencing to download.\r\n";
            // GetAsync returns a Task<HttpResponseMessage>. 
            // ***The c argument carries the message if the Cancel button is chosen.
            HttpResponseMessage response = await client.GetAsync("http://msdn.microsoft.com/en-us/library/dd470362.aspx", c);

            // Retrieve the website contents from the HttpResponseMessage.
            byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

            // The result of the method is the length of the downloaded web site.
            return urlContents.Length;
        }
    }

    // Output for a successful download:

    // Ready to download.

    // Length of the downloaded string: 158125.


    // Or, if you cancel:

    // Ready to download.

    // Download canceled.
}

 

As always feel free to ask or comment.


A Simple WPF DataGrid using MVVM

Published 9/15/2017 by Christian in Code
Tags: , , ,

Her follows a simple WPF DataGrid.

In the Visual Studio Design view it look like this:

The DefaultButtonStyle and DefaultDataGrid style can be found elsewhere in this blog.

Ill include the XAML for the entire Window.

<Window x:Class="Ellab.Main.Sessions.Chamber.WPFUnitSelection.UnitSelectionView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Ellab.Main.Sessions.Chamber.WPFUnitSelection"
        mc:Ignorable="d"
        Title="{Binding Title}" x:Name="MainWindow" Height="300" Width="750">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Ellab.WPF;component/View/Styles/ButtonStyle.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/Ellab.WPF;component/View/Styles/DataGridStyle.xaml"/>
                <ResourceDictionary Source="MvvmResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Background="{Binding Background, FallbackValue=Red}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0" ItemsSource="{Binding Rows, FallbackValue=AllTheSmartRows}" Style="{StaticResource DefaultDataGrid}" HeadersVisibility="Column" AutoGenerateColumns="False" VerticalAlignment="Top" SelectionMode="Single" SelectionUnit="FullRow" SelectedItem="{Binding SelectedItem}">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <EventSetter Event="MouseLeftButtonDown" Handler="DataGrid_MouseLeftButtonDown"/>
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="#FF009CDD" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Header="{Binding UnitIDHeader, FallbackValue=ID}" Binding="{Binding UnitID, FallbackValue=ID}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding TypeHeader, FallbackValue=Type}" Binding="{Binding Type, FallbackValue=Type}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding UnitTypeHeader, FallbackValue=Unit Type}" Binding="{Binding UnitType, FallbackValue=Unit}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding NameHeader, FallbackValue=Name}" Binding="{Binding Name, FallbackValue=Name}" MinWidth="125" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding DescriptionHeader, FallbackValue=Description}" Binding="{Binding Description, FallbackValue=Description}" MinWidth="25" Width="*" IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>
        <Grid Grid.Row="1" Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="40">
            <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Margin="5" Command="{Binding HelpClickedCommand}" Width="30" Style="{StaticResource DefaultButtonStyle}" Background="#FF123F74">
                    <Image Source="../../Resources/Help.png"/>
                </Button>
                <Button Margin="5" Content="{Binding ViewButtonContent, FallbackValue=#View}" Command="{Binding ViewClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ViewVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding AddNewButtonContent, FallbackValue=#Add New}" Command="{Binding AddNewClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding AddNewVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding EditButtonContent, FallbackValue=#Edit}" Command="{Binding EditClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding EditVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding RemoveButtonContent, FallbackValue=#Remove}" Command="{Binding RemoveClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding RemoveVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding ImportButtonContent, FallbackValue=#Import}" Command="{Binding ImportClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ImportVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding ExportButtonContent, FallbackValue=#Export}" Command="{Binding ExportClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ExportVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding OKButtonContent, FallbackValue=#OK}" Command="{Binding OKClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding OKVisible}" IsDefault="True" MinWidth="75"/>
                <Button Margin="5" Content="{Binding CloseButtonContent, FallbackValue=#Close}" Command="{Binding CloseClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding CloseVisible}" IsCancel="True" MinWidth="75"/>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

Allthough using the MVVM design patten, I've opted to handel  event in the codebehind, as in my opinion this is View releated. Here is the event handler

namespace Ellab.Main.Sessions.Chamber.WPFUnitSelection
{
    /// <summary>
    /// Interaction logic for UnitSelectionView.xaml
    /// </summary>
    public partial class UnitSelectionView : Window
    {
        private UnitSelectionView()
        {
            InitializeComponent();
        }

        public UnitSelectionView(UnitSelectionViewModel mainContext)
            : this()
        {
            DataContext = mainContext;
        }
        private void DataGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataGridRow clickedRos = sender as DataGridRow;
            clickedRos.IsSelected = true;
        }
    }
}

As always, feel free to comment, or ask.


The System.Linq.Distinct extension returns a list (or more to the point, an IEnumerable<>) of ... surprise ... distinct items in a list.

This is all well and good for simple data types (e.g. integers). But what if you have more complex data types, and you want to get a distinct list based on a specific property.

Well - Distinct extension enumerates the Object.Equals method on all items in the list, and returns a new list list based on the result. An object is only equal to another object if they have the same hash code. So running List<T>.Distinct() would only exclude items from List<T> where T are the same object, and not items with the same information.

Say you have a Student type:

public class Student
{
    public long ID { get; set; }
    public string Name { get; set; }

    public Student(long id, string name)
    {
        ID = id;
        Name = name;
    }
}

And a Class:

public class Class
{
    private List<Student> _students { get; } = new List<Student>() { new Student(1, "John Doe"), new Student(1, "John Doe"), new Student(2, "Jane Doe") };
}

Running 

IEnumerable<Student> distinctStudent = _students.Distinct();

would give you 3 items, as both "John Doe" have unique HashCode - they are not the same object.

There are two ways of getting about this.

Either override Object.Equals(object obj) and Object.GetHashCode() on the Student type:

public class Student
{
    public long ID { get; set; }
    public string Name { get; set; }

    public Student(long id, string name)
    {
        ID = id;
        Name = name;
    }

    public override bool Equals(object obj)
    {
        var student = obj as Student;
        return this.ID.Equals(student?.ID);
    }
    public override int GetHashCode()
    {
        return ID.GetHashCode();
    }
    public override string ToString()
    {
        return Name;
    }
}

This executes fairly fast, but you would only be able to get unique items based on their ID.

If you want a more customisable way, you could write an extension:

public static class Extensions
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        HashSet<TKey> seenKeys = new HashSet<TKey>();
        foreach (TSource item in source)
        {
            if (seenKeys.Add(keySelector(item)))
            {
                yield return item;
            }
        }
    }
}

and user it like this:

public class Class
{
    private List<Student> _students { get; } = new List<Student>() { new Student(1, "John Doe"), new Student(1, "John Doe"), new Student(2, "Jane Doe") };

    public IEnumerable<Student> GetDistinct()
    {
        return _students.Distinct();
    }

    public IEnumerable<Student> GetDistinctBy()
    {
        return _students.DistinctBy(s => s.ID);
    }

    public IEnumerable<Student> GetDistinctByMore()
    {
        return _students.DistinctBy(s => new { s.ID, s.Name });
    }
}

As always, feel free to comment, or ask.


Getting an ancestor property value can be done by binding to its element name. Here's an example

<Grid Width="{Binding Width}" Margin="{Binding Margin}">
	<Border BorderBrush=" #FF17447E" BorderThickness="5">
		<StackPanel Name="MainStackPanel" Orientation="Vertical">
			<ScrollViewer Height="{Binding ElementName=MainStackPanel, Path=ActualHeight}">
				<ItemsControl ItemsSource="{Binding Rows, FallbackValue=Rows}" Background="Transparent">
					<ItemsControl.ItemsPanel>
						<ItemsPanelTemplate>
							<StackPanel Orientation="Vertical"/>
						</ItemsPanelTemplate>
					</ItemsControl.ItemsPanel>
					<ItemsControl.ItemTemplate>
						<DataTemplate>
							<ContentPresenter Content="{Binding}" Height="30"/>
						</DataTemplate>
					</ItemsControl.ItemTemplate>
				</ItemsControl>
			</ScrollViewer>
		</StackPanel>
	</Border>
</Grid>

As always, feel free to comment, or ask


WPF Controls has no ‘InvokeRequired’/’Invoke’ like WinForms, so making accessing a WPF Window/Control threadsafe can be accomplished by using the System.Windows.Threading.Dispatcher. Here are some examples. First a property: 

 

public int Progress
{
	get
	{
		if (!Dispatcher.CheckAccess())
		{
			Func<int> f = delegate () { return Progress; };
			return Dispatcher.Invoke(f);
		}

		...
	}
	set
	{
		if (!Dispatcher.CheckAccess())
		{
			Action<int> a = delegate (int progress) { Progress = progress; };
			Dispatcher.Invoke(a);
			return;
		}

		...
	}
}

 

  A void method

 

 

public void SetProgress(object obj, int progress)
{
	if (!Dispatcher.CheckAccess())
	{
		Action<object, int> a = new Action<object, int>(SetProgress);
		Dispatcher.Invoke(a, DispatcherPriority.Normal, obj, progress);
		return;
	}

	...
}

 

And lastly a method with a return value

 

 

public bool AllProcessesDone()
{
	if (!Dispatcher.CheckAccess())
	{
		Func<bool> f = new Func<bool>(AllProcessesDone);
		return Dispatcher.Invoke(f, DispatcherPriority.Normal);
	}

	...
}

 

As always, feel free to comment, or ask.

 


OK - So I’ve got a WPF DataGrid, with a DataGridTemplateColumn. The DataTemplate is a plane TextBox. When I tab through the cells, I want to select the text in the TextBox. And when I click the text in the TextBox, I also want to select it. That proved more difficult than I expected.

But hacking and slashing from this blog

http://andora.us/blog/2011/06/09/wpf-textbox-select-all-on-focus/

and this answer

http://stackoverflow.com/questions/1104164/wpf-datagridtemplatecolumn-am-i-missing-something

I came up with a solution. Although not strictly MVVM, I still think it falls under that design pattern. All View related stuff is still handled in the View.

Anyway - First of all. when you tab through the cells the first tab stop is the border of the cell, and the second is the actual TextBox.

Secondly, In WPF, the default behavior of the TextBox on focus is to put the cursor where it was the last time the TextBox had lost focus or if it hasn’t had focus yet, at the beginning.

The first problem I solved by by using the answer from stackoverflow:

<DataGridTemplateColumn.CellStyle>
	<Style TargetType="{x:Type DataGridCell}">
		<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
	</Style>
</DataGridTemplateColumn.CellStyle>

The second by following Andora block. So the hole XAML DataGrid looks like this:

<DataGrid Name="TextBlockDataGrid" ItemsSource="{Binding Path=Rows}" Style="{StaticResource DefaultSettingsDataGrid}">
	<DataGrid.Columns>
		<DataGridTextColumn Binding="{Binding Text}" IsReadOnly="True"/>
		<DataGridTemplateColumn Width="*">
			<DataGridTemplateColumn.CellStyle>
				<Style TargetType="{x:Type DataGridCell}">
					<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
				</Style>
			</DataGridTemplateColumn.CellStyle>
			<DataGridTemplateColumn.CellTemplate>
				<DataTemplate>
					<Border BorderThickness="{Binding ErrorBorderThickness}" BorderBrush="{Binding ErrorBorderBrush}">
						<TextBox Text="{Binding UserText, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 
								 HorizontalAlignment="Right" 
								 GotKeyboardFocus="TextBox_GotKeyboardFocus" 
								 PreviewMouseDown="TextBox_PreviewMouseDown"
								 Style="{StaticResource DefaultTextBox}"/>
					</Border>
				</DataTemplate>
			</DataGridTemplateColumn.CellTemplate>
		</DataGridTemplateColumn>
	</DataGrid.Columns>
</DataGrid>

And the code-behind like this:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
	try
	{
		((TextBox)sender).SelectAll();
	}
	catch { }
}

private void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
	try
	{
		// If its a triple click, select all text for the user.
		if (e.ClickCount == 3)
		{
			((TextBox)sender).SelectAll();
			return;
		}

		// Find the TextBox
		DependencyObject parent = e.OriginalSource as UIElement;
		while (parent != null && !(parent is TextBox))
		{
			parent = System.Windows.Media.VisualTreeHelper.GetParent(parent);
		}

		if (parent != null)
		{
			if (parent is TextBox)
			{
				var textBox = (TextBox)parent;
				if (!textBox.IsKeyboardFocusWithin)
				{
					// If the text box is not yet focussed, give it the focus and
					// stop further processing of this click event.
					textBox.Focus();
					e.Handled = true;
				}
			}
		}
	}
	catch { }
}

 

As always, feel free to comment, or ask.


ICommand implementation

Published 10/31/2014 by Christian
Tags: , ,

This is a small class that implements ICommand

public class RelayCommand : ICommand
{
	#region Fields
	private readonly Action<object> execute;
	private readonly Predicate<object> canExecute;
	#endregion Fields

	#region Constructors
	public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
	{
		if (execute == null)
			throw new ArgumentNullException("execute");

		this.execute = execute;
		this.canExecute = canExecute;
	}
	#endregion Constructors

	#region ICommand Members
	[DebuggerStepThrough]
	public bool CanExecute(object parameter)
	{
		return canExecute == null ? true : canExecute(parameter);
	}

	public event EventHandler CanExecuteChanged
	{
		add { CommandManager.RequerySuggested += value; }
		remove { CommandManager.RequerySuggested -= value; }
	}

	public void Execute(object parameter)
	{
		execute(parameter);
	}
	#endregion ICommand Members
}

As always, feel free to comment, or ask.


This post is about how control events, like MouseDoubleClick, MouseEnter ect., can be handled in a MVVM design

First a general Behaviour class

public static partial class Behaviours
{
	public static class EventBehaviourFactory
	{
		public static DependencyProperty CreateCommandExecutionEventBehaviour(RoutedEvent routedEvent, string propertyName, Type ownerType)
		{
			DependencyProperty property = DependencyProperty.RegisterAttached(propertyName, typeof(ICommand), ownerType,
				new PropertyMetadata(null,
					new ExecuteCommandOnRoutedEventBehaviour(routedEvent).PropertyChangedHandler));

			return property;
		}

		/// <summary>
		/// An internal class to handle listening for an event and executing a command,
		/// when a Command is assigned to a particular DependencyProperty
		/// </summary>
		private class ExecuteCommandOnRoutedEventBehaviour : ExecuteCommandBehaviour
		{
			private readonly RoutedEvent _routedEvent;

			public ExecuteCommandOnRoutedEventBehaviour(RoutedEvent routedEvent)
			{
				_routedEvent = routedEvent;
			}

			/// <summary>
			/// Handles attaching or Detaching Event handlers when a Command is assigned or unassigned
			/// </summary>
			/// <param name="sender"></param>
			/// <param name="oldValue"></param>
			/// <param name="newValue"></param>
			protected override void AdjustEventHandlers(DependencyObject sender, object oldValue, object newValue)
			{
				UIElement element = sender as UIElement;
				if (element == null) { return; }

				if (oldValue != null)
				{
					element.RemoveHandler(_routedEvent, new RoutedEventHandler(EventHandler));
				}

				if (newValue != null)
				{
					element.AddHandler(_routedEvent, new RoutedEventHandler(EventHandler));
				}
			}

			protected void EventHandler(object sender, RoutedEventArgs e)
			{
				HandleEvent(sender, e);
			}
		}

		internal abstract class ExecuteCommandBehaviour
		{
			protected DependencyProperty _property;
			protected abstract void AdjustEventHandlers(DependencyObject sender, object oldValue, object newValue);

			protected void HandleEvent(object sender, EventArgs e)
			{
				DependencyObject dp = sender as DependencyObject;
				if (dp == null)
				{
					return;
				}

				ICommand command = dp.GetValue(_property) as ICommand;

				if (command == null)
				{
					return;
				}

				if (command.CanExecute(e))
				{
					command.Execute(e);
				}
			}

			/// <summary>
			/// Listens for a change in the DependencyProperty that we are assigned to, and
			/// adjusts the EventHandlers accordingly
			/// </summary>
			/// <param name="sender"></param>
			/// <param name="e"></param>
			public void PropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
			{
				// the first time the property changes,
				// make a note of which property we are supposed
				// to be watching
				if (_property == null)
				{
					_property = e.Property;
				}

				object oldValue = e.OldValue;
				object newValue = e.NewValue;

				AdjustEventHandlers(sender, oldValue, newValue);
			}
		}
	}
}

The ControlEventBehaviour class

public class ControlEventBehaviour
{
	#region Button
	public static readonly DependencyProperty MouseEnterCommand = Behaviours.EventBehaviourFactory.CreateCommandExecutionEventBehaviour
			 (Button.MouseEnterEvent, "MouseEnterCommand", typeof(ControlEventBehaviour));

	public static void SetMouseEnterCommand(DependencyObject o, ICommand value)
	{
		o.SetValue(MouseEnterCommand, value);
	}

	public static ICommand GetMouseEnterCommand(DependencyObject o)
	{
		return o.GetValue(MouseEnterCommand) as ICommand;
	}

	public static readonly DependencyProperty MouseLeaveCommand = Behaviours.EventBehaviourFactory.CreateCommandExecutionEventBehaviour
		 (Button.MouseLeaveEvent, "MouseLeaveCommand", typeof(ControlEventBehaviour));

	public static void SetMouseLeaveCommand(DependencyObject o, ICommand value)
	{
		o.SetValue(MouseLeaveCommand, value);
	}

	public static ICommand GetMouseLeaveCommand(DependencyObject o)
	{
		return o.GetValue(MouseLeaveCommand) as ICommand;
	}

	public static readonly DependencyProperty MouseDoubleClickCommand = Behaviours.EventBehaviourFactory.CreateCommandExecutionEventBehaviour
		 (Button.MouseDoubleClickEvent, "MouseDoubleClickCommand", typeof(ControlEventBehaviour));

	public static void SetMouseDoubleClickCommand(DependencyObject o, ICommand value)
	{
		o.SetValue(MouseDoubleClickCommand, value);
	}

	public static ICommand GetMouseDoubleClickCommand(DependencyObject o)
	{
		return o.GetValue(MouseDoubleClickCommand) as ICommand;
	}
	#endregion Button
}

The shown example only handle button events, but with slight modification can be used for all WPF controls.

In the View:

<Button Command="{Binding Path=ButtonClickCommand}"
		utilities:ControlEventBehaviour.MouseEnterCommand="{Binding Path=MouseEnter}"
		utilities:ControlEventBehaviour.MouseLeaveCommand="{Binding Path=MouseLeave}"
		utilities:ControlEventBehaviour.MouseDoubleClickCommand="{Binding Path=ButtonDoubleClick}">

And finally in the ViewModel. This is only for MouseEnter, but I'm sure that you get the gist of it :)

private RelayCommand _mouseEnter = null;
public virtual RelayCommand MouseEnter
{
	get
	{
		if (_mouseEnter == null)
		{
			_mouseEnter = new RelayCommand(param =>
			{
				try
				{
				}
				catch { }
			}, param => { return true; });
		}
		return _mouseEnter;
	}
}

As always, feel free to comment, or ask.


Stright forward, but still ...

public static class Convert
{
	public static System.Windows.Media.ImageSource ConvertImage(System.Drawing.Image image)
	{
		try
		{
			if (image != null)
			{
				var bitmap = new System.Windows.Media.Imaging.BitmapImage();
				bitmap.BeginInit();
				System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
				image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
				memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
				bitmap.StreamSource = memoryStream;
				bitmap.EndInit();
				return bitmap;
			}
		}
		catch { }
		return null;
	}
}

As always, feel free to comment, or ask.