RoutedEvent to Command action behavior (Blend 3).

Blend 3 has added two new assemblies which consists of new functionalities including advance behaviors

  1. Microsoft.Expression.Interactions.dll
  2. System.Windows.Interactivity.dll

These advance behavior classes lets you create attached behaviors with simplicity. Code snippet below shows how to create a behavior which can be applied on any UIElement’s Routed event and when that event is triggered the given command is invoked with its command parameters. These behaviors help us write clean code and we dont have to deal with click events when using M-V-vM pattern. We can wite our command and bind that command to any routed event on any user interface element and implement the command on view model.

Code Snippet
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Input;
  4. using System.Windows.Interactivity;
  5. using EventTrigger = System.Windows.Interactivity.EventTrigger;
  6. namespace Behaviors
  7. {
  8. /// <summary>
  9. /// Behaviour helps to bind any RoutedEvent of UIElement to Command.
  10. /// </summary>
  11. [DefaultTrigger(typeof(UIElement), typeof(EventTrigger), "MouseLeftButtonDown")]
  12. public class ExecuteCommandAction : TargetedTriggerAction<UIElement>
  13. {
  14. /// <summary>
  15. /// Dependency property represents the Command of the behaviour.
  16. /// </summary>
  17. public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
  18. “CommandParameter”,
  19. typeof(object),
  20. typeof(ExecuteCommandAction),
  21. new FrameworkPropertyMetadata(null));
  22. /// <summary>
  23. /// Dependency property represents the Command parameter of the behaviour.
  24. /// </summary>
  25. public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
  26. “Command”,
  27. typeof(ICommand),
  28. typeof(ExecuteCommandAction),
  29. new FrameworkPropertyMetadata(null));
  30. /// <summary>
  31. /// Gets or sets the Commmand.
  32. /// </summary>
  33. public ICommand Command
  34. {
  35. get
  36. {
  37. return (ICommand)this.GetValue(CommandProperty);
  38. }
  39. set
  40. {
  41. this.SetValue(CommandProperty, value);
  42. }
  43. }
  44. /// <summary>
  45. /// Gets or sets the CommandParameter.
  46. /// </summary>
  47. public object CommandParameter
  48. {
  49. get
  50. {
  51. return this.GetValue(CommandParameterProperty);
  52. }
  53. set
  54. {
  55. this.SetValue(CommandParameterProperty, value);
  56. }
  57. }
  58. /// <summary>
  59. /// Invoke method is called when the given routed event is fired.
  60. /// </summary>
  61. /// <param name=”parameter”>
  62. /// Parameter is the sender of the event.
  63. /// </param>
  64. protected override void Invoke(object parameter)
  65. {
  66. if (this.Command != null)
  67. {
  68. if (this.Command.CanExecute(this.CommandParameter))
  69. {
  70. this.Command.Execute(this.CommandParameter);
  71. }
  72. }
  73. }
  74. }
  75. \

Once you create a class with the above code and open the project in blend and open any UI, you can see the following view in the asset tab. Marked in red is our behavior.

image

Drop the behavior onto any UIElement

image

Finally you can see how we can select the Event and bind the command and command parameters in the properties tab.

image

XAML for above blend designer setting.

Code Snippet
  1. <Grid>
  2. <i:Interaction.Triggers>
  3. <i:EventTrigger EventName=”MouseLeftButtonDown”>
  4. <Behaviours:ExecuteCommandAction Command=”{Binding MyCommand}” CommandParameter=”{Binding MyCommandParameter}”/>
  5. </i:EventTrigger>
  6. </i:Interaction.Triggers>
Posted in Blend 3, Mvvm, WPF. Tags: , , . 2 Comments »

Design time support for Prism.

As we all know that Designer-Developer workflow is not feasible when the application is developed in Prism (Composite Application Guidance). Prism requires each use  case to have it’s functionality in different modules and load these modules at run-time.

Due to runtime loading of the user control neither Visual Studio or Blend can be used for implementing designer-developer workflow as the user interface cannot be seen in its entirety.

Here is what i implemented with the help of Marc Jacobs . We create an attached behavior that can be set on any ContentControl or ItemsControl. This attached behavior takes the user control which we need to display while design-time.

Code Snippet
  1. public static void OnContentChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
  2. {
  3. if (DesignerProperties.GetIsInDesignMode(depObj))
  4. {
  5. var contentControl = depObj as ContentControl;
  6. if (contentControl != null)
  7. {
  8. contentControl.Content = e.NewValue;
  9. }
  10. else
  11. {
  12. var itemsControl = depObj as ItemsControl;
  13. if (itemsControl != null)
  14. {
  15. itemsControl.Items.Add(e.NewValue);
  16. }
  17. }
  18. }
  19. \

The magic happens in the OnContentChanged method, when we set the attached behavior content this method is invoked. The code inside the method only inserts the user control in the design mode.

Code Snippet
  1. <Window x:Class=”DesignTimePrism.ShellView”
  2. xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
  3. xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
  4. xmlns:cal=”http://www.codeplex.com/CompositeWPF”
  5. xmlns:local=”clr-namespace:DesignTimePrism”
  6. xmlns:menu=”clr-namespace:DesignTimePrism.Modules.Menu;assembly=DesignTimePrism.Modules.Menu”
  7. xmlns:main=”clr-namespace:DesignTimePrism.Modules.Main;assembly=DesignTimePrism.Modules.Main”
  8. Title=”Window1″ Height=”600″ Width=”600″>
  9. <Window.Resources>
  10. <main:MainView x:Key=”mainView” />
  11. <menu:MenuView x:Key=”menuView” />
  12. </Window.Resources>
  13. <Grid>
  14. <Grid.ColumnDefinitions>
  15. <ColumnDefinition Width=”0.3*” />
  16. <ColumnDefinition Width=”0.7*” />
  17. </Grid.ColumnDefinitions>
  18. <ContentControl Grid.Column=”0″
  19. local:DesignTime.Content=”{StaticResource mainView}”
  20. cal:RegionManager.RegionName=”MenuRegion” />
  21. <ContentControl Grid.Column=”1″
  22. local:DesignTime.Content=”{StaticResource menuView}”
  23. cal:RegionManager.RegionName=”MainRegion” />
  24. </Grid>
  25. </Window>

The only downside of using this technique is having the user controls declared in the resource dictionary. Also below are the snapshots  of the application in design and runtime mode.

Design time snapshot Runtime snapshot
DesignTime RunTime

Code DesignTimePrism.zip

Posted in WPF. Tags: . 2 Comments »

WPF ConverterParameter

Just came to my knowledge and want share with people. 

<TextBlock Text=”{Binding Path=ABCD, Converter={StaticResource FormatConv}, ConverterParameter=’{0:C}’}” />

The above code wont work i know there is nothing wrong in there but still compiler would complianed about it.

One needs to add {}  in the ConverterParameter value and that will solve the problem.

ConverterParameter=’{}{0:C}’

Posted in WPF. Tags: . Leave a Comment »

WPF Dispatcher using PriorityQueue

I am sure everyone using WPF know about Dispacther and how it works but i was more curious to see how it implementes the work prioritization. So i opened the Reflector and disassembled the System.Windows.Threading dll.

private PriorityQueue PriorityQueue();

For people who do not know about PriorityQueues please visit http://en.wikipedia.org/wiki/PriorityQueue

The best part about the priority queues is that user can tell execution of which workitem is more important than the other.

Microsoft should have exposed the PriorityQueue they have implemented to the developers in the collections namespace, reason being lot of realtime systems use priority queues.

Dispacther class uses following enumeration for prioritization.

public enumDispatcherPriority
{
ApplicationIdle = 2,
Background = 4,
ContextIdle = 3,
DataBind = 8,
Inactive = 0,
Input = 5,
Invalid = -1,
Loaded = 6,
Normal = 9,
Render = 7,
Send = 10,
SystemIdle = 1
}

Posted in WPF. Tags: . Leave a Comment »