Sunday, February 2, 2014

Pattern Lock for Windows Phone

Do you have a security / privacy application? You need to lock your application's screen to provide secure access? Well, I am writing a series of open source control which will help you do just that!

In this first article, I am going to cover how to create a Pattern Lock or Swipe Lock, that you might have seen quite often on Android platform. This is my second effort to port such functionality from Android platform or other platforms. First up is Notification Notch Control.

                                              Image 1. A sample for swipe lock

Well, I'll try to create something which blends nicely with Modern UI a.k.a Metro.

                                           Image 2A sample for WP swipe lock

PREREQUISITE:  


1. Knowledge of MVVM in .Net.
2. MVVM Light Toolkit.

                                   Image 3. Snapshot for Project's core component


LETS START BUILDING THE CONTROL: 

We will quickly watch for the core STEPS to build this control.

CREATE RECTANGULAR COMPONENT:

Our main component is Rectangle (which fits well in Metro design) as shown in image  2.


Image 4Rectangle when not selected                            Image 5Rectangle when selected 

Following code is used to build square component:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace PatternLockControl.Code
{
    public class SquarePattern : PatternDesignBase
    {
        #region Data
        #region SquareProperty
        private Border _Square;
        public Border Square
        {
            get
            { return _Square; }
            set
            {
                if (_Square == value)
                {
                    return;
                }
                _Square = value;
                RaisePropertyChanged("Square");
            }
        }
        #endregion

        /// 
        /// Sets or gets the Zindex Value for Icon
        /// 
        public override int ZIndexVal
        {
            get { return (int)Square.GetValue(Canvas.ZIndexProperty); }
            set { Square.SetValue(Canvas.ZIndexProperty, value); }
        }

        #region BorderColProperty
        private Color _BorderCol;
        public Color BorderCol
        {
            get
            { return _BorderCol; }
            set
            {
                if (_BorderCol == value)
                {
                    return;
                }
                _BorderCol = value;
                RaisePropertyChanged("BorderCol");
                BorderBrush = new SolidColorBrush(_BorderCol);
            }
        }
        #endregion

        #region BorderBrushProperty
        private SolidColorBrush _BorderBrush;
        public SolidColorBrush BorderBrush
        {
            get
            { return _BorderBrush; }
            private set
            {
                if (_BorderBrush == value)
                {
                    return;
                }
                _BorderBrush = value;
                RaisePropertyChanged("BorderBrush");
            }
        }
        #endregion

        public int Row { get; set; }

        public int Column { get; set; }
        #endregion

        #region Constructor
        public SquarePattern(int row, int column, int width, int value, Color fillNormal, Color fillSelected, Color borderCol)
            : base(fillNormal, fillSelected, value)
        {
            this.FillColNormal = fillNormal;
            this.BorderCol = borderCol;
            this.Row = row;
            this.Column = column;
            Square = new Border() { Name = string.Concat(row, column), Width = width, Height = width, Background = this.FillBrushNormal, BorderBrush = BorderBrush, BorderThickness = new Thickness(2) };
            ZIndexVal = 1;
        } 
        #endregion

        #region Methods
        public override void GridPosition(int row, int col)
        {
            Square.SetValue(Grid.RowProperty, row);
            Square.SetValue(Grid.ColumnProperty, col);
        }
        public override void MarkAsSelected()
        {
            this.Square.Background = FillBrushSelected;
        }
        #endregion
    }
}

Note: This class inherits from PatternDesignBase (abstract) class. PatternDesignBase work as a base class for such controls which could have different core items like Square (in current sample), Triangle, Circles, etc.

CREATE LAYOUT ROOT :

This control's layout will be hosted in a UserControl which also implements it's  core functionality for Pattern Lock Control.

Full code can be found in PatternLockMetroControl.cs and PatternLockMetroControl.xaml. I am going to list down important functionalities from it.
  1. InitializeAnimateGrid. 
  2. DrawLine.
  3. AddPolygon: . 
InitializeAnimateGrid
This method is responsible to initializing SquarePatterns and placing them into a Grid control which collectively forms core of this control

private void InitializeAnimateGrid()
        {
            LockPatterShapes = new ObservableCollection();
            var chromeColor = (this.Resources["PhoneAccentBrush"] as SolidColorBrush).Color;
            int pattVal = 0;
            for (int row = 0, maxRows = RootContainer.RowDefinitions.Count; row < maxRows; ++row)
            {
                for (int col = 0, maxCols = RootContainer.ColumnDefinitions.Count; col < maxCols; ++col)
                {
                    var LockPatterShape = new SquarePattern(row, col, 100, pattVal++, Colors.Black, chromeColor, chromeColor);
                    LockPatterShape.GridPosition(row, col);
                    RootContainer.Children.Add(LockPatterShape.Square);
                    LockPatterShape.Square.MouseEnter += SquarePattern_MouseMoveEvent;
                    LockPatterShape.Square.MouseLeftButtonUp += Square_MouseLeftButtonUp;
                    LockPatterShapes.Add(LockPatterShape);
                }
            }
        }

DrawLine
This methods holds the responsibility to draw lines between two square pattern, as we continue to swipe. There are certain methods available in LineHelper class which helps to complete the task by this method. This method comes into action when user starts moving his fingers on screen. I've captured the sample code for a quick reference here.

private void DrawLine()
        {
            if (MyPattern.Count < 2) return;
            if (_MouseMoveLine != null)
            {
                RootContainer.Children.Remove(_MouseMoveLine);
                _MouseMoveLine = null;
            }

            Point ptDest, ptSource;
            var sqPattEnd = MyPattern.LastOrDefault().Value;
            var sqPattStart = MyPattern.ElementAt(MyPattern.Count - 2).Value;

            //Find points to draw line from start and end.
            ptDest = LineHelper.GetPtRelativeToQuadrant(RootContainer, sqPattEnd.Square, LineHelper.FindQuadrantToDrawLineBW(sqPattEnd.Row, sqPattEnd.Column, sqPattStart.Row, sqPattStart.Column));
            ptSource = LineHelper.GetPtRelativeToQuadrant(RootContainer, sqPattStart.Square, LineHelper.FindQuadrantToDrawLineBW(sqPattStart.Row, sqPattStart.Column, sqPattEnd.Row, sqPattEnd.Column));

            Line line;
            LineType lType = LineHelper.FindLineType(sqPattStart.Row, sqPattStart.Column, sqPattEnd.Row, sqPattEnd.Column);

            if (lType == LineType.SIMPLE)
                line = LineHelper.CreateLine(ptSource, ptDest, DragLineWidth, (this.Resources["PhoneAccentBrush"] as SolidColorBrush), ZIdxForDrawnLines++, RootContainer, lType);
            else
                line = LineHelper.CreateLine(ptSource, ptDest, DottedLineWidth, SelectedLineBrush, ZIdxForDrawnLines++, RootContainer, lType);
            AddPolygon(MyPattern.ElementAt(MyPattern.Count - 2).Value.Square, LineHelper.FindQuadrantToDrawLineBW(sqPattStart.Row, sqPattStart.Column, sqPattEnd.Row, sqPattEnd.Column));

            RootContainer.Children.Add(line);
        }



AddPolygon
This method generates tiny white colored triangle. These little triangles indicate the direction of swipe when user swipes it's fingers from one rectangle to another. These triangles will only be visible when they have moved from one rectangle to another. Logic to identify where the triangles to be drawn is written inside GetPoinstForPolygon(). A sample code for AddPolygon is referenced here:

private void AddPolygon(Border shape, LineQuadrant quad)
        {
            Polygon poly = new Polygon();
            poly.Fill = new SolidColorBrush(Colors.White);
            poly.Points = LineHelper.GetPointsForPolygon(shape.ActualWidth, quad, poly);
            shape.BorderThickness = new Thickness(0);
            shape.Child = poly;
            //Set the Max ZIdx for poly/Border so that it will always be on top of all drawn lines
            shape.SetValue(Canvas.ZIndexProperty, ZIdxForDrawnLines + 1);
        }

That's it!! We are DONE!!!


OTHER IMPORTANT FEATURES / INFO:

1. Registration Mode : We can easily configure this control to register a new pattern or to use verify an existing pattern
2. Decoy Pattern : This feature provides an additional flexibility to register additional set of pattern. This will be helpful in case you want your application to support multiple access mode say one for Admin and another for User mode. 
3. Pattern Format : Based on your selection i.e. Registration Mode or Verify Pattern mode this control will generate an event to publish the result. In case of Registration mode if your selection is as per Image 6 then it will return a List of integer [1,2,3,6,9].

                                           Image 6A sample selection for result.


VIDEO

Monday, December 24, 2012

Notification Notch Control for Windows Phone

Many of you would have wondered why there is no Notification Notch in +Windows Phone, similar to the one seen first in Android and then later in iOS5 as well. However, there might be some restriction/limitation for them (WP team) to implement Notification Notch at this point of time but this shouldn't stop you from implementing it in your application. In today's article I am going to explain how to create a Notification Notch and how to use it in your application.

Well, our objective will be completed in 3 steps:

1. Create a custom behavior i.e. "Drag Notch Behavior" to mimic drag and expand/close nature of a notification notch.
2. Create a sample user control i.e. "Drag Notch Control" to use this behavior.
3. Create a sample project to use this control.

PREREQUISITE:  

1. Knowledge of Behavior in .Net

BUILDING HELPER CLASSES:

There are a few extension methods that are required to easily find and manipulate a FrameworkElemant from code. For doing so I've shamelessly pinched the code from "Joost van Schaik"  code article - "Simple Windows Phone 7 / Silverlight drag/flick behavior". These Libraries can be found under utilities in my sample code attached.








 










DRAG NOTCH BEHAVIOR:

Code for DragNotch Behavior is implemented by following class:
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Animation;
using nishantcop_Behaviors.Utilities;

namespace nishantcop_Behaviors.Behaviors
{
    public class DragNotchBehavior : Behavior
    {
        private FrameworkElement _elementToAnimate;
        public event NotchStateChangedHandler NotchStateChanged;

        public delegate void NotchStateChangedHandler(object sender, NotchStateChangedEventArgs e);

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.Loaded += AssociatedObjectLoaded;
            AssociatedObject.ManipulationDelta += AssociatedObjectManipulationDelta;
            AssociatedObject.ManipulationCompleted += AssociatedObjectManipulationCompleted;

        }

        void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
        {
            _elementToAnimate = AssociatedObject.GetElementToAnimate();
            if (!(_elementToAnimate.RenderTransform is CompositeTransform))
            {
                _elementToAnimate.RenderTransform = new CompositeTransform();
                _elementToAnimate.RenderTransformOrigin = new Point(0.5, 0.5);
            }
            StartPosition = AssociatedObject.GetTranslatePoint();
        }

        void AssociatedObjectManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            //var dx = e.DeltaManipulation.Translation.X;
            var dy = e.DeltaManipulation.Translation.Y;
            var currentPosition = _elementToAnimate.GetTranslatePoint();
            _elementToAnimate.SetTranslatePoint(currentPosition.X, currentPosition.Y + dy);
        }

        private void AssociatedObjectManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            // Create a storyboard that will emulate a 'flick'
            var currentPosition = _elementToAnimate.GetTranslatePoint();
            var velocity = e.FinalVelocities.LinearVelocity;
            if (velocity.Y > 0)
            {
                //var to = new Point(currentPosition.X, 360 + (velocity.Y / BrakeSpeed));
            }

            var storyboard = new Storyboard { FillBehavior = FillBehavior.HoldEnd };

            var to = new Point(currentPosition.X + (velocity.X / BrakeSpeed),
                currentPosition.Y + (velocity.Y / BrakeSpeed));
            storyboard.AddTranslationAnimation(_elementToAnimate, currentPosition, GetEndPoint(),
                new Duration(TimeSpan.FromMilliseconds(500)),
                new CubicEase { EasingMode = EasingMode.EaseOut });
            storyboard.Begin();
        }

        protected override void OnDetaching()
        {
            AssociatedObject.Loaded -= AssociatedObjectLoaded;
            AssociatedObject.ManipulationCompleted -= AssociatedObjectManipulationCompleted;
            AssociatedObject.ManipulationDelta -= AssociatedObjectManipulationDelta;
            base.OnDetaching();
        }

        private Point GetEndPoint()
        {
            double midPoint = Math.Abs(StartPosition.Y) - Math.Abs(_elementToAnimate.GetTranslatePoint().Y);
            if (midPoint &lt; Math.Abs(StartPosition.Y) / 2)
            {
                
                NotchStateChanged(this, new NotchStateChangedEventArgs(false));
                return StartPosition;
            }
            else
            {
                IsNotchExpanded = true;
                NotchStateChanged(this, new NotchStateChangedEventArgs(true));
                return EndPosition;
            }
        }

        /// 
        /// This function tries to collapse a notch if it's expanded.
        /// 
        public void TryRollBackNotch()
        {
            var currentPosition = _elementToAnimate.GetTranslatePoint();
            if (currentPosition != StartPosition)
            {
                var storyboard = new Storyboard { FillBehavior = FillBehavior.HoldEnd };

                storyboard.AddTranslationAnimation(_elementToAnimate, currentPosition, StartPosition,
                    new Duration(TimeSpan.FromMilliseconds(500)),
                    new CubicEase { EasingMode = EasingMode.EaseOut });
                storyboard.Begin();
                storyboard.Completed += new EventHandler(storyboard_Completed);
            }
        }

        void storyboard_Completed(object sender, EventArgs e)
        {
            var storyboard = sender as Storyboard;
            storyboard.Completed -= storyboard_Completed;
            IsNotchExpanded = false;
            NotchStateChanged(this, new NotchStateChangedEventArgs(false));
        }

        #region IsNotchExpandedProperty
        public bool IsNotchExpanded
        {
            get { return (bool)GetValue(IsNotchExpandedProperty); }
            set { SetValue(IsNotchExpandedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsNotchExpanded.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsNotchExpandedProperty =
            DependencyProperty.Register("IsNotchExpanded", typeof(bool), typeof(DragNotchBehavior), new PropertyMetadata(false, OnIsNotchExpandedPropertyChanged));

        private static void OnIsNotchExpandedPropertyChanged(DependencyObject source,
        DependencyPropertyChangedEventArgs e)
        {
            DragNotchBehavior behavior = source as DragNotchBehavior;
            bool time = (bool)e.NewValue;
            // Put some update logic here...
        } 
        #endregion

        #region BrakeSpeed
        public const string BrakeSpeedPropertyName = "BrakeSpeed";

        /// 
        /// Describes how fast the element should brake, i.e. come to rest,
        /// after a flick. Higher = apply more brake ;-)
        /// 
        public int BrakeSpeed
        {
            get { return (int)GetValue(BrakeSpeedProperty); }
            set { SetValue(BrakeSpeedProperty, value); }
        }

        public static readonly DependencyProperty BrakeSpeedProperty = DependencyProperty.Register(
            BrakeSpeedPropertyName,
            typeof(int),
            typeof(DragNotchBehavior),
            new PropertyMetadata(10));

        #endregion

        #region StartPosition
        public Point StartPosition
        {
            get { return (Point)GetValue(StartPositionProperty); }
            set { SetValue(StartPositionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StartPosition.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StartPositionProperty =
            DependencyProperty.Register("StartPosition", typeof(Point), typeof(DragNotchBehavior), new PropertyMetadata(new Point(0, 0)));
        #endregion

        #region End Position
        public Point EndPosition
        {
            get { return (Point)GetValue(EndPositionProperty); }
            set { SetValue(EndPositionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for EndPosition.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty EndPositionProperty =
            DependencyProperty.Register("EndPosition", typeof(Point), typeof(DragNotchBehavior), new PropertyMetadata(new Point(0, 0))); 
        #endregion
        
    }
}

This behavior exposes following important properties:
  1. StartPosition: Element starts it's animation at this point. 
  2. EndPostion: Element ends it's animation at this point.
  3. BrakeSpeed: Speed by which animation should come to halt. 
  4. TryRollBackNotch:  A Function to force close/Rollback your Notification Notch control. 
  5. NotchStateChanged: An Event to notify the change in status of Notification Notch control i.e. closed or expanded.  
If you wish to fiddle around with it you can change the behavior to move horizontally only, contrasted to it's default vertical movement.

For adding a NotchStateChanged Event you will need to provide an customized EventArgs class. Code for which will look like this: 
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace nishantcop_Behaviors.Utilities
{
    public class NotchStateChangedEventArgs : EventArgs
    {
        private bool _IsNotchExpanded;

        public NotchStateChangedEventArgs(bool isNotchExpanded)
        {
            this._IsNotchExpanded = isNotchExpanded;
            //this.exceededPercentage = exceededPercentage;
            // not shown - validation for input
        }

        public bool IsNotchExpanded
        {
            get { return this._IsNotchExpanded; }
        }
    }
}

This class provides current state for your Notch Control. We handle this class in our Drag Notch Behavior whenever we are animating our control for expanding and closing it. 

So, that's about the Drag Notch Behavior now lets take a look into how exactly to use it in your project. 

DRAG NOTCH CONTROL

Now we need a DragNotch control that can be used across our application. A sample xaml for DragNotch control is: 


 
  
            
        
  
   
  
  
  
 
This control simply contains a Grid and our DragNotchBehavior is attached to it. For this custom behavior we need to set it's x:fieldModifier = "public" so that we can access it from code behind. Also we need to set the TranslateY property of CompositeTransform to a suitable position so that it won't be visible until it's being dragged. For this demo I've set this value to -700. However it can be easily tweaked as per your requirement.

Code behind for your DragNotch control:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace WPTestBehavior
{
 public partial class DragNotch : UserControl
 {
  public DragNotch()
  {
   // Required to initialize variables
   InitializeComponent();
  }

        private void Notch_NotchStateChanged(object sender, nishantcop_Behaviors.Utilities.NotchStateChangedEventArgs e)
        {
            bool b = e.IsNotchExpanded;
        }
        public void RollBackNotch()
        {
            Notch.TryRollBackNotch();
        }
 }
}

In code behind we are handling the NotchStateChanged event from our behavior and a public method (RollBackNotch) is exposed so that you can force your control to collapsed.

Now, your control is ready you can fill in whatever you want inside this grid, for your notification purpose or whatever you may want to call it :-)

USE DRAG NOTCH CONTROL

For using the DragNotch control in last step I've created this sample page:



    
    
        
            
            
        

        
        

        
        
         
         
         
        
    
This page contains ListBox filled with some sample data and our "TestDragNotch" control to overlay it when it's expanded to demonstrate the Notification Notch behavior.

VIDEO

Sunday, December 2, 2012

Mashape API - How to Consume in WP

Today I'll talk about Mashape APIs and their integration into WP project.  Before getting into more details I'll like to answer few FAQs.

Q1 : What is Mashape?
Ans: Mashape is API cloud based API hub. You can used hosted API there and can quickly develop an application.

Q2 : How can I use that in WP Application?
Ans: You can consume their API(s) using REST services in WP. (Soon, auto generated client libraries will also be supported for WP code).

Prerequisite:

1. Json Client Library: This library will be helpful to consume Json response from Mashape's AP. Download the source code and compile it for the WP version you are going to use and then add in your project and use.  

How to consume REST API in Windows Phone

For my sample app I am consuming  QR code generator API.

1. Create a WebClient Request:

WebClient client = new WebClient();

2. Set Content Type in request's Header:

client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";


3. Add Authorization Header: An authorization code is required to authenticate each request, this code can be easily generated by a tool provided at this link for all registered Mashape users





client.Headers["X-Mashape-Authorization"] = "YourAutorizationHeaderNeedToGenerateFromTool";


4. Add Data for Web Request:

StringBuilder postData = new StringBuilder();
postData.AppendFormat("{0}={1}", "content", HttpUtility.UrlEncode("TestQRCode"));
postData.AppendFormat("&{0}={1}", "quality", HttpUtility.UrlEncode("L"));
postData.AppendFormat("&{0}={1}", "type", HttpUtility.UrlEncode("text"));
postData.AppendFormat("&{0}={1}", "size", HttpUtility.UrlEncode("5"));


5. Create Mashape API's URI: This URI responsible to call a specific API listed in Mashape cloud listing. You can get the URL from Mashape site as shown here


var uri = new Uri("https://mutationevent-qr-code-generator.p.mashape.com/generate.php?", UriKind.Absolute);


6. Register a Asyn Call Completed Event:

client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted)


7. Make Async http Call:

client.UploadStringAsync(uri, "POST", postData.ToString());


8. Consume Response in completed event:

void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
    var client = sender as WebClient;
    client.UploadStringCompleted -= client_UploadStringCompleted;
    string response = string.Empty;
    if (!e.Cancelled)
    {
        response = HttpUtility.UrlDecode(e.Result);
    }
}

You are done!!!

A full working sample can be found at the links given below.

Source Code: WP7, WP8

Saturday, September 8, 2012

WP Context Menu using MVVM

When I used ContextMenu in my application for the very first time, my applications were not using MVVM. Therefore, I had to add a context menu either in code behind or using Event Handler in code behind. Now, there were two issues in doing so :

1. Tedious Code Structure :  While adding a context menu from code behind and managing events.
2. Style Can't be saved to Resource Dictionary : While using Event Handler in xaml you can't define a style in Resource Dictionary because they do not have a code behind file. So you must define the style in your view only. It restrict the modularity of your application.

You can find many good articles about using ContextMenu in code behind. But problem still remains the same. So now how to solve this in more elegant way? And the answer comes with MVVM

For this article of mine I am using Galasoft-MVVM Light. A handful of useful links: 
  1. Download Galasoft-MVVM Light from here
  2. Alternatively, you can install it from NuGet (VS extension). 
  3. Learn how to install NuGet package from here
I am presuming you may have a little understanding of Galasoft's MVVM Light or any other MVVM framework, to better understand this article. 

Prerequisite (installed): 
1. NuGet extension for VS.
3. Galasoft-MVVM Light.

1. Objective: 

We will try to create a ListBox and fill it with some text item(s).  Each item in ListBox should have context menu say "READ" on click of that MenuItem we should be able to display the value of selected ListBox item.

2. Create a New Project: 

Create a new Project -> Silverlight for Windows Phone -> Mvvm and name it ContextMenu_MVVM.
Note:- once you have MVVM installed a default template will be available in Installed Templates as shown below. 



















3. Adding a Resource Dictionary (Style):

Open your project in Expression Blend. Once it's opened in Blend, right click project and Select Add new item





















Select Resource Dictionary and rename it Styles.xaml(Refer image above).

Now replace the code of Styles.xaml with this code:



 
 

This code contains a necessary style for a ListboxItem, that we are going to use for our demonstration purpose. 

4. Adding Code For MainPage.xaml 

In you MainPage.xaml replace code for ContentPanel grid with this one:


  
   
  


5. Update Code for MainPage View Model: 

In you MainViewModel.cs add this code in using syntax area to include the reference for some namespaces:

using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using System.Windows;


Add this code to same page just before you MainViewModel class closes:

#region Properties
public RelayCommand CTest { get; private set; }

private ObservableCollection _CtxItems;
public ObservableCollection CtxItems
{
    get
    { return _CtxItems; }
    set
    {
        if (_CtxItems == value)
        {
            return;
        }
        var oldValue = _CtxItems;
        _CtxItems = value;
        base.RaisePropertyChanged("CtxItems");
    }
}

private string _SelectedCtxItems;
public string SelectedCtxItems
{
    get
    { return _SelectedCtxItems; }
    set
    {
        if (_SelectedCtxItems == value)
        {
            return;
        }
        var oldValue = _SelectedCtxItems;
        _SelectedCtxItems = value;
        base.RaisePropertyChanged("SelectedCtxItems");
    }
} 
#endregion

#region Methods
private void LoadData()
{
    CtxItems = new ObservableCollection();
    for (int i = 0; i < 10; i++)
    {
        CtxItems.Add("Item " + i.ToString());
    }
}

private void Test(string data)
{
    MessageBox.Show(data);
}
#endregion

This code contains all the logic for populating your ListBox and RelayCommands used for doing command binding.

Add following code to MaiViewModel constructor to initialize the collection that we placed in code above.

public MainViewModel()
{
    if (IsInDesignMode)
    {
        // Code runs in Blend --> create design time data.
    }
    else
    {
        LoadData();
        CTest = new RelayCommand(Test);
    }
}

6. Working :

Style:

A style for ListBox item is defined in styles.xaml which contains a Textbox which has a ContextMenu. For this ContextMenu we have bound its property called Command to Relay Command i.e. CTest in MainViewModel. Also we are binding CommandParameter property of ContextMenu with Templated DataContext to insure we get currently selected item in our view-model. 

ViewModel: 

It contains 4 items:
  1. CTest: A property that will expose a relay command to enable binding to our view. 
  2. CtxItems: A property that provides ann ObservableCollection that contains items to be listed in ListBox. 
  3. LoadData: Methods to initialize CtxItems. 
  4. Test: An Action that need to be passed in as an argument for relay command while initializing command. 
A full source code link is given below for reference.

Source Code

Thanks and Regards
Nishant Rana

Thursday, December 29, 2011

Add Scrolling Event in a List - WP7

Many of you might have been in  a situation when you desperately wanted to know if a scroll bar is scrolling or not.

Currently there is no direct provision to attain this in WP7. I'll walk through the code which will help you to identify if a list is scrolling or not. Later at the end there ia a full working sample attached.

My sample is straight forward. I'll be changing the page title to "Scrolling" when we scroll the list and "NotScrolling" while it is stationary.

We have a list called theList.

1. Now attach a Loaded event to the page constructor:

public MainPage()
{
    InitializeComponent();
    Loaded += new RoutedEventHandler(MainPage_Loaded);
    theList.ItemsSource = GetListData(60);
}

2. Define a variable to identify if ScrollEvent has been hooked already:

bool alreadyHookedScrollEvents = false;

3. Define MainPage_Loaded handler. All major work will be done here:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    if (alreadyHookedScrollEvents)
        return;

    alreadyHookedScrollEvents = true;

    //This is the key player which holds the magic for this trick
    //This ScrollViewer is the first templated child of your List
    ScrollViewer viewer = FindSimpleVisualChild<ScrollViewer>(theList);

    if (viewer != null)
    {
        // Visual States are always on the first child of the control template 
        FrameworkElement element = VisualTreeHelper.GetChild(viewer, 0) as FrameworkElement;
        if (element != null)
        {
            VisualStateGroup group = FindVisualState(element, "ScrollStates");
            if (group != null)
            {
                group.CurrentStateChanging += group_CurrentStateChanging;
            }
        }
    }
}

4. Use this helper function to identify the first visual child (ScrollViewer):

T FindSimpleVisualChild<T>(DependencyObject element) where T : class
{
    while (element != null)
    {
        if (element is T)
            return element as T;
        element = VisualTreeHelper.GetChild(element, 0);
    }
    return null;
}

5. Actual even handler which identify a changed state for scrollviewer:

void group_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)
{
    //for demonstration change page's title
    PageTitle.Text = e.NewState.Name;
}

6. Helper function to filter out the required VisualState:


VisualStateGroup FindVisualState(FrameworkElement element, string name)
{
    if (element == null)
        return null;

    IList<VisualStateGroup> groups = (IList<VisualStateGroup>)VisualStateManager.GetVisualStateGroups(element);
    foreach (VisualStateGroup group in groups)
        if (group.Name == name)
            return group;

    return null;
}

     
7. Another helper function to fill the data in list to demonstrate implementation:


ObservableCollection<int> GetListData(int count)
{
    sourceList = new ObservableCollection<int>();
    for (int i = 1; i <= count; i++)
    {
        sourceList.Add(i);
    }
    return sourceList;
}

     
Source Code

Thursday, September 29, 2011

Windows Phone 7 and Emulator Shortcut Keys

KeyDescription
F1Use F1 key on the keyboard instead of back button on the phone
F2Use the key F2 on the keyboard for the Windows key in the Windows Phone 7
PageupEnables the keyboard in the emulator when the focus is on the textbox
PageDownDisables the keyboard in the emulator
F3To open the Bing Search
F7To Activate the Physical Camera
F9Increase the Volume
F10Decrease the volume

Additional link from MSDN





Thursday, August 25, 2011

Passing Data between Pages in Windows Phone 7


Passing data among pages is something which needs to be given a little care in terms what approach you follow . Since each approach has its own benefits and side effects. I'll try to explain each of them one by one.

For illustration of this concept I've created a sample code which is attached at the end of the article. In this project I've various project each corresponds to one approach which I've described below. Each project has two pages. Touching on the coloured part of one page takes you to another page. First page will display a text string which is provided by the second page. You can simply go to second page add some text into TextBox and you can touch the coloured part to go back to first page which displays the string which you entered on first page.

So here are the approaches one by one:

1. Using Global Variable: This is the easiest and quickest procedure to pass your data among various pages.

Define a "Global Variable" in your App.xaml file as:
public string SecondPageText { get; set; }

After that on your Second page on ManipulationStarted event for the coloured Border use this code:
App.Current as App).SecondPageText = txtBox.Text; // add value to Global variable
NavigationService.GoBack(); // Navigate to first page

PhonePageOne page add this:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
     base.OnNavigatedTo(e);
     txtBlock.Text = (App.Current as App).SecondPageText;
}

2. Using Query String: This procedure is good when we just need to share string based data between two pages.

Add this code in your PhonePageTwo:
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
         string uri = "/PhonePageOne.xaml?Text=";
         uri += txtBox.Text;
         NavigationService.Navigate(new Uri(uri, UriKind.Relative));
}

Use this code in your PhonePageTwo:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
         IDictionary<string, string> parameters = this.NavigationContext.QueryString;
         if (parameters.ContainsKey("Text"))
         {
             txtBlock.Text = parameters["Text"];
         }
}

3. Using PhoneApplicationSerivce States: Every application has a PhoneApplicationService defined Microsoft.Phone.Shell. Each application has one PhoneApplicationService defined in its App.xaml file. We can use this service's property called "State". These "States" are all transient data which means they are available only for one instant of your application which means once you restart your application these states will be lost. Also we should not try to create a new PhoneApplicationService instead we must try to use the service from the current instant. Which can be retrieved using this code:

PhoneApplicationService.Current.State

Now, lets look how can we really use it in our sample.

PhonePageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    PhoneApplicationService.Current.State["Text"] = txtBox.Text;
} 
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
    NavigationService.GoBack();
}

PhonePageOne add this code:

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
 NavigationService.Navigate(new Uri("/PhonePageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if(PhoneApplicationService.Current.State.ContainsKey("Text"))
        txtBlock.Text = (string)PhoneApplicationService.Current.State["Text"];
}

4. Using NextPage intance: Whenever we call "Navigate" using a "/PageOne.xaml" or "/PageTwo.xaml" the OnNavigatedFrom method in current page is called with event arguments with a  Uri property indicating other page and a Content property of type that page (Navigating to) . After that OnNavigatedTo of other page will be called with same arguments. So we have an opportunity to fix the set the value for next page prior to navigating to it. Just take a look at the sample code:

PageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (e.Content is PageOne)
    {
        (e.Content as PageOne).txtBlock.Text = txtBox.Text;
    }
} 
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
    NavigationService.GoBack();
}

PageOne add this code: (Basically no need to do any thing just use this)

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
 NavigationService.Navigate(new Uri("/PageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
 base.OnNavigatedTo(e);
}


Source Cod