Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

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.

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

How to compress 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 compress a set of files and save the compressed file to a particular location.

Steps to compress a set of files:

Step 1: Select the folder containing the files which you want to compress.

//Select Folder to Compress
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 compress StorageFolder storageFolderForCompression = await saveFolder.PickSingleFolderAsync();

Step 2: Retrieve the files present under the selected folder

// Retrieve the files to compress
IReadOnlyList<StorageFile> filesToCompress = await GetStorageFiles(storageFolderForCompression as IStorageItem);

Helper methods:

async Task<List<StorageFile>> GetStorageFiles(IStorageItem storageItem)
{

List<StorageFile> storageFileList = new List<StorageFile>();
// Gets the items under the selected folder (Storage Item)
IReadOnlyList<IStorageItem> items = await (storageItem as StorageFolder).GetItemsAsync();
foreach(IStorageItem item in items)
{
switch(item.Attributes)
{
case FileAttributes.Directory:
// If the item is a directory under the selected folder, then retrieve the files under the directory by calling the same function recursively
List<StorageFile> temp = await GetStorageFiles(item);
// Copy the files under the directory to the storage file list
Copy(temp, storageFileList);
break;
default:
// If the item is a file, Add the item to the storage file list
storageFileList.Add(item as StorageFile);
break;
}
}
// Return storage file list for compression
return storageFileList;
}

private void Copy(List<StorageFile> source, List<StorageFile> destination)
{
// For each file item present under the directory copy it to the destination storage file list
foreach (StorageFile file in source)
{
destination.Add(file);
}
}

Note: Alternatively you can use FileOpenPicker control’s PickMultipleFilesAsync() method to allow the users to select multiple files instead selecting the folder. In this way you can skip both Step 1 and Step 2.

// File open picker
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
fileOpenPicker.FileTypeFilter.Add("*");
// Allows user to select multiple files which returns storage file list
IReadOnlyList<StorageFile> filesToCompress = await fileOpenPicker.PickMultipleFilesAsync();


Step 3: Create ZipArchive object using a memory stream and then for each file to be compressed Add a ZipArchiveEntry with the file name and copy the file contents to the ZipArchiveEntry stream.

Once the files are added to the zip archive, close the zip archive object and copy the contents of memory stream to the storage file which is saved to a particular location.

// Retrieve files to compress
IReadOnlyList<StorageFile> filesToCompress = await GetStorageFiles(storageFolderForCompression as IStorageItem);

// Created new file to store compressed files
//This will create a file under the selected folder in the name “Compressed.zip”
StorageFile zipFile = await storageFolderForCompression.CreateFileAsync("Compressed.zip");

// Create stream to compress files in memory (ZipArchive can't stream to an IRandomAccessStream, see
// http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/62541424-ba7d-43d3-9585-1fe53dc7d9e2
// for details on this issue)
using (MemoryStream zipMemoryStream = new MemoryStream())
{
// Create zip archive
using (ZipArchive zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create))
{
// For each file to compress...
foreach (StorageFile fileToCompress in filesToCompress)
{
//Read the contents of the file
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(fileToCompress));

// Create a zip archive entry
ZipArchiveEntry entry = zipArchive.CreateEntry(fileToCompress.Name);

// And write the contents to it
using (Stream entryStream = entry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
}
}

using (IRandomAccessStream zipStream = await zipFile.OpenAsync(FileAccessMode.ReadWrite))
{
// Write compressed data from memory to file
using (Stream outstream = zipStream.AsStreamForWrite())
{
byte[] buffer = zipMemoryStream.ToArray();
outstream.Write(buffer, 0, buffer.Length);
outstream.Flush();
}
}
}

Thus the files under the selected folder are compressed 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