Sunday, December 30, 2012

How to manipulate cursor for WinRT UI control as like WPF control?


In this blog post I am going to demonstrate on how to manipulate cursor for WinRT UI control as like in WPF control.

In WPF, you will find a property (Cursor) in UI control which allows you to get/sets the cursor which displays when mouse pointer is over the UI (ex: Textbox) element. Whereas in WinRT environment there is no cursor property for each UI control instead we can manipulate the cursor used by the window using the current core window pointer cursor.

//Gets or sets the cursor used by the window.
Window.Current.CoreWindow.PointerCursor

In the below sample (referred from WinRTXamlToolkit samples) I have manipulated the cursor used by the window when hovering over (pointer entered and pointer exited event) the text block element.

Sample link:
 
Code Snippet:

private void txtBlock_PointerEntered_1(object sender, PointerRoutedEventArgs e)
{
//Store current cursor used by the window
m_defaultCursor = Window.Current.CoreWindow.PointerCursor;
//Set cursor of current core window
Window.Current.CoreWindow.PointerCursor = Cursor;
}
 
private void txtBlock_PointerExited_1(object sender, PointerRoutedEventArgs e)
{
//Reset pointer cursor on mouse pointer exits
Window.Current.CoreWindow.PointerCursor = m_defaultCursor;
}

References:

Thursday, September 6, 2012

How to access Manifest (Embedded) resource from an Assembly in WinRT application.


In this blog post, I am going to demonstrate on how to access a simple XML file embedded in the WinRT assembly.

One of the easier way to retrieve an assembly in .Net application is by using below method.
// This will return the assembly whose code is currently executing.
Assembly.GetExecutingAssembly();

Alternate one is to use Type object of the classes present in the assembly.
Assembly assembly = typeof(DemoClass).GetType().Assembly;

From the assembly object we can retrieve the manifest resource stream (embedded file) using GetManifestResourceStream() method. All we need is to pass the name of the embedded resource. The name of the embedded resource is the combination of root namespace, folder path and the file name.

For example consider the root namespace of a demo application to be MyApp and the XML file (Embedded.xml) is available under Resources folder of the assembly. Then the name of the embedded resource is “MyApp.Resources.Embedded.xml”.

Sample code snippet for .Net
Assembly assembly = Assembly.GetExecutingAssembly();
Or
Assembly assembly = typeof(DemoClass).GetType().Assembly;

Stream xmlStream = assembly.GetManifestResourceStream("MyApp.Resources.Embedded.xml");

In WinRT, Both GetExecutingAssembly() and GetType().Assembly are not available, instead you can retrieve the assembly object from the classes declared in the assembly by means of using TypeInfo object. Now the remaining part to access the manifest resource is same as in .Net application. Please find the code snippet from below.

Sample code snippet for WinRT
Assembly assembly = typeof(DemoClass).GetTypeInfo().Assembly;
Stream xmlStream = assembly.GetManifestResourceStream("MyApp.Resources.Embedded.xml");

Please find the demo application from below link


In this application, embedded XML file is retrieved and its contents are displayed in a text box.

Monday, July 16, 2012

How to implement “Infinite Scroll” in web application?


In this blog post, I am going the demonstrate the steps involved in implementing “Infinite Scroll” in web application for loading images just like in Bing and Google image search.

Infinite Scroll – Infinite scroll has been called auto paganize/endless pages. But essentially it is pre-fetching content from a subsequent page and adding it directly to the user’s current page.

One of the most annoying thing when working with large data is how to continuously loading the data on demand to your page?
The common solution is paging but paging itself will not help too much you can end with hundreds or thousands of pages. So a new solution now is on the surface and it's called "Infinite Scroll". It allows you to load chunk of data when you scroll down of the page and inject it inside the page, it will load data each time you scrolling down on the page.


 
Step 1: Include jquery library file. You can download the current version of “jquery” library from this link http://docs.jquery.com/Downloading_jQuery

<script type="text/javascript" src="Scripts/jquery-x.x.x.min.js"></script>

Step 2: Add Images folder to the web project which contains images that is loaded on runtime in the website.

Step 3: Add below designer code to create a list view to load the images initially.
<asp:ListView ID="ListView1" runat="server" EnableModelValidation="True">
        <LayoutTemplate>
            <ul id="itemPlaceholderContainer" runat="server" class="thumb">
                <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
             <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("image")%>' />
        </ItemTemplate>
</asp:ListView>

Step 4: Fill the list view with images using below code on Page Load event.
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
         FillListView(48);
    }
}
//Fill images in the list view
private void FillListView(int Rows)
{
     string Imagespath = HttpContext.Current.Server.MapPath("~/Images/");
     string SitePath = HttpContext.Current.Server.MapPath("~");
     //Load image files using linq query
     var Files = (from file in Directory.GetFiles(Imagespath) select new { image = file.Replace(SitePath, "~/") }).Take(Rows);
      ListView1.DataSource = Files.ToList();
      ListView1.DataBind();
}

Step 5: For now we have loaded 48 images to the list view. In the next step we are going to use the script and the code behind to load the next set of images dynamically on scroll down just like in Google and Bing.
a.       Add below script the aspx file
<script type="text/javascript">
        $(document).ready(function () {
            var Skip = 48; //Number of image to skip
            var Take = 14; //
            function Load(Skip, Take) {
//Post below loader image as progress bar
                $('#divPostsLoader').html('<img src="ProgressBar/ajax-loader.gif">');

                //send a query to server side to present new content
                $.ajax({
                    type: "POST",
           url: "Default.aspx/LoadImages", //Call the LoadImage method in the code behind
                    data: "{ Skip:" + Skip + ", Take:" + Take + " }",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {

                        if (data != "") {
                            $('.thumb').append(data.d); //Append the retrieved images next to list view
                        }
                        $('#divPostsLoader').empty();
                    }

                })
            };
            //Larger thumbnail preview

            //When scroll down, the scroller is at the bottom with the function below and fire the lastPostFunc function
            $(window).scroll(function () {
                if ($(window).scrollTop() == ($(document).height() - $(window).height())) {
                    Load(Skip, Take);
                    Skip = Skip + 14;
                }
            });
        });
    </script>
b.      Add below method next to FillListView(). This method will the next set of images provided number of images to skip and the next set of images to take.
[WebMethod]
        public static string LoadImages(int Skip, int Take)
        {
            System.Threading.Thread.Sleep(2000);
            StringBuilder GetImages = new StringBuilder();
            string Imagespath = HttpContext.Current.Server.MapPath("~/Images/");
            string SitePath = HttpContext.Current.Server.MapPath("~");
            var Files = (from file in Directory.GetFiles(Imagespath) select new { image = file.Replace(SitePath, "~/") }).Skip(Skip).Take(Take);
            foreach (var file in Files)
            {
                var imageSrc = file.image.Replace("\\", "/").Substring(1); //Remove First '/' from image path
                GetImages.Append(" ");
                GetImages.AppendFormat(string.Format("<img src='{0}'/>", imageSrc)); GetImages.Append(" ");
            }
            return GetImages.ToString();
        }

Final Code:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="InfiniteScroll.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Infinite Scroll</title>
    <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            var Skip = 48; //Number of skipped image
            var Take = 14; //
            function Load(Skip, Take) {
                $('#divPostsLoader').html('<img src="ProgressBar/ajax-loader.gif">');

                //send a query to server side to present new content
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/LoadImages",
                    data: "{ Skip:" + Skip + ", Take:" + Take + " }",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {

                        if (data != "") {
                            $('.thumb').append(data.d);
                        }
                        $('#divPostsLoader').empty();
                    }

                })
            };
            //Larger thumbnail preview

            //When scroll down, the scroller is at the bottom with the function below and fire the lastPostFunc function
            $(window).scroll(function () {
                if ($(window).scrollTop() == ($(document).height() - $(window).height())) {
                    Load(Skip, Take);
                    Skip = Skip + 14;
                }
            });
        });
    </script>
    <style type="text/css">
        img { border:"none"; margin:"auto"}
        .container { padding:"2px"; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div class="header">
            <div class="title">
                <h1>
                    Infinite Scroll Example
                </h1>
            </div>
        </div>
        <div>
            <asp:ListView ID="ListView1" runat="server" EnableModelValidation="True">
                <LayoutTemplate>
                    <ul id="itemPlaceholderContainer" runat="server" class="thumb">
                        <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
                    </ul>
                </LayoutTemplate>
                <ItemTemplate>
                    <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("image")%>' />
                </ItemTemplate>
            </asp:ListView>
            <div style="margin-left: auto; margin-right: auto; width: 120px;" id="divPostsLoader">
            </div>
        </div>
    </div>
    </form>
</body>
</html>

Default.aspx.cs
using System;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Text;
using System.IO;
namespace InfiniteScroll
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Fill_List(48);
            }
        }

        private void Fill_List(int Rows)
        {
            string Imagespath = HttpContext.Current.Server.MapPath("~/Images/");
            string SitePath = HttpContext.Current.Server.MapPath("~");
            var Files = (from file in Directory.GetFiles(Imagespath) select new { image = file.Replace(SitePath, "~/") }).Take(Rows);
            ListView1.DataSource = Files.ToList();
            ListView1.DataBind();
        }
        [WebMethod]
        public static string LoadImages(int Skip, int Take)
        {
            System.Threading.Thread.Sleep(2000);
            StringBuilder GetImages = new StringBuilder();
            string Imagespath = HttpContext.Current.Server.MapPath("~/Images/");
            string SitePath = HttpContext.Current.Server.MapPath("~");
            var Files = (from file in Directory.GetFiles(Imagespath) select new { image = file.Replace(SitePath, "~/") }).Skip(Skip).Take(Take);
            foreach (var file in Files)
            {
                var imageSrc = file.image.Replace("\\", "/").Substring(1); //Remove First '/' from image path
                GetImages.Append(" ");
                GetImages.AppendFormat(string.Format("<img src='{0}'/>", imageSrc)); GetImages.Append(" ");
            }
            return GetImages.ToString();
        }
    }
}

This post provides just an introduction (basic) on the usage of “Infinite Scroll” feature. However the likes (immense potential) of which we have already seen in “Facebook updates”, “Flip kart item search” and “Bing and Google image search” etc.,.

References:

Saturday, June 2, 2012

How to decompress files in Metro style applications?


In this blog post, I am going to demonstrate on how to use ZipArchive class in Metro style app to decompress a set of files and save the extracted files to a particular location.

Steps to decompress a set of files:

Step 1: Select the compressed file to decompress.

//Initialize file open picker
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.ViewMode = PickerViewMode.List;
//Suggest start location
fileOpenPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
//Add file type filter
fileOpenPicker.FileTypeFilter.Add("*.zip");
//Opens file open picker to allow the user to select the compressed file
StorageFile stgFile = await fileOpenPicker.PickSingleFileAsync();

Step 2: Select folder to extract the files

//Initialize folder picker
FolderPicker saveFolder = new FolderPicker();
//Suggest start location
saveFolder.SuggestedStartLocation = PickerLocationId.Desktop;
//Add file type filter
saveFolder.FileTypeFilter.Add("*");
//Opens folder picker to allow the user to select the folder to extract the compressed items
StorageFolder storageFolder = await saveFolder.PickSingleFolderAsync();


Step 3: Use ZipArchive class to extract the files to the selected folder
//Read the stream from the compressed file
Stream stream = await stgFile.OpenStreamForReadAsync();
//Copy it to Memory stream for further manipulation
MemoryStream ms = new MemoryStream();
await stream.CopyToAsync(ms);
ms.Position = 0;

//Open Zip archive of the compressed file
zipArchive = new ZipArchive(ms, ZipArchiveMode.Read);

//For each archive entry, create file and folder accordingly and then copy the entry stream to the file.
foreach (ZipArchiveEntry entry in zipArchive.Entries)
{
StorageFile storageFile;
//Assign Selected save folder
StorageFolder stgFolder = storageFolder;
//Create Folder
stgFolder = await CreateFolder(storageFolder, entry.FullName.Replace(entry.Name, string.Empty));
//Create File
storageFile = await stgFolder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
//Open file stream for writing
Stream s = await storageFile.OpenStreamForWriteAsync();
//Copy the entry stream to the file stream
await entry.Open().CopyToAsync(s);
//Dispose
s.Dispose();
}
//Dispose
zipArchive.Dispose();
stream.Dispose();
ms.Dispose();

Helper methods:
Create folder based on the file path present in Zip Archive entry

async Task<StorageFolder> CreateFolder(StorageFolder stgFolder, string path)
{
//Split the folder path for creating sub folder
string[] locationSplit = path.Split(new char[] { '/' });
for (int i = 0; i < locationSplit.Length; i++)
{
//Create folder
if (locationSplit[i] != string.Empty)
stgFolder = await stgFolder.CreateFolderAsync(locationSplit[i], CreationCollisionOption.OpenIfExists);
}
return stgFolder;
}

Thus the files under the selected compressed file are extracted to a particular location.

References:
http://msdn.microsoft.com/en-us/library/windows/apps/br207928.aspx
http://msdn.microsoft.com/library/windows/apps/BR207847
http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.folderpicker.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/system.runtime.interopservices.windowsruntime.windowsruntimebufferextensions%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/hh454050%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/system.io.compression.ziparchive%28v=vs.110%29.aspx