Showing posts with label WinRT. Show all posts
Showing posts with label WinRT. Show all posts

Friday, August 2, 2013

Modal Popup & Flyout Popup in WinRT




First I created a child window base class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace PopupSample.Bases
{
    public class ChildWindowBase : UserControl, IDisposable
    {
        public ChildWindowBase() : base()
        {

        }

        public Page Opener { get; set; }
        public bool? DialogResult { get; set; }

        public string ChildWindowName
        {
            get { return this.GetType().Name; }
        }

        private static Popup _popup;
        private static Popup _RootPopup;

        [DefaultValue(FlyoutType.Center)]
        public FlyoutType Flyout { get; set; }

        public void Show()
        {
            switch (Flyout)
            {
                //Modal Popup
                case FlyoutType.Center:
                    CenterShow();
                    break;
                case FlyoutType.Left:
                    LeftShow();
                    break;
                case FlyoutType.Top:
                    TopShow();
                    break;
                case FlyoutType.Right:
                    RightShow();
                    break;
                case FlyoutType.Bottom:
                    BottomShow();
                    break;
                default:
                    break;
            }
        }

        private void CenterShow()
        {
            var bounds = Window.Current.Bounds;
            var width = Double.IsNaN(this.Width) ? 900 : this.Width;
            var height = Double.IsNaN(this.Height) ? 550 : this.Height;

            Grid RootPanel = new Grid
            {
                Name = "RootPanel",
                Opacity = 0.60,
                Background = new SolidColorBrush(Colors.White),
                Width = bounds.Width,
                Height = bounds.Height,
                VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Stretch,
                HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Stretch
            };

            _RootPopup = new Popup
            {
                Child = RootPanel
            };

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new AddDeleteThemeTransition(),
                                                        new PopupThemeTransition {FromVerticalOffset = bounds.Height}
                                                    },
                HorizontalOffset = (bounds.Width / 2) - (width / 2),
                VerticalOffset = (bounds.Height / 2) - (height / 2),
                Child = this,
            };

            _RootPopup.IsOpen = true;
            (Window.Current.Content as Frame).IsEnabled = false;
            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void LeftShow()
        {
            var bounds = Window.Current.Bounds;

            var width = Double.IsNaN(this.Width) ? 480 : this.Width;
            (this.Content as FrameworkElement).Height = bounds.Height;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromHorizontalOffset = 0},
                                                    },
                HorizontalOffset = 0,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void TopShow()
        {
            var bounds = Window.Current.Bounds;

            var height = Double.IsNaN(this.Height) ? 200 : this.Height;
            (this.Content as FrameworkElement).Width = bounds.Width;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromVerticalOffset = 0}
                                                    },
                VerticalOffset = 0,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void RightShow()
        {
            var bounds = Window.Current.Bounds;

            var width = Double.IsNaN(this.Width) ? 480 : this.Width;
            (this.Content as FrameworkElement).Height = bounds.Height;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromHorizontalOffset = bounds.Width}
                                                    },
                HorizontalOffset = bounds.Width - width,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void BottomShow()
        {
            var bounds = Window.Current.Bounds;

            var height = Double.IsNaN(this.Height) ? 200 : this.Height;
            (this.Content as FrameworkElement).Width = bounds.Width;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromVerticalOffset = bounds.Height}
                                                    },
                VerticalOffset = bounds.Height - height,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        public void Close()
        {
            _popup.IsOpen = false;
            (Window.Current.Content as Frame).IsEnabled = true;

            if (Flyout == FlyoutType.Center)
            {
                _RootPopup.IsOpen = false;
            }

            OnClosed(EventArgs.Empty);
        }

        public void OnInitialized()
        {

        }

        public event EventHandler Closed;
        public event EventHandler ShowCompleted;

        protected virtual void OnClosed(EventArgs e)
        {
            if (Closed != null)
                Closed(this, e);
        }

        protected virtual void OnShowCompleted(EventArgs e)
        {
            if (ShowCompleted != null)
                ShowCompleted(this, e);
        }

        #region IDisposable Members

        public virtual async void Dispose()
        {
            try
            {
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    this.Close();
                    this.Content = null;
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        #endregion
    }

    public enum FlyoutType
    {
        Center,
        Left,
        Top,
        Right,
        Bottom
    }
}
 

For selecting popup type (modal or flyout) I use an enum (FlyoutType) if FlyoutType = Center then the popup is modal else the popup is flyout.


Modal Sample:
XAML:

<bases:ChildWindowBase
    x:Class="PopupSample.ChildWindows.ModalSample"
    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"
    xmlns:bases="using:PopupSample.Bases"
    mc:Ignorable="d"
    d:DesignHeight="216"
    d:DesignWidth="384"
    Height="216"
    Width="384">

    <Border BorderThickness="2" BorderBrush="#FF8F8B8B" Background="DarkOrchid" CornerRadius="20">
        <Grid Margin="10">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="50"/>
                </Grid.RowDefinitions>

                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
                    <Button Width="100" Height="35" Content="Save" Click="btnSave_Click"/>
                    <Button Width="100" Height="35" Content="Cancel" Click="btnCancel_Click"/>
                </StackPanel>
            </Grid>
        </Grid>
    </Border>
</bases:ChildWindowBase>


CS:

using PopupSample.Bases;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace PopupSample.ChildWindows
{
    public sealed partial class ModalSample : ChildWindowBase
    {
        public ModalSample()
        {
            this.InitializeComponent();

            this.Loaded += ModalSample_Loaded;
        }

        private void ModalSample_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Close();
        }
    }
}

DialogResualt is for returning value into opener window.


Open a modal popup:


ModalSample modal;

private void Modal_Click(object sender, RoutedEventArgs e)
{
    modal = new ModalSample();
    modal.ShowCompleted += modal_ShowCompleted;
    modal.Closed += modal_Closed;

    modal.Show();
}

void modal_ShowCompleted(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("modal_ShowCompleted - {0}", DateTime.Now));
}

void modal_Closed(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("modal_Closed - {0} - Resualt: {1}", DateTime.Now, modal.DialogResult));
}


ShowCompleted Event fire when popup opened successfully.
Closed Event fire when popup closed successfully.



Flyout Sample:

XAML:


<bases:ChildWindowBase
    x:Class="PopupSample.ChildWindows.FlyoutSample"
    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"
    xmlns:bases="using:PopupSample.Bases"
    mc:Ignorable="d"
    d:DesignHeight="500"
    d:DesignWidth="384"
    MinWidth="384"
    MinHeight="500"
    Width="384">

    <Border BorderThickness="2" BorderBrush="#FF8F8B8B" Background="#FFDCD6D6">
        
    </Border>
</bases:ChildWindowBase>


CS:

using PopupSample.Bases;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace PopupSample.ChildWindows
{
    public sealed partial class FlyoutSample : ChildWindowBase
    {
        public FlyoutSample()
        {
            this.InitializeComponent();

            this.Loaded += FlayoutSample_Loaded;
        }

        private void FlayoutSample_Loaded(object sender, RoutedEventArgs e)
        {
            
        }
    }
}


Open a flyout popup:

FlyoutSample flyout;
        
private void Flyout_Click(object sender, RoutedEventArgs e)
{
    flyout = new FlyoutSample { Flyout = Bases.FlyoutType.Right };
    flyout.ShowCompleted += flyout_ShowCompleted;

    flyout.Show();
}

void flyout_ShowCompleted(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("flyout_ShowCompleted - {0}", DateTime.Now));
}




Download full sample from here

Thursday, August 1, 2013

WinRT IsoStorage Sample




First we should create a Storage Helper:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Windows.Storage;
using System.IO;
using Windows.Storage.Streams;
using System.Xml.Linq;
using IsoStorageSample.Helpers;

namespace IsoStorageSample.Helpers
{
    public enum StorageType { Local, Temporary, Roaming }

    public class IsoStorage<T>
    {
        protected ApplicationData appData = Windows.Storage.ApplicationData.Current;
        protected StorageFolder storageFolder;
        protected StorageType storageType;

        public StorageType StorageType
        {
            get { return storageType; }
            set
            {
                storageType = value;
                // set the storage folder
                switch (storageType)
                {
                    case StorageType.Local:
                        storageFolder = appData.LocalFolder;
                        break;
                    case StorageType.Temporary:
                        storageFolder = appData.TemporaryFolder;
                        break;
                    case StorageType.Roaming:
                        storageFolder = appData.RoamingFolder;
                        break;
                    default:
                        throw new Exception(String.Format("Unknown StorageType: {0}", storageType));
                }
            }
        }

        public IsoStorage() : this(StorageType.Local) { }
        public IsoStorage(StorageType type)
        {
            StorageType = type;
        }

        public async Task CopyAsync(StorageFolder folder, string fileName)
        {
            try
            {
                StorageFile storageFile = await folder.GetFileAsync(fileName);

                if (await GetFileIfExistsAsync(storageFile.Name) == null)
                {
                    await storageFile.CopyAsync(storageFolder);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public async Task<XDocument> LoadXml(string fileName)
        {
            try
            {
                StorageFile xmlFile = await GetFileIfExistsAsync(fileName);

                if (xmlFile != null)
                {
                    return XDocument.Load(xmlFile.Path);
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Delete a file asynchronously
        /// </summary>
        /// <param name="fileName"></param>
        public async void DeleteAsync(string fileName)
        {
            try
            {
                fileName = AppendExt(fileName);
                var file = await GetFileIfExistsAsync(fileName);
                if (file != null)
                    await file.DeleteAsync();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// At the moment the only way to check if a file exists to catch an exception... :/
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        protected async Task<StorageFile> GetFileIfExistsAsync(string fileName)
        {
            try
            {
                return await storageFolder.GetFileAsync(fileName);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Appends the file extension to the given filename
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        protected string AppendExt(string fileName)
        {
            if (fileName.Contains(".txt"))
                return fileName;
            else
                return string.Format("{0}.txt", fileName);
        }

        /// <summary>
        /// Saves a serialized object to storage asynchronously
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="obj"></param>
        public async void SaveAsync(string fileName, T data, string key = null)
        {
            try
            {
                if (data == null)
                    return;

                fileName = AppendExt(fileName);
                var file = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

                string serializedObject = JSONSerializerHelper.Serialize(data);
                string encryptedObject = serializedObject;

                if (key != null)
                {
                    encryptedObject = Hashing.Encrypt(serializedObject, key);
                }

                await FileIO.WriteTextAsync(file, encryptedObject);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Load a given filename asynchronously
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<T> LoadAsync(string fileName, string key = null)
        {
            try
            {
                fileName = AppendExt(fileName);
                StorageFile file = null;
                file = await storageFolder.GetFileAsync(fileName);

                string serializedObject = await FileIO.ReadTextAsync(file);
                string decryptedObject = serializedObject;

                if (key != null)
                {
                    decryptedObject = Hashing.Decrypt(serializedObject, key);
                }

                return (T)JSONSerializerHelper.DeSerialize(typeof(T), decryptedObject);
            }
            catch (FileNotFoundException)
            {
                //file not existing is perfectly valid so simply return the default
                return default(T);
                //throw;
            }
            catch (Exception)
            {
                //Unable to load contents of file
                throw;
            }
        }
    }
}


For serializing data, I use Json.NET and create a helper for that:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IsoStorageSample.Helpers
{
    public static class JSONSerializerHelper
    {
        public static string Serialize(object obj)
        {
            string json = JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, TypeNameHandling = TypeNameHandling.Objects });
            return json;
        }

        public static object DeSerialize(Type type, string str)
        {
            object json = JsonConvert.DeserializeObject(str, type, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, TypeNameHandling = TypeNameHandling.Objects });
            return json;
        }
    }
}


And for hashing data I use Windows.Security.Cryptography

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

namespace IsoStorageSample.Helpers
{
    public class Hashing
    {
        public static string Encrypt(string dataToEncrypt, string myKey)
        {
            //make sure we have data to work with
            if (string.IsNullOrEmpty(dataToEncrypt))
                throw new ArgumentException("input cannot be empty");

            if (string.IsNullOrEmpty(myKey))
                throw new ArgumentException("password cannot be empty");

            // get IV, key and encrypt
            var iv = CreateInitializationVector(myKey);
            var key = CreateKey(myKey);

            var encryptedBuffer = CryptographicEngine.Encrypt(key, CryptographicBuffer.ConvertStringToBinary(dataToEncrypt, BinaryStringEncoding.Utf8), iv);
            return CryptographicBuffer.EncodeToBase64String(encryptedBuffer);
        }

        public static string Decrypt(string encryptedString, string myKey)
        {
            try
            {
                //make sure we have data to work with
                if (string.IsNullOrEmpty(encryptedString))
                    throw new ArgumentException("input cannot be empty");

                if (string.IsNullOrEmpty(myKey))
                    throw new ArgumentException("password cannot be empty");

                // get IV, key and decrypt
                var iv = CreateInitializationVector(myKey);
                var key = CreateKey(myKey);

                var decryptedBuffer = CryptographicEngine.Decrypt(key, CryptographicBuffer.DecodeFromBase64String(encryptedString), iv);

                return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedBuffer);
            }
            catch (Exception)
            {
                throw;
            }
        }

        private static IBuffer CreateInitializationVector(string password)
        {
            var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
            var newPassword = password;

            // make sure we satify minimum length requirements
            while (newPassword.Length < provider.BlockLength)
            {
                newPassword = newPassword + password;
            }

            //create vecotr
            var iv = CryptographicBuffer.CreateFromByteArray(UTF8Encoding.UTF8.GetBytes(newPassword));
            return iv;
        }

        private static CryptographicKey CreateKey(string password)
        {
            var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
            var newPassword = password;

            // make sure we satify minimum length requirements
            while (newPassword.Length < provider.BlockLength)
            {
                newPassword = newPassword + password;
            }

            var buffer = CryptographicBuffer.ConvertStringToBinary(newPassword, BinaryStringEncoding.Utf8);
            buffer.Length = provider.BlockLength;

            var key = provider.CreateSymmetricKey(buffer);
            return key;
        }
    }
}


Now we can use that like this:

private void SaveData()
{
    Dictionary<int, Person> persons = new Dictionary<int, Person>();

    persons.Add(1, new Person { ID = 1, Name = "Michael" });
    persons.Add(2, new Person { ID = 2, Name = "John" });
    persons.Add(3, new Person { ID = 3, Name = "Rose" });

    IsoStorage<Dictionary<int, Person>> storage = new IsoStorage<Dictionary<int, Person>>();

    //if key is not equal null => data will be encrypt
    storage.SaveAsync("TestStorage", persons, null);
}

private async void LoadData()
{
    IsoStorage<Dictionary<int, Person>> storage = new IsoStorage<Dictionary<int, Person>>();
    Dictionary<int, Person> persons = await storage.LoadAsync("TestStorage", null);
}

public class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
}

Download full sample from here