Saturday, May 30, 2009

Changing the Orientation or Surface application

Surface supports orientation of applications to 2 sides according to the seating position of the user.If we are developing applications we have to rotate our applications our self.Its done by checking the static property Microsoft.Surface.ApplicationLauncher.Orientation.
There is an event called Microsoft.Surface.ApplicationLauncher.OrientationChanged which fires when the user changes his side by clicking on the access buttons at the corresponding side.

Setting the Orientation
We need to have a RotateTransform in our application whose Angle ,we are going to change according to the Orientation.Normally we place the RotateTransform in the root element of the SurfaceWindow.

<s:SurfaceWindow x:Class="SurfaceApplication1.SurfaceWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
Title="SurfaceApplication1">
<Grid Name="MenuGrid">
<Grid.LayoutTransform>
<RotateTransform x:Name="OrientationTransform" Angle="0"/>
</Grid.LayoutTransform>
<TextBlock Name="OrientationTextBox" HorizontalAlignment="Center"/>
</Grid>
</s:SurfaceWindow>



Subscribe to the ApplicationLauncher.OrientationChanged event and set the Angle as per the ApplicationLauncher.Orientation property.

private void AddActivationHandlers()
{
// Subscribe to surface application activation events
ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
ApplicationLauncher.OrientationChanged += ApplicationLauncher_OrientationChanged;
}
void ApplicationLauncher_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
OrientationTransform.Angle = ApplicationLauncher.Orientation == UserOrientation.Top ? 180 : 0;
OrientationTextBox.Text = ApplicationLauncher.Orientation.ToString();
}



Using Triggers to change the Orientation or Surface application based on ApplicationLauncher.Orientation.

Its clear like water that we can’t use EventTrigger to set the Angle of Transform.Another method is PropertyTrigger.Since the ApplicationLauncher.Orientation is not an AttachedProperty we can’t use that method too.Simply saying we have to write code in order to achieve.I am searching for a method which does the same using xaml alone.If anybody finds,please share with me.

Sunday, May 24, 2009

Generating and Printing Surface IdentityTag

Tags support is the most important feature in Microsoft Surface.Tags enable our application to recognize objects through surface.As you know there are 2 types of tags.Byte tag and identity tag.So before placing objects on the surface to recognize we have to print the tag and stick on the bottom part of the object.Then only surface can identify the tag value through its infrared sensing mechanism.There are 3 ways to visualize the tags.One is using the command line tool GenTag.exe and another using it’s visual tool GenTagUI.exe and last using our own programs which make use of the class IdentityTagGenerator

Using IdentityTag Image Generator
Tool is located at

[Install drive]:\Program Files\Microsoft SDKs\Surface\v1.0\Tools\GenTag\GenTag.exe

Syntax :
GenTag.exe <Series> <Value> <FileName.png> [/dpi:number]

Value and Series are in Hex.This tool outputs the tag as png image.Later we can print that image.Dots Per Inch (dpi) is optional.

Using IdentityTag printing tool
Surface now includes a tool in it’s sdk which helps us to generate and print IdentityTags.You can locate the program in start menu itself

Programs->Microsoft Surface sdk 1.0 sp1->Tools->Identity Tag Printing Tool

or in the location

[Install drive]:\Program Files\Microsoft SDKs\Surface\v1.0\Tools\GenTag\GenTagUI.exe

There is nothing to explain about using the tool I think.Try yourself.

Using IdentityTagGenerator class
Microsoft has provided API to visualize the tags and later we can save or print them.The entry to tag visualization API is IdentityTagGenerator.That class contains 2 static methods for getting tag in it’s actual form.

  • Image GenerateTag(long series,long value) : As its signature implies, it returns the tag image according to parameters series and value.There is an overload available which takes dpi as parameter and returns image according to that.
  • RenderTag(long series,long value,Point point,Graphics g) :Draws identity tag on the Graphics object.Mainly targeted to be used in Windows forms applications.Also this helps in distributing tags through asp.net applications.
In the first method we can set the returned Image object as source of image control in our application.The second method uses Graphics object and that is available in OnPaint methods or we can create it using the Graphics class.

The usage is straight forward.Seems there is no need to post a sample.

NB: Printed tag should be exactly 1.125 inches square in order to get detected by Surface.

Wednesday, May 20, 2009

Introducing Surface SP1

The first Service pack for Microsoft surface has released on May 10.It has got significant changes comparing to the older older.Here are the main features I noticed.

  1. New controls
    1. ElementMenu
    2. LibraryBar
  2. Tagged object routing
  3. Improved contact visualization
  4. Improved access points

More details here
http://blogs.msdn.com/surface/archive/2009/05/11/service-pack-1-officially-released-today.aspx
http://arstechnica.com/microsoft/news/2009/05/microsoft-surface-sp1-adds-new-features.ars

As a developer, I am more interested in the new controls and will be posting about them later.

Tuesday, May 19, 2009

WatermarkTextBox by inheriting TextBox

I am very happy to see that my previous post “WPF Watermark TextBox using XAML Style” helped a lot of peoples to solve their issues and currently that is the most popular post in my blog.That post describes about creating a WPF watermark textbox by changing it’s style.All the things are done in xaml and there is no property to set the water mark text.
There was a requirement from one of the readers for such a property.ie a Watermark property which decides the watermark text.So rewriting the sample with that property.
Here I just derived a new class called WatemarkTextBox from standard TextBox added a new dependency property called Watermark and defined default style for that control in generic.xaml.The steps are as follows

  1. Subclass TextBox and create a new class called WatermarkTextBox.
  2. Add a new DP called Watermark which is of type object.
  3. In the generic.xaml write the default style.
public class WatermarkTextBox : TextBox
{
static WatermarkTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox),
new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));
}

public object Watermark
{
get { return (object)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
// Using a DependencyProperty as the backing store for Watermark. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register(
"Watermark",
typeof(object),
typeof(WatermarkTextBox),
new UIPropertyMetadata(null));
}

And its style in generic.xaml contains almost same elements as of my last post.But here I have used TemplateBinding to set Watermark into the TextBlock.

<Style TargetType="{x:Type local:WatermarkTextBox}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush"
Value="Blue" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Padding"
Value="1" />
<Setter Property="AllowDrop"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:WatermarkTextBox}">
<Grid>
<Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd"
SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"
RenderMouseOver="{TemplateBinding IsMouseOver}">
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Microsoft_Windows_Themes:ListBoxChrome>
<TextBlock x:Name="textBlock"
Opacity="0.345"
Text="{TemplateBinding Watermark}"
TextWrapping="Wrap"
Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused"
Value="False" />
<Condition Property="Text"
Value="" />
</MultiTrigger.Conditions>
<Setter Property="Visibility"
TargetName="textBlock"
Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Download sample from here.

Saturday, May 16, 2009

MVVM CommandReference and KeyBinding

Recently when I was digging into MVVM sample in codeplex I came to notice one class named CommandReference.That class just contains a dependency property which is of ICommand.At first, I didn’t get why they created that class.But after seeing it’s application in the sample,I decided to add that in my MVVM.Core project because that was important when we come to a situation where  we need to bind a command to non dependency properties.Eg :InputBinding.Command
If you still didn’t get the importance of CommandReference just try to Bind a command to a KeyBinding as follows.

<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="N"
Command="{Binding CreateCustomerCommand}" />
</Window.InputBindings>


The result will be an Exception



A 'Binding' cannot be set on the 'Command' property of type 'KeyBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject



Reason is simple the Command property is not DependencyProperty.To get rid of this we have to use the CommandReference.The usage is as follows.



<Window.Resources>
<coreView:CommandReference x:Key="newCust"
Command="{Binding NewCustomerCommand}" />
</Window.Resources>
<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="N"
Command="{StaticResource newCust}" />
</Window.InputBindings>

See the sample for more details.This is again a modified version of Josh Smith's MVVM sample.

Friday, May 15, 2009

Magic transparent color glass using Interactions and OpacityMask

This is continuation of my previous post and this requires some knowledge about OpacityMask and the new Interactions mechanism introduced by the Blend team.

Prerequisites
Writing custom TriggerAction using Interaction to enhance MVVM
Understanding OpacityMask and its usage

What is this transparent color glass
Simply a Glass which shows a black and white image in color.The application here contains a black and white image along with a elliptical glass on it.We can see the same image in color through the glass and the glass is moving with mouse.

Basic idea of creating transparent glass
Of course there are 2 images one is color and another is black and white image of the same.In the application basically there are 3 layers inside a Canvas.One layer is again a Canvas and rest are Images.Bindings are used to make sure that all are in same size.

The canvas is at bottom ,with an ellipse inside.The second layer is the black and white image.At the top we have placed the actual color image and its opacity mask is set to make it viewable only through an elliptical portion.
The parent canvas is enabled with FollowMouseAction.It is a trigger action which enables the elements in Canvas to follow the mouse.The FollowMouseAction is bound to the MouseMove trigger.Hence it updates it’s position on mouse move.
We have to create a VisualBrush of the Canvas which is at the bottom layer to apply as OpacityMask of top layer image.Keep this as Resource.Set Stretch property of VisualBrush to None.Then set the OpacityMask of the top image to this resource.

Yes its done.Now run the project and see the glass in action.
Below are the step by step instructions to create this application.Later I will be writing about how to create color glass using Expression Blend 3

Steps

  1. Create a WPF application.
  2. Add 2 photos into application.One is the original which is in color and another is ,black and white version of the same.
  3. Add a Canvas to the Grid in Window and name it as ‘rootcanvas’ .Set its Height and Width.
  4. Add another Canvas in to rootcanvas and name it as ‘childcanvas’.Bind it’s Width and height to ActualHeight and ActualWidth of rootcanvas 
  5. Set the background property of childcanvas to any color with alpha value of 00.Eg :#00ffffff
  6. In the child canvas add an Ellipse named ‘ellipse’.Set it’s color to Red.Set Height and Width.
  7. Add 2 images into parentcanvas.Bind Width and Height in to ActualWidth and ActualHeight of rootcanvas.
  8. Set black and white photo to the first image(middle layer)and color photo to the top most layer.
  9. Create a Visual brush of childcanvas and store as Resource named ‘CanvasVisualBrush’.Set its stretch to None.
  10. Apply ‘CanvasVisualBrush’ as OpacityMask of Image which is in top layer.(which has the color photo)
  11. Add Reference to the dll MyActionsLibrary.(See my previous post to get MyActionsLibrary dll)
  12. Add FollowMouseBehavior into the parentcanvas.Set it’s Event to MouseMove.
  13. Set the Element property of FollowMouseAction to ‘ellipse’.
  14. Run and enjoy.

Try these steps your self.In the worst case (If you can’t do it by yourself) see the sample here.Let me know if you got struck somewhere in steps.

Thursday, May 14, 2009

Understanding OpacityMask and its usage

OpacityMask as it’s name implies a mask to the opacity.ie a mask which is given to the visibility of a visual element.So the places which are not covered by the mask will be transparent.
Here comes the first doubt.How can we specify this opacitymask ? Mask here refers to a definition of Brush.Brush is the abstract base class for a variety of brushes like SolidColorBrush,LinearGradientBrush,VisualBrush etc…So we can apply mask in so many ways.

Need for OpacityMask

The main application of OpacityMask is to define some transparent areas in visual elements.Let’s consider the scenario below.
We have a Rectangle filled with Yellow and and an Ellipse filled with Red on top of it.So naturally the red ellipse will be visible over rectangle.Below is the xaml and image in blend.

<Grid x:Name="LayoutRoot">
<Rectangle Fill="#FFFFFF00" />
<Ellipse Stroke="#FF000000" Fill="#FFFF0000"/>
</Grid>



Qn : We need to show the yellow rectangle over the ellipse what we do?

Ans : Just set the Alpha value of the Fill property of the ellipse to 00.Its fully transparent and we can view the rectangle.

Qn : We need to make the bottom half of the ellipse transparent.What will we do?

Ans : We will make the Fill brush of ellipse to a LinearGradientBrush and set the bottom part transparent by setting alpha to 0.Xaml and screenshot is below.



<Grid x:Name="LayoutRoot">
<Rectangle Fill="#FFFFFF00" />
<Ellipse Stroke="#FF000000">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00000000" Offset="0.571"/>
<GradientStop Color="#FFFF0000" Offset="0.531"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>



Qn : How can we make 3/4 th of ellipse transparent?

Ans : According to my WPF knowledge there is no way to do this by using only one brush.Here comes the importance of OpacityMask.OpacityMask here defines another area which is transparent by using another LinearGradientBrush.Code and screenshot is below.



<Grid x:Name="LayoutRoot">
<Rectangle Fill="#FFFFFF00" />
<Ellipse Stroke="#FF000000">
<Ellipse.OpacityMask>
<LinearGradientBrush EndPoint="0.05,0.56" StartPoint="0.943,0.568">
<GradientStop Color="#FF000000" Offset="0.487"/>
<GradientStop Color="#00FFFFFF" Offset="0.527"/>
</LinearGradientBrush>
</Ellipse.OpacityMask>
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00000000" Offset="0.571"/>
<GradientStop Color="#FFFF0000" Offset="0.531"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>



I have used a LinearGradientBrush with Brush transform to implement this.When we are specifying OpacityMask,it won’t consider the color of the brush.Because here the intention is to define an area which is transparent or opaque.But it cares the alpha value very seriously.According to the alpha value only it defines the amount of transparency or opacity.

This is the basic idea of OpacityMask.I will get confused often while working extensively with OpacityMask.So if anybody reading this, have more knowledge about OpacityMask please share with me.

OpacityMask is very much useful in giving awesome look and feel to your application like glass effects transparency etc…To understand better about the opacitymask I will be writing another post which talks about creating a magic transparent glass.


More links about OpacityMask

http://geekswithblogs.net/Silverlight2/archive/2008/10/22/working-with-opacity-masks.aspx

http://www.vbdotnetheaven.com/UploadFile/dbeniwal321/OpacityMaskWPF01302009011520AM/OpacityMaskWPF.aspx

Wednesday, May 13, 2009

Where is the main method in my WPF application?

If you are an expert WPF developer and knows the answer just stop here.Rest will be boring for you.

Normally when a new deveoper comes into WPF from the .net 2.0 environment he will naturally look for the main method where the execution starts.He can't find out the main method by simply searching in the Visual Studio using ctrl+shift+f.So where is the main method ? or WPF application don't have anything like that ? then how the execution starts in wpf and where is the entry point?

The main method in WPF application lies in the file App.g.cs located at obj\debug.This is autogenerated and will not be visible until we press the 'Show all files' button in the solution explorer.See the screen shot below.


Adding our own Main method in WPF applications
Now it is clear that the WPF application has a mainmethod where the execcution starts.Let's check whether we can write our own main method.If we write a Main method in the App.Xaml.cs it will not compile by saying "App already define a member called 'Main' with the same parameter types".So what to do?

We can write in some other classes like Window1.xaml.cs.Then how the system identifies which Main should get called.That too simple.Go to project properties.Select application tab.Then change the start up object to Window1.cs.See the below code for more details

Tuesday, May 12, 2009

MVVM Communication among ViewModels

When a new person enters into the MVVM world ,the first doubt in his mind would be ‘How can I achieve messaging among View-Models ? ’or ‘How to notify other ViewModels about a change or operation in one ViewModel ?’ For example if we take a scenario of CRUD database operations there should be notifications passing through on each operation like creation,deletion etc...Otherwise the listing ViewModel will not be up to date.

When the same view-model communication came in to my mind, the possible solutions I got are

  1. Events : Raising events on operations so that subscribed view models will get notification.
    1. Data access layer / Data repository / Data provider  owns events
    2. View models own events.
  2. Mediator pattern : A centralized place where the subscriptions or handlers are stored against messages.

1.Events

This is the common solution found in most of the MVVM implementations.This is very easy to implement too.After each operation an event will get fired and the subscribed viewmodels will update themselves according to that.When we came to implement this method ,the common question would be where we should write these events.There are 2 places where we can write these events.

Events at data layer

The sample contained in the Josh Smith’s article uses this method.Events are written in the data layer and will be fired as soon the operation completed successfully. For more details see the CustomerAdded event in the file CustomerRepository.cs

Pros : All the events reside at a single place.So easy to maintain.ViewModels will contain only data bindable properties and commands.

Cons : If they data layer is done by some other developer who is in different location and doesn’t care about the MVVM this fails.If the project is just to upgrade the UI of an existing application to WPF, we can’t expect the existing data layer with these type of events.

Events at ViewModel level

Here the events are written in the view models.Whenever an operation finishes or a view model wants to notify other viewmodels about something, it will raise an event which in turn ,captured by other view models and they can process according to that.

In the attached sample showing the editing customer view is done by that method.The AllCustomersViewModel has got a new event called EditCustomer which is fired when ever the user clicks on the edit command.ie When we click on the Edit link in the AllCustomersView the event EditCusomer will get fired.Thus MainViewModel receives the notification since it has subscribed to that event and it shows the CustomerView with the selected customer.

I think there is no need to explain the pros and cons as it is reverse of the above.

2.Mediator pattern

This is a well known pattern.For more details about the pattern see these posts

MVVM Mediator Pattern

[MVVM + Mediator + ACB = cool WPF App] – Intro « C# Disciples

In the attached sample you can see the ViewModelMessages.CustomerDeleted message is dispatched  after the deletion in the method CustomerViewmodel.Delete().This is captured by the AllCustomersViewmodel and it updates its collection to update the view.

Sample

The sample attached here is taken from the famous MVVM article by Josh Smith.Thanks Josh.I modified that sample to show these notification mechanisms.It contains the implementation of all these messaging techniques mentioned above.Another change I did is creating separate projects for view,view-model,model,MVVM etc…to easily understand the separation of model and view.

The sample can be downloaded from here.

Monday, May 11, 2009

Writing custom TriggerAction using Interaction to enhance MVVM

The Blend team has introduced a new concept called Interactions for both WPF and Silverlight.According to my understanding it is a method to interact with the xaml elements without writing code behind.Expression Blend is developed using the new architectural concept MVVM and I think they mainly introduced it to enhance MVVM.

There are 2 methods to implement this interaction.One is Behaviors and other is Triggers.Behaviors will be covered in a separate post.This post is related with Triggers, Actions and creation of  a custom Action called FollowMouse.

I have already wrote a post about Microsoft.Expression.Interactivity.dll which tells about creating a custom trigger named RoutedEventTrigger which fires on the associated RoutedEvent.In that post, the intention was to invoke a command upon attached events like Mouse.MouseDown,Mouse.MouseMove,Contacts.ContactDown etc…That is too, very much useful to achieve a perfect MVVM architecture.

In the perfect MVVM world there should be no code behind for xaml files.But when we implement in the real world ,sometimes we will be forced to write code behind to implement some special cases such as MessageBox.Show.Using the Microsoft.Expression.Interactivity.dll we can write actions which display the messagebox.

More links about the behaviors and interactions are below

http://electricbeach.org/?p=147
http://blog.kirupa.com/?p=341

What are these new Interactions

As I told earlier this is a method to interact without writing code behind.The code will be encapsulated in the action classes.See the example below which shows  a MessageBox using only xaml upon a MouseDown.

<Grid Background="Red">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<myactions:ShowMessageBoxAction MessageBoxText="Mouse down" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>


Hope the above code is clear.It tells to show a MessageBox upon MouseDown in the Grid.We know that it is not possible or don’t have default support in xaml to show the message itself.Then where is the C# code to show the message.The answer is simple.It is in the ShowMessageBoxAction class.That class has a MessageBoxText property which is displayed on invoking that action.


To implement interaction it is using attached properties.Interaction.Triggers is an attached property of type TriggerCollection.We can add as many triggers we want.The condition is that all those triggers should be derived from TriggerBase.Here I have used built in EventTrigger and a custom action ShowMessageBoxAction.


Developing our own custom Trigger Action : FollowMouseAction


Writing a custom trigger action is very simple.There should be a reference to the Microsoft.Expression.Interactivity.dll in our project.That dll is from Expression Blend 3 so it should be blend installed in your system to refer.Path is <Install drive>:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\WPF.Or you can download from any blogs.


The action class ,we need to derive from the base class named Microsoft.Expression.Interactivity.TargetedTriggerAction<T> this has a generic parameter which is the type of the target.


Here we are going to implement a FollowMouseAction.The purpose of this is to create an action which follows mouse and updates it’s position according to that.For that we have to associate trigger to a Canvas.Canvas is the simple panel in which children can be easily placed by specifying Left and Top.So at the time of inheriting class we have to specify the Canvas as it’s action type.


One more thing we need is which child of canvas is following the mouse.So we have to add one more property called Element which is of type FrameworkElement.On action invocation we will be setting the Canvas.Left and Canvas.Top properties of Element according to the mouse position.




public class FollowMouseAction : Microsoft.Expression.Interactivity.TargetedTriggerAction<Canvas>
{
public FrameworkElement Element
{
get { return (FrameworkElement)GetValue(ElementProperty); }
set { SetValue(ElementProperty, value); }
}

// Using a DependencyProperty as the backing store for element. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ElementProperty =
DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(FollowMouseAction), new UIPropertyMetadata(null));

protected override void Invoke(object parameter)
{
Point pt = Mouse.GetPosition(this.Target);
if (Element != null)
{
Element.SetValue(Canvas.LeftProperty, pt.X);
Element.SetValue(Canvas.TopProperty, pt.Y);
}
}
}

Using the FollowMouseAction in xaml.



<Grid>
<Canvas Width="300" Height="300" Background="Red">
<Ellipse Width="50"
Height="50"
Fill="Green"
x:Name="ele">
</Ellipse>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<myactions:FollowMouseAction Element="{Binding ElementName=ele}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</Grid>


The above code updates mouse position when we click on the mouse.How can we make it movable accoring mouse ?Easy just change the event name to “MouseMove”.See below if you are still not clear.



<Grid>
<Canvas Width="300" Height="300" Background="Red">
<Ellipse Width="50"
Height="50"
Fill="Green"
x:Name="ele">
</Ellipse>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseMove">
<myactions:FollowMouseAction Element="{Binding ElementName=ele}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</Grid>



NB: Please don’t confuse these Triggers and Actions with the standard triggers and actions available in WPF.They are entirely different where the Triggers mentioned here comes from the namespace Microsoft.Expression.Interactivity and the standard WPF Triggers comes from System.Windows



The above is applicable to Silverlight too.The only change you have to to do is change the reference to the interactivity dll located at <install drive>:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\Silverlight.If you need more and more details please see this great article from my colleague Laurent Bugnion 


Sample can be downloaded from here.

Saturday, May 9, 2009

MVVM Developing a generic Mediator class

When I tried to separate the MVVM related classes to a different project called ‘MVVM.Core’ for future use,I came to see one issue.That is the mediator which I used is handling messages which are specific to my project.’GameOver’,’GameStarted’ etc…This would not be the case in my future projects.There the messages may be ‘UserAdded’,’UserDeleted’ or something else.So I decided to make the existing Mediator class generic.
The MultiDictionary remains the same as in MVVM Mediator Pattern(This is the place where I got Mediator code.Thanks to Sacha Barber).The changes are mainly in the Mediator class.I removed the ViewModelMessage enum (specific to my project)from that class and made it coming as generic type parameter T .Changed all references of ViewModelMessage into T.The below code snippets tell the difference.

public sealed class Mediator
{...}


public sealed class Mediator<T>
{...}

Then I had to change the view model hierarchy.I created a new Viewmodel which is called MediatorEnabledViewModel to contain the Mediator functionality.



public class MediatorEnabledViewModel<T>:WorkspaceViewModel
{
public Mediator<T> Mediator
{
get
{
return Mediator<T>.Instance;
}
}
}

These classes are in MVVM.Core project and in the application specific viewmodel project, I added one more base viewmodel which is more specific to the application where I specify the type of generic parameter T.



public class DemoAppViewModelBase : MediatorEnabledViewModel<ViewModelMessages>
{
public CustomerRepository CustomerRepository
{
get { return CustomerRepository.SingleTon; }
}
}

Now its all set.We can change the type of the message which mediator handles from the application’s view-model according to the nature of the application.Type of the message can be any enum which contains application specific values / messages.Below is the screenshot of solution structure.



The entire mediator code can be downloaded from here

Friday, May 8, 2009

Using TagVisualizer and TagVisualization in Surface development

This post describes about the programming aspects of Surface tags.If you are not familiar with surface and surface tags please see posts below

Surface Application Development using Simulator and VisualStudio.
Identifying Finger ,Tag and Blob in Surface using Contacts class

TagVisualizer

TagVisualizer is a ContentControl derived from SurfaceContentControl and it’s basic function is to show Tag Visualizations when the corresponding tag is placed on the surface. Tag Visualizations are added by means of TagVisualizationDefinition.For that the TagVisualizer has a property called Definitions which is of type TagVisualizationDefinitionCollection.Each TagVisualizationDefinition tells what to display when a tag is being placed.

TagVisualizationDefinitions

This defines the visual against the tag value.The visual can be a UserControl and it is mentioned in the form of Uri.There are 2 types of tags in surface as you know.So there should be a mechanism to differentiate these tags while displaying.The method here used here is inheritance.ByteTagVisualizationDefinition  which is derived from abstract class TagVisualizationDefinition deals with the byte tags and IdentityTagVisualizationDefinition derived from same ,deals with Identity tags.A simple xaml code which shows a red colored usercontrol on byte tag of value 10 is shown below.

<Grid Background="{StaticResource WindowBackground}">
<s:TagVisualizer>
<s:TagVisualizer.Definitions>
<s:ByteTagVisualizationDefinition Value="10"
Source="ByteTagVisualization.xaml">
</s:ByteTagVisualizationDefinition>
</s:TagVisualizer.Definitions>
</s:TagVisualizer>
</Grid>


<UserControl x:Class="SurfaceApplication1.ByteTagVisualization"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Background="Red">
<Grid>

</Grid>
</UserControl>

ByteTagVisualization is a normal UserControl available in WPF.Hope this is clear like water.Shows the UserControl ByteTagVisualization when we place a byte tag with value 10 in the area covered by TagVisualizer.


TagVisualization


This is again a ContentControl which can be used as Source in TagVisualizationDefinition.The advantage here is that, the TagVisualization class has some properties which are related to the tag and tag data.Below goes steps which explains how to create TagVisualization.


  1. Create a UserControl

  2. In the xaml file change the root tag as s:TagVisualization where s is xmlns:s="http://schemas.microsoft.com/surface/2008" namespace of surface controls.

  3. In the xaml.cs file change the base class to TagVisualization.Also change the constructor to suit the class.


A sample TagVisualization is given below



<s:TagVisualization x:Class="SurfaceApplication1.IdentityTagVisualization"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008">
<StackPanel>
<TextBlock>An Identity tag has been placed</TextBlock>
</StackPanel >
</s:TagVisualization>

Getting tag values in TagVisualization and databinding


Even though the TagVisualization has the Property TagData we can’t use that in binding because that is not WPF friendly.



<TextBlock  Text="{Binding VisualizedTag.Type,ElementName=tagVisualization}" />

The above code won’t work

To enable databinding in TagVisualization we have to write our own properties which are data bindable.Then to get the value of tag which is placed over TagVisualizer override the OnGotTag method and get value from VisualizedTag property.



public partial class IdentityTagVisualization : TagVisualization
{
public long? TagValue
{
get { return (long?)GetValue(TagValueProperty); }
set { SetValue(TagValueProperty, value); }
}
public static readonly DependencyProperty TagValueProperty =
DependencyProperty.Register("TagValue", typeof(long?), typeof(IdentityTagVisualization));

public IdentityTagVisualization()
{
InitializeComponent();
}
protected override void OnGotTag(RoutedEventArgs e)
{
if (VisualizedTag != null)
{
TagValue = (VisualizedTag.Type == TagType.Byte) ?
VisualizedTag.Byte.Value :
VisualizedTag.Identity.Value;
}
base.OnGotTag(e);
}
}
}

Now you can databind the value of the tag in xaml.



<s:TagVisualization x:Class="SurfaceApplication1.IdentityTagVisualization"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008" x:Name="tagVisualization">
<StackPanel>
<TextBlock>Tag has been placed value is </TextBlock>
<TextBlock Text="{Binding TagValue,ElementName=tagVisualization}" />
</StackPanel >
</s:TagVisualization>

Download sample from here.

Thursday, May 7, 2009

MVVM invoking command on attached event

When I started my last WPF project using MVVM by referring Josh Smith’s article ,I was very much excited about the way it separates the view and model.But after going some way, I got issues.The reason was how to execute command on events like MouseOver and MouseDown.In the sample which I got,the commands were  just bound to the Button.Command property.It was possible because the Button implements ICommandSource interface.In that case also we can’t invoke command on events other than Button.Click.

After a tough Google ,I found this article in Jaco Karsten’s blog which allows to invoke command on any control any event.The only thing is we have to use an Expression Blend 3 dll named Microsoft.Expression.Interactivity which have its own attached Interaction trigger mechanism along with Jaco’s CommandAction class.Attached trigger mechanism allows us to add a EventTrigger and CommandAction class will invoke a command when the trigger if fired.Life became cool again.Thanks to Jaco.

<Image Width="360"
Height="177"
Source="sample.jpg">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseMove">
<mvvmjaco:CommandAction Command="{Binding MouseMoveCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>

Implemention of Interaction.Triggers and Command action.Command will execute when the trigger fired


When this comes to Surface,I again saw a hurdle.We can’t invoke command on attached events.For example we can’t invoke command on s:Contacts.ContactDown.

After reflecting the class EventTrigger present in the Microsoft.Expression.Interactivity dll, I came to know that it is using reflection to find out the event from it’s EventName property which is not applicable in the case of attached events.Hence I was forced to create a new trigger which fires on attached event by inheriting EventTriggerBase<T> class.


Implementation of RoutedEventTrigger


A property named RoutedEvent of type RoutedEvent is being added.In the overridable method OnAttached, I attached a handler to the RoutedEvent and in the handler call the OnEvent method present in the base.That in turn calls all the actions associated with that trigger.For more details see the code below



public class RoutedEventTrigger :EventTriggerBase<DependencyObject>
{
RoutedEvent _routedEvent;

public RoutedEvent RoutedEvent
{
get { return _routedEvent; }
set { _routedEvent = value; }
}

public RoutedEventTrigger()
{
}
protected override void OnAttached()
{
Behavior behavior = base.AssociatedObject as Behavior;
FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement;

if (behavior != null)
{
associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
}
if (associatedElement == null)
{
throw new ArgumentException("Routed Event trigger can only be associated to framework elements");
}
if (RoutedEvent != null)
{
associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
}
}
void OnRoutedEvent(object sender,RoutedEventArgs args)
{
base.OnEvent(args);
}
protected override string GetEventName()
{
return RoutedEvent.Name;
}
}


Using RoutedEventTrigger



<Image Width="360" Height="177" Source="Resources\PlayerArea.png">
<i:Interaction.Triggers>
<mvvmjoy:RoutedEventTrigger RoutedEvent="s:Contacts.ContactDown">
<mvvmjaco:CommandAction Command="{Binding TouchCommand}" />
</mvvmjoy:RoutedEventTrigger>
</i:Interaction.Triggers>
</Image>




Executes touch command on Contacts.ContactDown event.