Tuesday, December 8, 2009

New WPF and XAML features

For those who didn’t try the new features yet.

http://blogs.msdn.com/llobo/archive/2009/11/25/concluding-new-wpf-features-series.aspx
http://blogs.msdn.com/llobo/archive/2009/11/19/xaml-2009-features-generics-support.aspx

Thursday, October 1, 2009

Using Lambda expression in XAML databinding

When I was in net last week end the below links took my attention.The reason was they explain how can we give lambda expressions in XAML.As a developer you might also wonder how the author did that.
It is by creating a custom markup extension and constructing lambda expressions on the fly.

Thanks to M. Orçun Topdağı for such a smart solution.I need to find out another way to implement this in my current project as that is in Silverlight and Silverlight does't support custom mark-up extensions.

Wednesday, September 23, 2009

Auto formatting XAML code

Here is one way to format our XAML code in a neat way.In VisualStudio open the Options dialog. Tools->Options.

Goto TextEditor->XAML->Formatting->Spacing and set the options as per the below image.

Set it as XAML coding practice and do a smooth code review...

Saturday, September 19, 2009

Understanding WPF ResourceDictionary

When I did a WPF training to .net 2.0 audience, it took some more time to explain the concept of Resource dictionaries.The were all familiar to the resource concept in .net and were trying to relate this to the resource files.
What is ResourceDictionary in WPF

WPF resource dictionary is just a collection of objects which are accessible by their corresponding key.

The objects here means anything which are derived from System.Object.Including integers, strings and controls like TextBlock and Buttons.  Normally people thinks that ResourceDictionary is something which is related to Window, Styles & Templates.The problem is that we normally use ResourceDictionary along with Styles and Templates.See a simple sample below.

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="Window1">
    <Window.Resources>
        <sys:Byte x:Key="day">18</sys:Byte>
        <sys:String x:Key="month">Apr</sys:String>
        <sys:Int32 x:Key="year">1984</sys:Int32>
        <TextBlock x:Key="monthtxt"
                   Text="{StaticResource month}" />
        <sys:Double x:Key="fontsize">14</sys:Double>
    </Window.Resources>
    <StackPanel Orientation="Horizontal">
        <TextBlock FontSize="{StaticResource fontsize}"
                   Text="My DOB :" />
        <ContentControl  Content="{StaticResource day}" />
        <ContentControl Content="{StaticResource monthtxt}" />
        <ContentControl Content="{StaticResource year}" />
    </StackPanel >
</Window>
Note that the integer and string are from mscorlib.

Who all can have ResourceDictionary
In simple words who has a property of type ResourceDictionary can hold resources. Here the Resources property defined in one of the base classes called FrameworkElement. Most of the WPF elements are inherited from FrameworkElement and hence they can hold resources.


Accessing objects in ResourceDictionary
There are mainly 2 ways to get objects from ResourceDictionary.One is through XAML with mark-up extension and other through code.The above code shows how to retrieve through the StaticResource markup extension.Another method is through the tag <StaticResource>



<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Window.Resources>
        <sys:String x:Key="fullname">Joy George K</sys:String>
        <TextBlock x:Key="nametxt"
                   Text="{StaticResource fullname}" />
    </Window.Resources>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="FullName :" />
        <StaticResource ResourceKey="nametxt" />
    </StackPanel >
</Window>

Accessing from Code

Dim fullname As String = Me.FindResource("fullname")
If Not String.IsNullOrEmpty(fullname) Then
    MessageBox.Show("My FullName :" & fullname)
End If

My current project is in VB.Net and that is why you are seeing vb code instead of C# :-)

Merged ResourceDictionaries

Now one question comes.I have so many resources in ResourceDictionary such as Brushes, ControlTemplates and Styles.Can I categorize these in to separate files and merge them like CSS ?

Yes.It is possible by using Merged ResourceDictionaries.Add ResourceDictionary files by following the steps below and merge them at your Window or Application level.

Right click on the project -> Add -> ResourceDictionary


The below code show how to merge the ResourceDictionaries into your Window.xaml

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="brushes.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="FullName : Joy George K"
                   Background="{StaticResource background}" />
    </StackPanel >
</Window>

 Static & Dynamic ResourceDictionaries
We have seen the resources are being accessed by a mark-up extension StaticResource. Normally one question comes into our mind as a developer.Is there something called DynamicResource?
Yes.There exists DynamicResource mark-up extension too.Then what are the differences?
The main difference between Static and Dynamic resource mark-up extensions is the value calculation.In StaticResource it is done only once.But in DynamicResource it is done when ever the value of the resource changes.
I know it is difficult to understand.First question will be how to change the value of resource ? Simple .Its by code.
Lets take one example.There is a Brush resource in ResourceDictionary with color white and key backBrush.We have used this brush to give background to 2 StackPanels.One is by StaticResource and another is by DynamicResource mark-up extension.
It will work fine.When we run the application both these StackPanels will have white as background.Now suppose if I change the value of backBrush resource to Red through code what will happen? The answer is .The StackPanel which used DynamicResource will get the Red color and the other will be still in white.Hope this clears.


Refer this sample if you are still in confusion.

Saturday, August 1, 2009

WPF Training at Orion

I have seen so many times Jim Mangaly giving nice presentations and trainings, when I was working in Identitymine.As a Software engg I never thought that I have to take WPF sessions.

But the earth didn't stop it's rotations.It became weeks,weeks became months and months became years.After 2 years I joined in Orion Inc and at a fine noon ,I was asked to present a WPF session.

Initially I was in big confusion "How to present the new features in WPF ?" It is very easy to work with.But very difficult to make others understand these new features.I had 1 hour left with me to prepare.It is not enough to prepare even about XAML.But I have to convey what is xaml.My audience is from .Net2.0 so finally I decided to present WPF features by relating the drawbacks of .Net 2.0 windows forms, and coresponding solutions in WPF.See some examples below.
  • Windows forms developer has to get design(in some format like jpg) from designer and implement himself.This eats a good amount developer's precious time and the work is repetition.WPF has a solution which is called XAML to solve this problem.
  • In Windows forms if someone needs to replace a digital clock control by analog clock he has to create a new control and override it's OnPaint method.But WPF provides a mechanism called templating which does this in a shorter time.
  • Rotating a button in Windows forms is a 'Job'.But in WPF its a matter of 3 lines of code which specifies a RotateTransform.
Yes.This did the trick.At least they got some words like "XAML","Template","Transform","Styles" etc... which are going to make their life easier in the WPF world.The feedback was good and I decided to continue giving detailed sessions on WPF.2 sessions are over as of now and hope I can complete the other sessions soon...

Sunday, July 12, 2009

Different styles for alternate rows in ListBox

Simple but important feature which really help us in real-time applications.Giving different look and feel or colors to alternate rows helps users to differentiate two consecutive rows in a ListBox or ListView.Basically controls which are derived from ItemsControl.

Below xaml code shows how alternate colors are applied into a ListBox

Xaml code to create ListBox with 6 items

<ListBox AlternationCount="2">
    <ListBoxItem Content="Item1" />
    <ListBoxItem Content="Item2" />
    <ListBoxItem Content="Item3" />
    <ListBoxItem Content="Item4" />
    <ListBoxItem Content="Item5" />
    <ListBoxItem Content="Item6" />
</ListBox>

Xaml code of the Style which has the alternate style support.Note the change is in the ItemContainerStyle.Here Style is applied to ListBoxItem



<Style  TargetType="{x:Type ListBoxItem}">
    <Style.Triggers>
        <Trigger Property="ItemsControl.AlternationIndex"
                 Value="0">
            <Setter Property="Background"
                    Value="LightBlue"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex"
                 Value="1">
            <Setter Property="Background"
                    Value="LightGreen"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

When we run it shows as follows



Description


Here the ItemsControl has got most of the implementation part.It has some members which control the behavior of alternate style.The attached property ItemsControl.AlternationIndex tells the index and according to that we can change color or anything through style.


The Alternation count specifies the frequency.Below code uses 3 as ItemsControl.AlternationCount.See the difference.


Creating ListBox



<ListBox AlternationCount="3">
    <ListBoxItem Content="Item1" />
    <ListBoxItem Content="Item2" />
    <ListBoxItem Content="Item3" />
    <ListBoxItem Content="Item4" />
    <ListBoxItem Content="Item5" />
    <ListBoxItem Content="Item6" />
</ListBox>

Style supports AlternationCount=3



<Style  TargetType="{x:Type ListBoxItem}">
    <Style.Triggers>
        <Trigger Property="ItemsControl.AlternationIndex"
                 Value="0">
            <Setter Property="Background"
                    Value="LightBlue"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex"
                 Value="1">
            <Setter Property="Background"
                    Value="LightGreen"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex"
                 Value="2">
            <Setter Property="Background"
                    Value="LightYellow"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>


I don't think a sample is needed.

Tuesday, June 9, 2009

Deploying applications in Microsoft Surface SP1

The surface has a launcher application which is launching applications registered with the Surface Shell.Launcher can be activated from any of the 4 access points located at corners of surface.

Registering Microsoft Surface Application
To register an application with Microsoft surface shell we have to copy the application’s xml definitions file into the %PROGRAMDATA%\Microsoft\Surface\Programs folder.This is the folder where surface looks for application definitions.It maintains a list of applications listed here to load on demand by launcher.

Application’s definition file is a simple xml file which describes the application.Common elements included in the definition are

Title : Title  of the application
Description:Description about application
Executable: Path to exe.Path need to be absolute.
IconImageFile:Icon of application.
Preview: Preview images

A sample xml file

<?xml version="1.0" encoding="utf-8" ?>
<ss:ApplicationInfo
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ss="http://schemas.microsoft.com/Surface/2007/ApplicationMetadata">
<Application>
<Title>Test Surface App</Title>
<Description>This is a test Surface application.</Description>
<ExecutableFile>%ProgramData%\Microsoft\Surface\Programs\SurfaceApplication1.exe</ExecutableFile>
<Arguments></Arguments>
<IconImageFile>%ProgramData%\Microsoft\Surface\Programs\Resources\icon.png</IconImageFile>
<Preview>
<PreviewImageFile>%ProgramData%\Microsoft\Surface\Programs\Resources\iconPreview.png</PreviewImageFile>
</Preview>
</Application>
</ss:ApplicationInfo>

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.