A Simple Paint App on Windows Phone 7 using InkPresenter

Windows Phone 7 tools comes shipped with InkPresenter control . In this simple application , I  will select a color and draw on drawing surface which is an InkPresenter. Lets start.

Open Expression Blend , Select Windows Phone Application template.

pic1

For drawing surface , select  the InkPresenter control from Assets panel and draw it on ContentPanel(Grid). Call it as drawingCanvas.

pic3

Draw a simple palette  with ellipses of various colors laid over a colored rectangle to make it look like a palette.

pic4

After setting the page name and background color , below is how my paint app looks. Cool isn’t it.. 🙂

alt

Ok so UI is ready, lets wire it up with code-behind.

We need 2 variables . One to capture stroke and other to set the color of stroke.

SolidColorBrush colorPicked;
Stroke _colorStroke;

To capture mouse movements, we have to handle MouseLeftButtonUp, MouseLeftButtonDown and MouseMove events for the drawingCanvas.

 private void drawingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            drawingCanvas.CaptureMouse();
            _colorStroke = new Stroke();
            _colorStroke.StylusPoints.Add(GetStylusPoint(e.GetPosition(drawingCanvas)));
            _colorStroke.DrawingAttributes.Color = colorPicked.Color;
            drawingCanvas.Strokes.Add(_colorStroke);

        }

        private StylusPoint GetStylusPoint(Point position)
        {
            return new StylusPoint(position.X, position.Y);
        }
        private void drawingCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (_colorStroke != null)
            {
                _colorStroke.StylusPoints.Add(GetStylusPoint(e.GetPosition(drawingCanvas)));
            }
        }

        private void drawingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _colorStroke = null;
        }

 

For selecting a color from palette we will wire up every ellipse in palette with a MouseLeftButtonDown  event and  set brush used to draw strokes with the Fill of the ellipse .

 private void SelectColor(object sender, MouseButtonEventArgs e)
        {
            Ellipse selectedEllipse = sender as Ellipse;
            colorPicked = selectedEllipse.Fill as SolidColorBrush ;
        }

XAML code is below.

<Grid x:Name="LayoutRoot">
		<Grid.Background>
			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
				<GradientStop Color="#FF00243B" Offset="0"/>
				<GradientStop Color="#FF005185" Offset="0.992"/>
			</LinearGradientBrush>
		</Grid.Background>
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto"/>
			<RowDefinition Height="*"/>
		</Grid.RowDefinitions>

		<!--TitlePanel contains the name of the application and page title-->
		<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
			<TextBlock x:Name="ApplicationTitle" Style="{StaticResource PhoneTextNormalStyle}" Foreground="#FFA19696"/>
			<TextBlock Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" Foreground="#FFC04111"><Run Text="P">
					<Run.Foreground>
						<SolidColorBrush Color="#FFA120FF">
							<SolidColorBrush.RelativeTransform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.RelativeTransform>
							<SolidColorBrush.Transform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.Transform>
						</SolidColorBrush>
					</Run.Foreground>
				</Run><Run Text="a">
					<Run.Foreground>
						<SolidColorBrush Color="#FF1BADEB">
							<SolidColorBrush.RelativeTransform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.RelativeTransform>
							<SolidColorBrush.Transform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.Transform>
						</SolidColorBrush>
					</Run.Foreground>
				</Run><Run Text="i">
					<Run.Foreground>
						<SolidColorBrush Color="#FFFFE153">
							<SolidColorBrush.RelativeTransform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.RelativeTransform>
							<SolidColorBrush.Transform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.Transform>
						</SolidColorBrush>
					</Run.Foreground>
				</Run><Run Text="n">
					<Run.Foreground>
						<SolidColorBrush Color="#FF56C011">
							<SolidColorBrush.RelativeTransform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.RelativeTransform>
							<SolidColorBrush.Transform>
								<MatrixTransform Matrix="Identity"/>
							</SolidColorBrush.Transform>
						</SolidColorBrush>
					</Run.Foreground>
				</Run><Run Text="t "/></TextBlock>
		</StackPanel>
		<Grid x:Name="ContentPanel" Margin="12,0,12,0" Grid.Row="1" >
			<InkPresenter Background="White"
				x:Name="drawingCanvas" MouseLeftButtonDown="drawingCanvas_MouseLeftButtonDown"
				MouseMove="drawingCanvas_MouseMove"
				MouseLeftButtonUp="drawingCanvas_MouseLeftButtonUp" Margin="8,8,8,197"/>
			<Rectangle Height="174" RadiusY="26" RadiusX="26" Margin="8,0,8,8" VerticalAlignment="Bottom">
				<Rectangle.Fill>
					<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
						<GradientStop Color="#FF065474" Offset="0.004"/>
						<GradientStop Color="Black" Offset="1"/>
					</LinearGradientBrush>
				</Rectangle.Fill>
			</Rectangle>
			<Ellipse Height="66" Width="68" Fill="#FF005CF1"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Left" Margin="26,0,0,20" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FFFF0C00"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Left" Margin="26,0,0,96" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FFFDFF1F"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Left" Margin="108,0,0,20" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FF3AC00C"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Left" Margin="106,0,0,96" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Fill="#FF80007B"
				MouseLeftButtonDown="SelectColor" Margin="184,0,204,96" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FFE99A0B"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Right" Margin="0,0,128,96" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FF9D073E"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Right" Margin="0,0,48,96" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Fill="#FF1A0CC0"
				MouseLeftButtonDown="SelectColor" Margin="184,0,204,20" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FFA6C00C"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Right" Margin="0,0,128,16" VerticalAlignment="Bottom"/>

			<Ellipse Height="66" Width="68" Fill="#FFBE02F9"
				MouseLeftButtonDown="SelectColor" HorizontalAlignment="Right" Margin="0,0,46,18" VerticalAlignment="Bottom"/>
		</Grid>

		<!--ContentPanel - place additional content here-->
	</Grid>

This is it . Run your app and enjoy playing with strokes of different colors.

pic6

The xaml code above can surely be customized to include a WrapPanel with ellipses of various colors and loading the palette on click of button.

Below are some real good links for working with InkPresenter.

http://www.nickharris.net/2010/03/silverlight-for-mobile-on-windows-phone-7-inkpresenter-fun/

http://rongchaua.net/blog/windows-phone-signature-capturing-with-inkpresenter-and-save-to-png-file/

Advertisements

IE 9 The Beauty of WEB

iepic  Internet Explorer 9 Beta.. is out. IE9 is available for versions starting from Windows Vista,Windows 7..and supported for 32 bit and 64 bit.Gave it a try and spotted some real good features.

1) Sending images to Bluetooth devices from Browser itself.

If you have your mobile paired with your PC using Bluetooth, any image that you wish to send to your mobile can be easily sent from IE9 itself  by right clicking on an image and selecting Send Image to Bluetooth Device. I got the image real fast in my Nokia 7230 device. This saves a lot time…

image
 
alt image

2) Better printing and print preview options.

Printing support and print preview option is good in IE9. You can change the font, enable/disable background images and , set headers and footers etc.

image

 

 

3) Add site to Start Menu. 

You surf a site everyday.. Rather than opening the browser and clicking on bookmarks, IE9 provides a nice feature of pinning the site to Start Menu.

image  imageimage

4) IE 9 Developer Tools are great.. Excellent traffic capturing, viewing link paths, Validating html,css etc… I guess one line is not enough.. Shoud be writing another blog to explore only the IE9 developer tools…..

image imageimage

5) This is what I wished … Tracking and viewing  your downloads in IE9 … It is there 🙂

image

6) Great support for HTML5,CSS3 and really good rendering capabilities… You can download and explore IE9 at

http://www.beautyoftheweb.com/ 

Push Notification in Windows Phone 7

Windows Phone 7 has now got support for Push Notifications. Before diving into the implementation let us understand the working of Push Technology.

Push Technology:

This technology involves communication in form of messages initiated by a publisher or central server. Push services follow publish-subscribe model where in the server pushes the information to the clients and the client application subscribes and pulls the information.

Windows Phone 7 Push Notification functionality support :

Windows Phone 7 does not support multitasking, hence push notification is the only method to notify the user.

The push services work as follows in line of business applications:

 image

Steps:

1)  The cloud service sends notification requests to Push Notification service.

2)  It routes the notification to the application. Notifications may be one of the three types:

       a. Tile Notification – The tile notifications are handled by phone ,if the application is pinned to the start page. The title, tile image and the tile number are three items that can be altered with a tile notification. The phone receives tile notifications only when application is not in running state.

       b. Toast Notifications – A toast notification comes in when the application is running. If the user clicks the notification, the application will launch.

       c. Raw Notifications – Raw notifications include raw data of any format and size but within limits. The phone receives them only when the application is running.

3)  Once the notification type is set, a notification channel is created to receive the push notifications at the client side. A subscription is also created which allows the cloud service to push notifications to that channel. A channel is represented by a URI which contains all of the information associated with the subscription.

4)  Once an application receives the push notification, it can access the cloud service using the cloud service’s protocol to retrieve any needed information.

Now lets us go through the steps to complete our demo :

Step 1: Simulating the cloud service to sending Push Notifications.

Step 2 : Setting up notification channel to receive notifications.

Step 3: Registering with the notification service.

Step 4 : A client application on Windows Phone 7 receiving notifications.

The solution structure will include 3 projects:

img1

NotificationService:  A WCF project acting as a background process to send messages.
NotificationSender:   A WPF project sending messages.
NotificationConsumer:  Windows Phone 7 client application receiving messages and displaying them as notifications.

NotificationService Project:

 img2

The service contract includes methods to send toast messages, send raw messages and let client application subscribe for notifications:

[ServiceContract]
    public interface IService1
    {

      //function to let client application subscribe to notification service.
      [OperationContract]
        void Subscribe(Guid _uniqueID,string uri);

        //method to send toast notifications
        [OperationContract]
        void SendToastNotification(string message);

        //method to send raw notifications.
        [OperationContract]
        void SendRawNotification(string message);

    }

The class(Service1.svc.cs) implementing the service is as follows:

namespace NotificationService
{

    //Notification Types
    public enum NotificationType
    {
        Tile = 1,
        Toast = 2,
        Raw = 3
    }

    //Time interval required to send messages.
    public enum BatchingInterval
    {
        TileImmediately = 1,
        ToastImmediately = 2,
        RawImmediately = 3,
        TileWait450 = 11,
        ToastWait450 = 12,
        RawWait450 = 13,
        TileWait900 = 21,
        ToastWait900 = 22,
        RawWait900 = 23
    }

    public class Service1 : IService1
    {

        private static Dictionary<Guid, Uri> _clientUris = new Dictionary<Guid, Uri>();

        public void Subscribe(Guid _uniqueID, string uri)
        {
            if (_clientUris.ContainsKey(_uniqueID))
            {
                _clientUris[_uniqueID] = new Uri(uri);
            }

            else
            {
                _clientUris.Add(_uniqueID, new Uri(uri));
            }
        }

        public void SendToastNotification(string message)
        {
            var toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                 "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Toast>" +
                       "<wp:Text1>{0}</wp:Text1>" +
                      "</wp:Toast>" +
                 "</wp:Notification>";
            toastMessage = string.Format(toastMessage,message);

            var messageBytes = System.Text.Encoding.UTF8.GetBytes(toastMessage);

            foreach (var uri in _clientUris.Values)
            {
                SendMessage(uri, messageBytes, NotificationType.Toast);
            }
        }

        public void SendRawNotification(string message)
        {
            var messageBytes = Encoding.UTF8.GetBytes(message);

            foreach (var uri in _clientUris.Values)
            {
                SendMessage(uri, messageBytes, NotificationType.Raw);
            }   
        }

        public void SendTileNotification(string message)
        {
            throw new NotImplementedException();
        }

        private void SendMessage(Uri uri, byte[] messageBytes, NotificationType notificationType)
        {
            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = WebRequestMethods.Http.Post;
            request.ContentType = "text/xml";
            request.ContentLength = messageBytes.Length;

            request.Headers.Add("X-MessageID", Guid.NewGuid().ToString());

            if(notificationType == NotificationType.Toast)
            {
                    request.Headers["X-WindowsPhone-Target"] = "toast";
                    request.Headers.Add("X-NotificationClass",((int)BatchingInterval.ToastImmediately).ToString());
            }
            else
            {

                    request.Headers.Add("X-NotificationClass", ((int)BatchingInterval.RawImmediately).ToString());
            }

            using (var requestStream = request.GetRequestStream())
            {
                requestStream.Write(messageBytes, 0, messageBytes.Length);
            }

         }
    }
}

Web.config file including endpoint settings for the service.

img3

 

NotificationSender Project:

img4

This WPF project sends text lines to service which are sent either as toast notifications or raw notifications.

MainWindow.xaml

img5

Code behind for MainWindow.xaml.cs

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void SendtoastNotification_Click(object sender, RoutedEventArgs e)
        {
            var toastService = new NotificationSenderReference.Service1Client();
            toastService.SendToastNotification(txtToastMessage.Text);
        }

        private void SendRawNotification_Click(object sender, RoutedEventArgs e)
        {
            var rawService = new NotificationSenderReference.Service1Client();
            rawService.SendRawNotification(txtRawMessage.Text);
        }
    }

 

NotificationConsumer Project:

img6

MainPage.xaml: XAML Code for the above design. All messages are added as items in Listbox.

<Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!–TitlePanel contains the name of the application and page title–>
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12">
            <TextBlock x:Name="ApplicationTitle" Text="PUSH NOTIFICATION SAMPLE" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="UPDATES" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!–ContentPanel – place additional content here–>
        <Grid x:Name="ContentGrid" Grid.Row="1" Background="Gray" >

            <ListBox x:Name="lstOffers">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                            <TextBlock Text="{Binding}" FontFamily="Segoe WP Light"  FontSize="20"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Grid>

MainPage.xaml.cs code:

public partial class MainPage : PhoneApplicationPage
   {
       private HttpNotificationChannel _channel;
       private const string ChannelName = "Notifications.Phone.NotificationChannel";
       private Guid _deviceId;

       public MainPage()
       {
           InitializeComponent();
           if (DesignerProperties.IsInDesignTool)
               return;

           if (IsolatedStorageSettings.ApplicationSettings.Contains("DeviceId"))
           {
               _deviceId = (Guid)IsolatedStorageSettings.ApplicationSettings["DeviceId"];
           }
           else
           {
               _deviceId = Guid.NewGuid();
               IsolatedStorageSettings.ApplicationSettings["DeviceId"] = _deviceId;
           }

           SetupNotificationChannel();
       }

       private void SetupNotificationChannel()
       {
           _channel = HttpNotificationChannel.Find(ChannelName);

           if (_channel == null)
           {
               _channel = new HttpNotificationChannel(ChannelName);
               _channel.ChannelUriUpdated += ChannelUriUpdated;
               _channel.ErrorOccurred += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ErrorOccurred(e));
               _channel.Open();
           }
           else
           {
               RegisterForNotifications();
           }
       }

       private void RegisterForNotifications()
       {
           RegisterWithNotificationService();
           _channel.ShellToastNotificationReceived += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ToastReceived(e));
           _channel.HttpNotificationReceived += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => HttpNotificationReceived(e));
           _channel.ErrorOccurred += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ErrorOccurred(e));
       }

       private void HttpNotificationReceived(HttpNotificationEventArgs e)
       {
           var reader = new StreamReader(e.Notification.Body);
           var message = reader.ReadToEnd();
           .Items.Add("Raw notification : " + message);
           reader.Close();
       }

       private void RegisterWithNotificationService()
       {
           var svc = new NotificationServiceReference.Service1Client();

           svc.SubscribeCompleted += (s, e) =>
           {
               if (e.Error != null)
               {
                   Debug.WriteLine("Error registering with notification service");
               }
           };

           svc.SubscribeAsync(_deviceId, _channel.ChannelUri.ToString());
       }

       private void ToastReceived(NotificationEventArgs e)
       {
           lstOffers.Items.Add("Toast Recevied : "+ e.Collection["wp:Text1"]);
        }

       private void ErrorOccurred(NotificationChannelErrorEventArgs e)
       {

           lstOffers.Items.Add(e.Message);
           Debug.WriteLine("ERROR:" + e.Message);
       }

       private void ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
       {
           _channel = HttpNotificationChannel.Find(ChannelName);

           if (!_channel.IsShellToastBound)
           {
               _channel.BindToShellToast();
           }

           RegisterForNotifications();
       }
   }

 

Now let’s run the project:

First

1) Run the NotificationService, to start the service.

2) Start a new instance of NotificationSender application .

3) Start the Windows Phone 7 application to receive notifications.

Output:

img7

 

img8

 

So that was a simple demo on Push Notifications on Windows Phone 7. For receiving Tile notifications you can check below links and more information:

Excellent blogs:

http://www.thisisfanzoo.com/Blog/JeffF/archive/2010/08/02/a-really-long-post-about-the-windows-phone-7-push.aspx

http://chris.59north.com/post/Using-Windows-Phone-7-Push-Notifications.aspx

MSDN Links:

http://msdn.microsoft.com/en-us/library/ff402537%28v=VS.92%29.aspx

Collections and Generics.(Why generics are better?)

.Net platform supports two broad groups of data types value types and reference types. At times you might have to convert data from one category to another.  .NET supports a simple concept called:

Boxing:  It converts value types to reference types .
Example:
short a = 40;
object objShort = a;
In boxing CLR(Common Language Runtime) creates a new object on the heap.It copies the value(here 40) in created instance.
A reference to the new created object is returned.

image     image

Unboxing:  Exactly  reverse operation of boxing is unboxing . It converts reference types to value types.
It is mandatory that you unbox into appropriate data type. Else you get InvalidCastException.
Example:
short b = (short)objShort;   //this is ok.
int c = (int)objShort;           //this will raise an InvalidCastException.

So in order to box and unbox a simple short, CLR has to:

1) Create a new object on heap

2) Transfer value of stack based data on to that memory location

3) When unboxed,it has to transfer data back to the stack.

4) and finally Garbage collect the unused object on heap.

Although a programmer might find it easy to do boxing and unboxing operations,  if these operations are done frequently for huge collections of data , there are performance issues in speed of execution,code size and there is lack of type safety(Type safety ensures that variable or container can hold or operate only on the specified type of data).

After understanding in brief about boxing and and unboxing , let us now look into Collections and Generics and understand why generics are more better than Collections.

System.Collections namespace. 

.Net provides System.Collections namespace which contains interfaces and classes to to create dynamically sized containers.

Let us see a simple example of ArrayList , a type in System.Collections namespace.

C# code.

ArrayList arrayList = new ArrayList();
arrayList.Add(“Hello”);
arrayList.Add(34);
arrayList.Add(3.14);
arrayList.Add(new Person());

You can see that ArrayList object can be dynamically sized and there is no restriction to what the object of  ArrayList can hold. This is because  majority of types of System.Collections can hold anything ,as their members are prototyped to operate on System.Objects.

But I need a type safe container which holds data of particular type.

Say ,for example…. I want a dynamically sized container to hold data of strings only.

I will go ahead with a simple logic: Check the example.

class StringCollection
{
ArrayList arrayStringList = new ArrayList();
public void AddString(string str)
{
arrayStringList.Add(str);
}
public string GetString(int positionOfString)
{
return (string)arrayStringList[positionOfString];
}
public int Count()
{
return arrayStringList.Count;
}
}

Here StringCollection class contains an ArrayList object. I get a dynamically sized container to hold data. Then there are three methods

AddString method: To add strings to the ArrayList object
GetString method: To return strings from the ArrayList object. As members of ArrayList are protoyped to objects , to get a member’s value, unboxing is done.
Count method:  To know the count of members added to ArrayList object.

In Main Method, I am creating objects of StringCollection class  and printing the values of container to console.

class MainProgram
{
static void Main(string[] args)
{
StringCollection strCollection = new StringCollection();
strCollection.AddString("Hello");
strCollection.AddString("How are you");
strCollection.AddString("I am fine");
int count = strCollection.Count();

 

for (int i = 0; i < count; i++)
{
Console.WriteLine(strCollection.GetString(i));
}

 

Console.Read();
}
}

The above logic does serve my purpose of creating dynamically sized objects for storing data of string type.But what if I had to do similar operations or create containers for various types.

The above solution is very labor-intensive as I will have to write code for every type. And maintaining it … is very very time-consuming ,..it’s a nightmare…. Also there is an overhead of boxing and unboxing…..

Here is where Generics come into picture.

System.Collections.Generic

Generics provide:

  1. Flexible containers which are type-safe.
  2. There are no hassles of boxing and unboxing..so performance is better.
  3. You can easily create custom collections.

System.Collections.Generic namespace provides interfaces and classes to create dynamically sized generic containers. All types in this namespace have placeholders. You just have to specify the type for the placeholder.

So if I have to create a list of objects of any type .. I have a List<T> class. Here T is the type.

Example:

//This is List of integers
List<int> list = new List<int>();

 

//This is list of Strings.
List<string> listString = new List<string>();

 

//This is list for objects of Person class.
List<Person> listPeople= new List<Person>();

So  you can see how easy it is to work with generics and create containers for various types  without writing code for type-safety,boxing ,unboxing operations as it was done for collections. Thus generics are better than collections.

Virtual Hard Disk(Creating,attaching and detaching VHD in Windows 7)

What is Virtual Hard Disk?

Virtual Hard Disk is a file format or replica identical to physical hard drive. It allows multiple operating systems to reside on host machine without having the need to create partitions on your hard disk.

VHD support in Windows7

Windows7 has support for creating Virtual Hard Disks. So after upgrading my PC to Windows 7 , I decided to give a try to this new in built feature.

Here are the steps:

1) First go to the Disk Management Window. 3 ways.. to get there..

a) Click Start->Right Click Computer-> and Select-> Manage or

b) Click Start-> Click Control Panel->System and Security->Administrative Tools->Computer Management or

c) Type compmgmt.msc in Search Box and press Enter.

Under Storage option, click Disk Management to see the disks. This is my comp’s Disk Management View.

clip_image002

Step1: Right click Disk Management option or click Action on Menu and select the Create VHD option.

clip_image003         or      clip_image004

 

Step 2: Select the location to save your VHD file format. Enter it’s size . Choose the hard disk format. The options are self-descriptive.

For detailed explanation click here (ignore the title.) 

I chose to save the file as Vista.vhd in Vista VHD folder on G: drive. Virtual Hard Disk Size: 20GB. clip_image006

You might see this popup if notifications are enabled while the vhd files are being created.

clip_image007

 

Step 3: Now you see the black colored space saying Unknown ..Not initialized.

So right click and Initialize it. The next windows explains why to do so: You have to initialize disk to access it. Simple isn’t it?

Then select MBR option . Master Boot Record abbreviated as MBR does the job of bootstrapping or activating the operating systems .

clip_image009

clip_image011

clip_image012

Finally after success you should see a similar screen with Disk1 but unallocated…So….

clip_image014

Step 5: Now create a simple volume. Select the volume size. Select the letter for your drive. I selected “P”.

Format it using NTFS.

image 

image

image 

You have you primary partition created.

image

Once done.. you see the following window popped up.

image

Step 6: To detach VHD, right click Disk Management or Action and select Detach VHD.

 

clip_image015

Here are the links  for the best Blogs I referred and followed:

http://blogs.technet.com/aviraj/archive/2009/01/17/windows-7-boot-from-vhd-first-impression-part-1.aspx

http://blogs.msdn.com/virtual_pc_guy/archive/2009/02/05/mounting-vhds-with-windows-7.aspx

Theming in Silverlight

A good design is appreciated if the look and feel is consistent across the application or site you develop. The first and the most best,popular option that comes to our minds is "Themes".

Silverlight allows developers to create rich styles for controls.
Every style has a unique key to identify and it is targeted for a particular element.
To apply style to an element,you have to bind it’s Style property with the unique key of the style defined in the resources at application or local level or defined in resource dictionary.

But is it possible to avoid inline (StaticResource) binding of styles and implicitly apply them to all elements going by the concept of "Themes".
The answer is "YES" and here is the solution. 

How to go about.  ?
In addition to Silverlight library, you will have to install the Silverlight toolkit.
The latest release is here.
There are inbuild themes already available in Silverlight toolkit,but I will create a simple theme from scratch.

Here are the steps:
1) Open Visual Studio and select a Silverlight application.

Silverlight application
2) Add a new folder "Themes" to the project.
Add three Silverlight resource dictionaries each for red,blue and green theme. Set the "Build Action" to Content for each xaml resource file in properties panel ,so that they are added to .xap file and they can be relatively located.

Silverlight resource dictionary       Project structure

Setting the build action to content

 

3) Add reference to "System.Windows.Controls.Theming".
Adding System.Windows.Controls.Theming to the project

4) In MainPage.xaml, I have added a ListBox with names of colors as ListBoxItems.
In a Stackpanel elements like Button,TextBlock and RadioButton have been added.
What I wish to do is on selecting a particular color from ListBox, I want the themes to be applied to all the elements in the StackPanel without StaticResource binding. But first let us create styles for a every element for red,green and blue themes respectively.

Elements in MainPage.xaml file

Code in MainPage.xaml file.

<UserControl x:Class="Themes_Application.MainPage"
    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"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot"  HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListBox x:Name="lstThemeColor" SelectionChanged="lstThemeColor_SelectionChanged" Width="Auto" BorderBrush="Black" BorderThickness="1" Height="Auto" Grid.Row="0">
            <ListBoxItem Content="Red"/>
            <ListBoxItem Content="Blue"/>
            <ListBoxItem Content="Green"/>
        </ListBox>

        <StackPanel Grid.Row="1" Orientation="Horizontal" x:Name="pnlElements" >
            <Button Height="50" Width="100" Content="Button1" Margin="5"/>
            <Button Height="50" Width="100" Content="Button2" Margin="5"/>
            <Button Height="50" Width="100" Content="Button3" Margin="5"/>
            <TextBlock Text="TextBlock1" Width="Auto" Height="30" Margin="5"/>
            <TextBlock Text="TextBlock2" Width="Auto" Height="30" Margin="5" />
            <RadioButton Content="RadioButton1" Width="Auto" Height="30" Margin="5"/>
            <RadioButton Content="RadioButton2" Width="Auto" Height="30" Margin="5"/>
        </StackPanel>

    </Grid>
</UserControl>

5) The best way to create styles is to copy the xaml code created in Expression Blend after right clicking the element and selecting the "Edit Template" option. Expression Blend provides excellent options to create styles. Change the color properties and edit the states for a particular control. Click here “http://www.silverlight.net/learn/tutorials/stylestemplatesvsm-cs/” to learn how to create styles,templates.
After copy-pasting styles for different colors in resource dictionary, remove the "x:Key" property from every style created  for a particular control as it is not required. Your “RedTheme.xaml ” will look like this. Similary there will be styles created for every type of element in BlueTheme.xaml and GreenTheme.xaml files.

Code in RedTheme.xaml file

6) Once the styles are in place ,we now write the logic to apply it to the elements in the StackPanel. The code is written in MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;

//this reference is required…
using System.Windows.Controls.Theming;

namespace Themes_Application
{
    public partial class MainPage : UserControl
    {
        Uri uri_resource;
        public MainPage()
        {
            InitializeComponent();
        }

        //on selecting a color value the theme should be applied.
        private void lstThemeColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string color_name = ((ListBoxItem)(lstThemeColor.SelectedItem)).Content.ToString();
            if (color_name == "Red")
            {
                uri_resource = new Uri("Themes/RedTheme.xaml", UriKind.Relative);
            }
            else if (color_name == "Blue")
            {
                uri_resource = new Uri("Themes/BlueTheme.xaml", UriKind.Relative);
            }
            else if (color_name == "Green")
            {
                uri_resource = new Uri("Themes/GreenTheme.xaml", UriKind.Relative);
            }

            //get the theme file and apply it to elements in panel.
            ImplicitStyleManager.SetResourceDictionaryUri(pnlElements, uri_resource);
            ImplicitStyleManager.SetApplyMode(pnlElements, ImplicitStylesApplyMode.Auto);
            ImplicitStyleManager.Apply(pnlElements);
        }
    }
}

Here the ImplicitStyleManager is a class that provides methods to do the following tasks.

a) To first locate the resource dictionary which will apply styles to elements. Here it is the xaml files stored in “Themes” folder
b) To get the name of the parent element in which the child controls or descendants have to be applied styles.
c) To implicitly apply styles to the parent element and its descendants.

Thus without doing any StaticResource binding to any of the elements you can create Themes and apply them implicitly.
Here is the final output in browser.

      Green theme applied

       BlueTheme applied

Red Theme applied

How to consume/connect/use WCF service for Silverlight4 application.

The process is simple. You should know two things,what has to be provided as service.
Where it would be consumed.
Here Windows Communication Foundation lets you create services.
Silverlight application is the client which will consume it.

Steps for creating WCF service:
1) Select a Silverlight application hosted in Web application project.
2) Add to it a WCF service.

Img1
3) Three files will be added to your project.I have chosen the default names.

img2
4) The IService1.cs interface will define the contract and Service1.svc.cs will implement it.

Here MyHello is a simple method to return a message on input of a string.

Code in IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Sample1.Web
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string MyHello(string name);
    }
}

Code in Service1.svc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Sample1.Web
{
    public class Service1 : IService1
    {
        public string MyHello(string name)
        {
            return "Hello "+name+" from WCF service";
        }
    }
}

 
5) Once the service is created build the project and the view the .svc file in browser.

img3

 

Steps for consuming the service.
6) In our Silverlight application,in our xaml page we will add a textbox to enter a name , a button to call WCF service and a textblock to display the output.

img6  

<UserControl x:Class="Sample1.MainPage" 
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="Click to call WCF Service" Height="52" HorizontalAlignment="Left"   Margin="44,148,0,0" Name="btn_CallService" VerticalAlignment="Top" Width="320" Click="btn_CallService_Click" />
        <TextBox Height="64" HorizontalAlignment="Left" Margin="44,60,0,0" Name="txt_EnterName" VerticalAlignment="Top" Width="319" />
        <TextBlock Height="52" HorizontalAlignment="Left" Margin="44,222,0,0" Name="txt_DisplayHello" Text="" VerticalAlignment="Top" Width="318" />
    </Grid>
</UserControl>

 
7) Your silverlight application  has to first discover the service created. So add a service reference to your silverlight application project.

 img4

The project structure.

img5
8) Finally the last step. Create a proxy which is an object of ServiceClient to access the method. The methods are loaded asynchronously hence you may not see the name of the method,but two additional methods,one to load method asynchronously and the other to do something once its completed.

 

Code in MainPage.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.ServiceModel;

namespace Sample1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void btn_CallService_Click(object sender, RoutedEventArgs e)
        {
            ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client();

           //Hooking up the event to display the entered text.
            proxy.MyHelloCompleted +=new EventHandler<ServiceReference1.MyHelloCompletedEventArgs>    (proxy_MyHelloCompleted);

           //Passing the text input
            proxy.MyHelloAsync(txt_EnterName.Text);

        }

     

        void proxy_MyHelloCompleted(object sender, ServiceReference1.MyHelloCompletedEventArgs e)
        {
            txt_DisplayHello.Text = e.Result;
        }

    }
}

9) Its done. Now when you run your application,on click event of button the WCF service will call the function asynchronously to take in the entered text and display the output in textblock.

img7

 

Note: In Silverlight 4 application when using a WCF service I did not have to change the bindings from wsHttpBinding to basicHttpBinding.

Else we had to do it in  earlier versions of Silverlight applications.