C# Get all days in a week by given date

Wrote a little DateTime extension where you can get the range of days in a week by a given date.

So for example, today is 02/26/2013, Tuesday and you want to get the range of dates in the current week which is 02/25/2013 Sunday to 03/02/2013 Saturday. I made an extension to achieve that.

Here's the DateTime Extension code

public static class Extension_DateTime
{
	public static List<DateTime> GetDaysInWeek(this DateTime Date, DayOfWeek firstdayofweek)
	{
		List<DateTime> d = new List<DateTime>();

		int days = Date.DayOfWeek - firstdayofweek;
		DateTime dt = Date.AddDays(-days);
		d.Add(dt);
		d.AddRange(new DateTime[] { dt.AddDays(1), dt.AddDays(2), dt.AddDays(3), dt.AddDays(4), dt.AddDays(5), dt.AddDays(6) });

		return d;
	}
}

Here's how to use it

static void Main(string[] args)
{
	int curr_day = DateTime.Today.Day;

	foreach (DateTime d in DateTime.Now.GetDaysInWeek(CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek))
	{
		Console.Write(d.Day + " ");
	}

	Console.ReadLine();
}
Click here to expand the blog post

C# Windows 8 App - Tile Builder

With the recent projects I had in Windows 8 App, I had to incorporate tile updates locally, taking the newest projects for the day, and show them on the tile. So I made it, got some few UI updates, as well as how the tile would look like. I always a fan of "reusable codes" so whenever I need some special functionality on other projects, I could always get this "reusable code" and just use it right away, make some updates and add some features. With this ever changing requirements of how do tile would look like, I said to my self, "hey, why not just write a small wrapper that can help me update the tile template easier", so I made TileBuilder.

TileBuilder helps you create your animated tile, have multiple tile templates, and update your tile easily. Just add your images and texts on the collection and apply any tile template you want.

Here's the 25:07 minutes video showing how to use TileBuilder

TileBuilder code

/*
 * TileBuilder v1.0
 * Jayson Ragasa
 * http://wall.jaysonragasa.net
 */

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;

namespace Capploud
{
    public class TileBuilder : INotifyPropertyChanged
    {
        #region // Vars /

        TileUpdater tileupdate = TileUpdateManager.CreateTileUpdaterForApplication();

        #endregion

        #region // Properties /

        bool _cycle = true;
        public bool Cycle
        {
            get { return this._cycle; }
            set
            {
                if (this._cycle != value)
                {
                    this._cycle = value;
                    this.tileupdate.EnableNotificationQueue(value);
                }
            }
        }

        double _expire = 0;
        public double Expire
        {
            get { return this._expire; }
            set
            {
                if (this._expire != value)
                {
                    this._expire = value;
                }
            }
        }

        //TileTemplateType _widetiletemplate = TileTemplateType.TileWideImageAndText01;
        //public TileTemplateType WideTileTemplate
        //{
        //    get { return this._widetiletemplate; }
        //    set
        //    {
        //        if (this._widetiletemplate != value)
        //        {
        //            this._widetiletemplate = value;
        //            OnPropertyChanged("WideTileTemplate");
        //        }
        //    }
        //}

        //TileTemplateType _squaretiletemplate = TileTemplateType.TileWideImageAndText01;
        //public TileTemplateType SquareTileTemplate
        //{
        //    get { return this._squaretiletemplate; }
        //    set
        //    {
        //        if (this._squaretiletemplate != value)
        //        {
        //            this._squaretiletemplate = value;
        //            OnPropertyChanged("SquareTileTemplate");
        //        }
        //    }
        //}

        Model_TileDetails _tiledet = new Model_TileDetails();
        public Model_TileDetails TileDetailColelction
        {
            get { return this._tiledet; }
            set
            {
                this._tiledet = value;
                OnPropertyChanged("TileDetailColelction");
            }
        }

        List<XmlElement> _xmlnodecoll = new List<XmlElement>();
        List<XmlElement> XmlNodeCollection
        {
            get { return this._xmlnodecoll; }
            set
            {
                this._xmlnodecoll = value;
                OnPropertyChanged("TileDetailColelction");
            }
        }

        #endregion

        #region // Constructor /

        public TileBuilder()
        {
            this.tileupdate.EnableNotificationQueue(true);

            this.tileupdate.Clear();
        }

        #endregion

        #region // Support Singleton /
        static readonly TileBuilder _i = new TileBuilder();
        public static TileBuilder I { get { return _i; } }
        #endregion

        #region // Methods /

        public void ClearTile()
        {
            this.tileupdate.Clear();
        }

        public void ClearCollection()
        {
            this.TileDetailColelction.ImageFiles.Clear();
            this.TileDetailColelction.Texts.Clear();
        }

        /// <summary>
        /// obsolete
        /// </summary>
        public void BuildTile()
        {
            string sxml = "<title><visual lang=\"en-US\">";

            foreach (XmlElement node in XmlNodeCollection)
            {
                sxml += node.GetXml();
            }

            sxml += "</visual></title>";

            XmlDocument xml = new XmlDocument();
            xml.LoadXml(sxml);
            var tileNotification = new TileNotification(xml);
            if (Expire != 0)
            {
                tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddSeconds(Expire);
            }
            this.tileupdate.Update(tileNotification);
            
            ShowXML(xml);
        }

        public void BuildTile(TileTemplateType TileTemplate)
        {
            AddTileTemplate(TileTemplate);
        }

        public void AddTileTemplate(TileTemplateType TileTemplate)
        {
            XmlDocument tileXml = TileUpdateManager.GetTemplateContent(TileTemplate);

            // get "image" and "text" element in <binding> node
            XmlNodeList tileImageNode = tileXml.GetElementsByTagName("image");
            XmlNodeList tileTextNode = tileXml.GetElementsByTagName("text");

            // make sure there are image nodes
            if (tileImageNode.Count > 0)
            {
                // add blank image items in our collection
                if (tileImageNode.Count > TileDetailColelction.ImageFiles.Count)
                {
                    int diff = tileImageNode.Count - TileDetailColelction.ImageFiles.Count;
                    // add blank items
                    for (int i = 0; i < diff; i++)
                    {
                        this.TileDetailColelction.ImageFiles.Add(new Model_ImageTileDetails()
                        {
                            ImageFile = string.Empty,
                            Alt = string.Empty
                        });
                    }
                }

                // finally set all necessary attribute values
                for (int i = 0; i < tileImageNode.Count; i++)
                {
                    Model_ImageTileDetails mid = TileDetailColelction.ImageFiles[i];

                    ((XmlElement)tileImageNode[i]).SetAttribute("src", mid.ImageFile);
                    ((XmlElement)tileImageNode[i]).SetAttribute("alt", mid.Alt);
                }
            }

            // make sure there are text nodes
            if (tileTextNode.Count > 0)
            {
                // add blank image items
                if (tileTextNode.Count > TileDetailColelction.Texts.Count)
                {
                    int diff = tileTextNode.Count - TileDetailColelction.Texts.Count;
                    // add blank items
                    for (int i = 0; i < diff; i++)
                    {
                        this.TileDetailColelction.Texts.Add(string.Empty);
                    }
                }

                // finally set all necessary attribute values
                for (int i = 0; i < tileTextNode.Count; i++)
                {
                    ((XmlElement)tileTextNode[i]).InnerText = TileDetailColelction.Texts[i];
                }
            }

            //IXmlNode node = tileXml.ImportNode(tileXml.GetElementsByTagName("binding").Item(0), true);
            IXmlNode node = tileXml.SelectSingleNode("//binding");

            XmlNodeCollection.Add((XmlElement)node);
            //return node;

            var tileNotification = new TileNotification(tileXml);
            if (Expire != 0)
            {
                tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddSeconds(Expire);
            }
            this.tileupdate.Update(tileNotification);
        }

        public void ShowXML(XmlDocument xmldoc)
        {
            Debug.WriteLine(xmldoc.GetXml());
        }

        #endregion

        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            var eventHandler = this.PropertyChanged;
            if (eventHandler != null)
            {
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region // Class Models /

        public class Model_ImageTileDetails : INotifyPropertyChanged
        {
            string _imagefile = string.Empty;
            public string ImageFile
            {
                get { return this._imagefile; }
                set
                {
                    if (this._imagefile != value)
                    {
                        this._imagefile = value;
                        OnPropertyChanged("ImageFile");
                    }
                }
            }

            string _alt = string.Empty;
            public string Alt
            {
                get { return this._alt; }
                set
                {
                    if (this._alt != value)
                    {
                        this._alt = value;
                        OnPropertyChanged("Alt");
                    }
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                var eventHandler = this.PropertyChanged;
                if (eventHandler != null)
                {
                    eventHandler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        public class Model_TileDetails : INotifyPropertyChanged
        {
            ObservableCollection<Model_ImageTileDetails> _imagefile = new ObservableCollection<Model_ImageTileDetails>();
            public ObservableCollection<Model_ImageTileDetails> ImageFiles
            {
                get { return this._imagefile; }
                set
                {
                    this._imagefile = value;
                    OnPropertyChanged("ImageFiles");
                }
            }

            ObservableCollection<string> _text = new ObservableCollection<string>();
            public ObservableCollection<string> Texts
            {
                get { return this._text; }
                set
                {
                    this._text = value;
                    OnPropertyChanged("Texts");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                var eventHandler = this.PropertyChanged;
                if (eventHandler != null)
                {
                    eventHandler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        #endregion
    }
}

Usage

There are 2 basic properties that you need to consider before creating your new tile.

TileBuilder.Cycle (bool)

  • true - this will tell TileUpdater to have its notification queue enabled.
  • false - this will tell TileUpdater to have its notification queue disabled.

TileBuilder.Expire (double)

  • 0 - tile does not expire
  • >0 - tile does expire

After you have set those two properties. Make sure to call ClearTile() method to make sure the old tile template is cleared.

To start creating your tile, you need to use TileDetailsCollection. This property contains two collection object.

  • ImageFiles(Model_ImageTileDetails)
    • And in this Model_ImageTileDetails object, it has two properties that is needed for your image tiles
      • ImageFile
      • Alt
  • Texts(string)

Usage

TileBuilder tiler = new TileBuilder()
{
	Cycle = true,
	Expire = 0
};
tiler.ClearTile();

TileSquareBlock template

tiler.TileDetailColelction.Texts.Add(DateTime.Today.Day.ToString());
tiler.TileDetailColelction.Texts.Add(DateTime.Today.ToString("MMMM yyyy"));
tiler.BuildTile(TileTemplateType.TileSquareBlock);

TileWidePeekImageCollection05 template

tiler.TileDetailColelction.ImageFiles.Add(new TileBuilder.Model_ImageTileDetails()
{
	ImageFile = "ms-appx:///images/widetile1.jpg",
	Alt = "Wide Tile One"
});
tiler.TileDetailColelction.ImageFiles.Add(new TileBuilder.Model_ImageTileDetails()
{
	ImageFile = "ms-appx:///images/widetile2.jpg",
	Alt = "Wide Tile Two"
});
tiler.TileDetailColelction.ImageFiles.Add(new TileBuilder.Model_ImageTileDetails()
{
	ImageFile = "ms-appx:///images/widetile3.jpg",
	Alt = "Wide Tile Three"
});
tiler.TileDetailColelction.ImageFiles.Add(new TileBuilder.Model_ImageTileDetails()
{
	ImageFile = "ms-appx:///images/widetile4.jpg",
	Alt = "Wide Tile Four"
});
tiler.TileDetailColelction.ImageFiles.Add(new TileBuilder.Model_ImageTileDetails()
{
	ImageFile = "ms-appx:///images/widetile5.jpg",
	Alt = "Wide Tile Five"
});

tiler.TileDetailColelction.Texts.Add("Big Header Here");
tiler.TileDetailColelction.Texts.Add("Line 2");

tiler.BuildTile(TileTemplateType.TileWidePeekImageCollection05);

 

Changing the tile layout only requires you to change the TileTemplateType value in BuildTile

You can download the source in my box drive

TileTest.zip (69.6kb) 

Click here to expand the blog post

C# Enumerate Special Folders

This is just a simple code to enumerate all the special folders.

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (Environment.SpecialFolder sf in Enum.GetValues(typeof(Environment.SpecialFolder)))
            {
                Debug.WriteLine(string.Format("{0} - {1}", sf, Environment.GetFolderPath(sf)));
            }
        }
    }
}

make sure to check the Output pane.

Here's the preview of my Special Folders in Windows 7

Desktop = C:\Users\jaysonragasa\Desktop
Programs = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
MyDocuments = C:\Users\jaysonragasa\Documents
MyDocuments = C:\Users\jaysonragasa\Documents
Favorites = C:\Users\jaysonragasa\Favorites
Startup = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
Recent = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Recent
SendTo = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\SendTo
StartMenu = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Start Menu
MyMusic = C:\Users\jaysonragasa\Music
MyVideos = C:\Users\jaysonragasa\Videos
DesktopDirectory = C:\Users\jaysonragasa\Desktop
MyComputer = 
NetworkShortcuts = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Network Shortcuts
Fonts = C:\Windows\Fonts
Templates = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Templates
CommonStartMenu = C:\ProgramData\Microsoft\Windows\Start Menu
CommonPrograms = C:\ProgramData\Microsoft\Windows\Start Menu\Programs
CommonStartup = C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
CommonDesktopDirectory = C:\Users\Public\Desktop
ApplicationData = C:\Users\jaysonragasa\AppData\Roaming
PrinterShortcuts = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Printer Shortcuts
LocalApplicationData = C:\Users\jaysonragasa\AppData\Local
InternetCache = C:\Users\jaysonragasa\AppData\Local\Microsoft\Windows\Temporary Internet Files
Cookies = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Cookies
History = C:\Users\jaysonragasa\AppData\Local\Microsoft\Windows\History
CommonApplicationData = C:\ProgramData
Windows = C:\Windows
System = C:\Windows\system32
ProgramFiles = C:\Program Files
MyPictures = C:\Users\jaysonragasa\Pictures
UserProfile = C:\Users\jaysonragasa
SystemX86 = C:\Windows\system32
ProgramFilesX86 = C:\Program Files
CommonProgramFiles = C:\Program Files\Common Files
CommonProgramFilesX86 = C:\Program Files\Common Files
CommonTemplates = C:\ProgramData\Microsoft\Windows\Templates
CommonDocuments = C:\Users\Public\Documents
CommonAdminTools = C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools
AdminTools = C:\Users\jaysonragasa\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools
CommonMusic = C:\Users\Public\Music
CommonPictures = C:\Users\Public\Pictures
CommonVideos = C:\Users\Public\Videos
Resources = C:\Windows\resources
LocalizedResources = 
CommonOemLinks = 
CDBurning = C:\Users\jaysonragasa\AppData\Local\Microsoft\Windows\Burn\Burn
Click here to expand the blog post

Windows Phone - Close application like Windows 8

This is just a little experiment in Windows Phone where I can drag the application from top to bottom to close.. Just like Windows 8 App.

Cool right?

I just took my WPF code and implemented it in Windows Phone to see what it looks like but I think it's cool to see something like that. 

Here's a video preview of the app

You can download the code and play with it. You can also use this in your WPF applications since the code is written in MVVM pattern. Just make sure to add WPF in your Conditional Compilation Symbols.

So how to use?

Let's check out the XAML first

<Grid x:Name="LayoutRoot" Background="Transparent">
	<!-- we need canvas so we can use the Top and Left property instead of dealing with Margins -->
	<Canvas>
		<Grid x:Name="MainContent" Canvas.Top="0" Canvas.Left="0" Width="480" Height="760" Background="#FF137900">
			<Grid.RowDefinitions>
				<RowDefinition Height="Auto"/>
				<RowDefinition Height="*"/>
			</Grid.RowDefinitions>
	
			<!--TitlePanel contains the name of the application and page title-->
			<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
				<TextBlock x:Name="ApplicationTitle" Text="Start dragging here from top to bottom" Style="{StaticResource PhoneTextNormalStyle}"/>
				<TextBlock x:Name="PageTitle" Text="ala Windows 8" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
			</StackPanel>

			<!--ContentPanel - place additional content here-->
			<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
		</Grid>

		<!-- our drag bar which is just sitting on top -->
		<Grid x:Name="DragBar" Height="45" Canvas.Top="0" Canvas.Left="0" Background="Transparent" Cursor="Hand" />
	</Canvas>
</Grid>

If you notice, I used Canvas element, because using it is much easier for dealing with child element locations just by using Top and Left properties. It's important that the DragBar grid has to be the last child so it will always stay at the top of other child elements in the Canvas.

Since the code is fairly written in MVVM, you can just it by implementing the iDragComponents interface and instantiating ViewModel_DragComponents class

public partial class MainPage : PhoneApplicationPage, iDragComponents
{
	ViewModel_DragComponents dragcomp;

	// Constructor
	public MainPage()
	{
		InitializeComponent();
		InitializeObjects();
	}

	void InitializeObjects()
	{
		this.dragcomp = new ViewModel_DragComponents(this);
		this.dragcomp.HasToClose += new HasToCloseHandler(dragcomp_HasToClose);
		this.dragcomp.Distance = 200;
	}
	
	// has reached the distance
	void dragcomp_HasToClose(object o, EventArgs e)
	{
		NavigationService.GoBack();
	}

	#region iDragComponents implementation
	public Grid ContentGrid
	{
		get { return this.MainContent; }
		set { this.MainContent = value; }
	}
	public Grid DragBarGrid
	{
		get { return this.DragBar; }
		set { this.DragBar = value; }
	}
	#endregion
}

and so just simple as that.

You can download the code in my Box 

 http://liit.co.nr/?0l6n8

Click here to expand the blog post

Javascript Custom Loader and Bootstrap

I was doing some test about implementing my custom bootstrap and kernel in Javascript and I wanted to load them asynchronously because inside those files, there are other stuff being loaded in runtime. I tried looking for some answers to load the scripts files asynchronously but some of them are using jQuery and some were not useful. I really like like to get away with jQuery with my loader so I made my own using queueing technique just like what I used to do in C# using Queue<T>

Here's the sample loader I made

function loadFile(url, callback) {
    var head;
    var element;

    if (url.indexOf('.css') != -1) {
	head = document.getElementsByTagName('head')[0];
        element = document.createElement('link');
        element.setAttribute('type', 'text/css');
        element.setAttribute('href', url);
        element.setAttribute('rel', 'stylesheet');
    }
    else if (url.indexOf('.js') != -1) {
	head = document.getElementsByTagName('body')[0];
        element = document.createElement('script');
        element.setAttribute('type', 'text/javascript');
        element.setAttribute('src', url);
    }
    /*else I'll try to add more here soon*/

    /*bind the event to the callback function*/
    {
		/*http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/*/
        if (script.readyState){  /*IE*/
			script.onreadystatechange = function(){
				if (script.readyState == "loaded" ||
						script.readyState == "complete"){
					script.onreadystatechange = null;
					callback();
				}
			};
		} else {  /*Others*/
			script.onload = function(){
				callback();
			};
		}
    }

    /*fire the loading*/
    {
        head.appendChild(element);
    }
}

{ // ENQUEUE / DEQUEUE files for asyncloading
    var d = new Date();

    // enqueue files
    var files = new Array(
        "css/jquery.metro.css",
        "css/common2.css",
        "scripts/appmanifest.js",
        "scripts/kernel.js",
        "scripts/bootstrap.js"
    );

    // dequeue
    var ready = false;
    var callback = function () {
        // file is now loaded
        // call LoadFiles() again for dequeueing 
        LoadFiles();
    };
    function LoadFiles() {
        if (files.length != 0) {
            // load file and add time so browser thinks
            // we are loading a different file
            // in other words, I hate caching them while debugging
            var file = files[0] + '?t=' + d.getTime();

            // load the file
            loadFile(file, callback);

            // dequeue the file
            files.splice(0, 1);
        }
        else {
            ready = true;
        }
    }
}

In my code above, if you notice, the function tries to insert CSS on HEAD and Javascript on BODY so why is that? It's been a practice that whenever we load a script file in our web pages, we have to put them inside the HEAD to make sure our script variables, functions, etc are defined first. I have no problem with that, if you want to use my loader script, and insert the script in head, then that's fine. Though I haven't answered the question why would I like to insert the script in the BODY? The reason is very simple, I want to make sure every element written manually or inserted dynamically exists first before doing any changes at the elements at runtime. 

you can also use Push() and Shift() in in Javascript like this one

{ // ENQUEUE / DEQUEUE files for asyncloading
    var d = new Date();

    // enqueue files
    var queue = [];
    queue.push("css/jquery.metro.css");
    queue.push("css/common2.css");
    queue.push("scripts/appmanifest.js");
    queue.push("scripts/kernel.js");
    queue.push("scripts/bootstrap.js");

    // dequeue
    var ready = false;
    var callback = function () {
        // file is now loaded
        // call LoadFiles() again for dequeueing 
        LoadFiles();
    };
    function LoadFiles() {
        if (queue.length != 0) {
            // load file and add time so browser thinks
            // we are loading a different file
            // in other words, I hate caching them while debugging
            var f = queue.shift(); // dequeue
            var file = f + '?t=' + d.getTime();

            // load the file
            loadFile(file, callback);
        }
        else {
            ready = true;
        }
    }
}

So why would I create a new bootstrap instead of using the one the was already made? The reason of that is because I really don't need everything on those offered bootstrap and loading the unnecessary libraries will just cause another webpage slowdown. My bootstrap is pretty simple, and it loads just the necessary libraries that I need which is defined in my appmanifest.js. So what on earth is appmenifest.js? App Manifest was just a small implementation of what was originally used in Siverlight, Windows Phone, and in Windows 8. Here, you can add the deployment details or any other information you need in your application.

Here's what my appmanifest.js looks like

/*
CAPABILITIES
------------
CAP_METROPIVOT
CAP_KNOCKOUT
*/
var Capabilities = [];
/*Capabilities.push("CAP_KNOCKOUT");*/
Capabilities.push("CAP_METROPIVOT");

var LayoutFiles = [];
LayoutFiles.push("scripts/View/Layout.js");

var MVVMFiles = [];
MVVMFiles.push("scripts/ViewModel/CommonViewModel.js");

and finally my bootstrap.js

/*
bootstrap.js
written by: Jayson Ragasa
*/

var d = new Date();

{ // async load required libraries    
    var required_libs = [];
    required_libs.push('scripts/Libraries/jquery-1.7.1.min.js');

    // load capabilities
    for (var i = 0; i < Capabilities.length; i++) {
        var cap = Capabilities[i];

        if (cap == "CAP_METROPIVOT") {
            required_libs.push('scripts/Libraries/Capabilities/jquery.metro.js');
            required_libs.push('scripts/Libraries/Capabilities/jquery.metro.extension.js');
        }
        else if (cap == "CAP_KNOCKOUT") {
            required_libs.push('scripts/Libraries/Capabilities/knockout.min.js');
        }
    }

    function callback_library_loaded(a) {
        LoadLibrary();
    }
    function LoadLibrary() {
        //alert(required_libs.length);

        if (required_libs.length != 0) {
            var lib = required_libs.shift();
            var f = lib + '?t=' + d.getTime() + '&ref=bootstrap';
            loadScript(f,
                function () {
                    callback_library_loaded(lib);
                }
            );
        }
        else {
            LibrariesLoaded();
        }
    }
    
    // call once;
    LoadLibrary();
}

function LibrariesLoaded() {
    required_libs.length = 0;

    { // add script files for layout
        // render layout
        for (var i = 0; i < LayoutFiles.length; i++) {
            var f = LayoutFiles[i];
            //loadScript(f, function () { });
            required_libs.push(f);
        }

        // load MVVM files
        for (var i = 0; i < MVVMFiles.length; i++) {
            var f = MVVMFiles[i];
            required_libs.push(f);
        }

        RenderLayout();
    }
}

 // load layout files and mvvm files
function callback_renderfiles_loaded(a) {
    RenderLayout();
}
function RenderLayout() {
    if (required_libs.length != 0) {
        var lib = required_libs.shift();
        var f = lib + '?t=' + d.getTime() + '&ref=bootstrap.renderfiles';
        loadScript(f,
            function () {
                callback_renderfiles_loaded(lib);
            }
        );
    }
    else {
            
    }
}

so simple isn't it? But I am hoping my custom bootstrap.js can go further as well as my kernel.js? Why on earth do I need kernel.js? I believe here in kernel.js, I can put all the necessary functions needed for my web application development. 

Here's where I implemented the whole thing C.app.loud development

Click here to expand the blog post

WPF Convert Visual Element to Encoded Image

public enum ImageEncodeType
{
	BMP, PNG, JPG
}
void ToEncodedImage(UIElement elem, ImageEncodeType encodeType, string filename, int JPGQuality = 80)
{
	RenderTargetBitmap rtb = new RenderTargetBitmap(
		(int)elem.DesiredSize.Width, (int)elem.DesiredSize.Height,
		96, 96, PixelFormats.Pbgra32);
	DrawingVisual draw = new DrawingVisual();
	using (DrawingContext dc = draw.RenderOpen())
	{
		VisualBrush vb = new VisualBrush(elem);
		dc.DrawRectangle(vb, null, new Rect(new Point(), new Size(elem.DesiredSize.Width, elem.DesiredSize.Height)));
	}
	rtb.Render(draw);

	using (Stream stream = File.Create(filename))
	{
		switch (encodeType)
		{
			case ImageEncodeType.BMP:
				BmpBitmapEncoder bmp = new BmpBitmapEncoder();
				bmp.Frames.Add(BitmapFrame.Create(rtb));
				bmp.Save(stream);
				break;
			case ImageEncodeType.JPG:
				JpegBitmapEncoder jpg = new JpegBitmapEncoder()
				{
					QualityLevel = JPGQuality
				};
				jpg.Frames.Add(BitmapFrame.Create(rtb));
				jpg.Save(stream);

				break;
			case ImageEncodeType.PNG:
				PngBitmapEncoder png = new PngBitmapEncoder();
				png.Frames.Add(BitmapFrame.Create(rtb));
				png.Save(stream);
				break;
		}
	}
}

RenderTargetBitmap renders a visual element in your WPF to image and you can later save it to an encoded image like BMP, JPG, or PNG as well as you can copy the image to clipboard.

Here's a simplest way of doing it

RenderTargetBitmap bitmap = new RenderTargetBitmap(visual.width, visual.height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(visual);
PngBitmapEncoder image = new PngBitmapEncoder();
image.Frames.Add(BitmapFrame.Create(bitmap));
using (Stream fs = File.Create(filePath))
{
	image.Save(fs);
}
Click here to expand the blog post

Windows Phone - ApplicationBar Controller

While doing some awesome side project in Windows Phone, I needed a way to have a better control on the Application Bar. I want the ApplicationBar Icon Buttons and Menu Items to be dynamically added, removed, hide/show, or enable/disable, as well as hooking an event for the specific Icon Button or Menu Items. 

But first, what is an ApplicationBar in Windows Phone and how to use it?

In Windows Desktop development, we have a control called Toolbar where you can add a Button, Drop Down Menu, Label, Textbox, or Progressbar and also you can add an Icon to your Buttons or Labels as well. You can have a button as many as you want, position the control around the Form, and you can also have a toolbar on all sides of your Form.

In Windows Phone, there is also a sort of Toolbar, but in this platform, we call it "Application Bar".

The Application Bar can have a set of circled white icons that stays at the bottom of the screen if it's in Portrait mode, or at the Right, if you turned your phone in Landscape. The Application Bar can only have two controls and that is, the Icon Button and a Menu Item. Just like what you see below (courtesy from Microsoft)

source: Microsoft

Unfortunately, Icon Buttons are limited, and you're pretty much stuck of having a maximum of 4 Icon Buttons. On the other hand, we have Menu Items, and you can add as pretty much as you can. But our main concern is the usability of the Icon Buttons because if you think of a big project, you pretty much has to have different ways of letting your end-users easily navigate around your application and one of them is using ApplicationBar, and having a maximum of 4 Icon Buttons, is not enough. 

So how do we solve the problem? 2 ways, either create a multiple Application Bars or have your Icon Buttons dynamically changing at Run Time. Which one do you choose?

Let's take a moment of showing an example of creating a multiple Application Bars. In Windows Phone DevCenter, they wrote a way to do this

How to: Create an Application Bar in Code for Windows Phone

http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394036(v=vs.92).aspx

As you can see from their example, they have two Application Bars defined in XAML.

Now the problem is, it may soon get very long and unmanageable by means of having a duplicate Menu Items (like what you see there), and what if I have 4 different Application Bars and I need a specific Icon Button to always appear on those Application Bars, so I have to Copy & Paste the XAML definition of that Icon Button to each Application Bar, and possibly, in overtime, I have to change the icon and text, so I have to go over to each Application Bars and change it again. Manipulating the Icon Buttons on those Application Bars in Run time will again introduce another headache.

So what if we could create an easy way of controlling our Icon Buttons in just one single Application Bar? 

So I wrote a class called ApplicationBarController to address the problem where we can have a much smoother control over to our Icon Buttons and Menu Items in one Applicaion Bar. What we can do in this class is we can easily Show the Icon Buttons or Menu Items we need for a specific task, as well as Hide them if not needed anymore like. In the animated image above, I demoed how this class works.

And so, here's the ApplicationBarController class for you.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Phone.Shell;

namespace CAPPLOUD.WP.Controllers
{
    public class ApplicationBarController
    {
        IApplicationBar _appbar;

        public ApplicationBarController(IApplicationBar appbar)
        {
            this._appbar = appbar;
        }

        Dictionary<string, IApplicationBarIconButton> Buttons { get; set; }
        Dictionary<string, IApplicationBarMenuItem> MenuItems { get; set; }

        /// <summary>
        /// Add new Menu Item to the collection.
        /// Must call ShowMenuItems or ShowMenuItem to show the menu
        /// </summary>
        /// <param name="Text">Name of the menu item</param>
        /// <param name="isEnabled"></param>
        /// <param name="e">Delegated event</param>
        public void AddNewMenuItem(string Text, bool isEnabled, EventHandler e)
        {
            if (MenuItems == null)
            {
                MenuItems = new Dictionary<string, IApplicationBarMenuItem>();
            }

            if (MenuItems.ContainsKey(Text)) { return; }

            ApplicationBarMenuItem menuitem = new ApplicationBarMenuItem()
            {
                Text = Text,
                IsEnabled = isEnabled
            };
            menuitem.Click += e;

            MenuItems.Add(Text, menuitem);
        }
        /// <summary>
        /// Add new Icon Button to the collection.
        /// Must call ShowButtons or Showbutton to show the icon button
        /// </summary>
        /// <param name="Text">Text of the icon button</param>
        /// <param name="IconUri">Relative image url</param>
        /// <param name="isEnabled"></param>
        /// <param name="e">Delegated event</param>
        public void AddNewButton(string Text, string IconUri, bool isEnabled, EventHandler e)
        {
            if (Buttons == null)
            {
                Buttons = new Dictionary<string, IApplicationBarIconButton>();
            }

            if (Buttons.ContainsKey(Text)) { return; }

            ApplicationBarIconButton btn = new ApplicationBarIconButton()
            {
                Text = Text,
                IconUri = new Uri(IconUri, UriKind.Relative),
                IsEnabled = isEnabled
            };
            btn.Click += e;
            
            Buttons.Add(Text, btn);
        }

        /// <summary>
        /// Replace and show selected buttons in the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void ShowButtons(params string[] ButtonText)
        {
            this._appbar.Buttons.Clear();

            foreach (string text in ButtonText)
            {
                if (!_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Add(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Append the icon button in the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void ShowButton(params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                if (!_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Add(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Remove selected buttonsin the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void RemoveButtons(params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                if (_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Remove(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Clear all Icon Buttons in the application bar
        /// </summary>
        public void RemoveButtons()
        {
            this._appbar.Buttons.Clear();
        }
        /// <summary>
        /// Enable or Disable selected buttons
        /// </summary>
        /// <param name="Enabled"></param>
        /// <param name="ButtonText">Icon Button texts to Enable or Disable</param>
        public void EnableButtons(bool Enabled, params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                Buttons[text].IsEnabled = Enabled;
            }
        }

        /// <summary>
        /// Replace and show selected menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void ShowMenuItems(params string[] MenuItemText)
        {
            this._appbar.MenuItems.Clear();

            foreach (string text in MenuItemText)
            {
                if (!_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Add(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Append the menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void ShowMenuItem(params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                if (!_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Add(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Remove selected menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void RemoveMenuItems(params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                if (_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Remove(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Clear all menu items in the application bar
        /// </summary>
        public void RemoveMenuItems()
        {
            _appbar.MenuItems.Clear();
        }
        /// <summary>
        /// Enable or Disable selected menu items
        /// </summary>
        /// <param name="Enabled"></param>
        /// <param name="MenuItemText">menu items texts to Enable or Disable</param>
        public void EnableMenuItems(bool Enabled, params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                MenuItems[text].IsEnabled = Enabled;
            }
        }

        /// <summary>
        /// Show or Hide application bar
        /// </summary>
        /// <param name="Show"></param>
        public void ShowAppBar(bool Show)
        {
            if (this._appbar.IsVisible != Show)
            {
                this._appbar.IsVisible = Show;
            }
        }
    }
}

This ApplicationBarController class can pretty much do what ever you want. You can:

  • Add or Remove an Icon Button or Menu Items
  • Show or Hide Icon Buttons or Menu Items
  • Enable or Disable an Icon Button or Menu Items.

Here's an easy way you can implement ApplicationBarController class.

First thing you have to do is to hook the ApplicationBar for the current page.

// Hook the ApplicationBar in the current page
ApplicationBarController appbar = new ApplicationBarController(this.ApplicationBar);

Next is to prepare your Icon Buttons and Menu Items that you are going to need in your project.

void InitializeApplicationBar
{
	// prepare all Icon Buttons and Menu Items
	this.appbar.AddNewButton("add", "/icons/appbar.add.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("save", "/icons/appbar.save.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("cancel", "/icons/appbar.close.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("delete", "/icons/appbar.delete.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("clear", "/icons/appbar.close.rest.png", true, ApplicationBarIconButton_Click);

	this.appbar.AddNewButton("ff", "/icons/appbar.transport.ff.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("play", "/icons/appbar.transport.play.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("pause", "/icons/appbar.transport.pause.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("rew", "/icons/appbar.transport.rew.rest.png", true, ApplicationBarIconButton_Click);

	this.appbar.AddNewButton("add menu", "/icons/appbar.add.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewButton("clear menus", "/icons/appbar.close.rest.png", true, ApplicationBarIconButton_Click);
	this.appbar.AddNewMenuItem("Message", true, ApplicationBarMenuItem_Click);
}

private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
	ApplicationBarIconButton btn = (ApplicationBarIconButton)sender;
	string text = btn.Text.ToLower();
	
	// your conditions here
	if (text == "add")
	{
		MessageBox.Show("Add button was clicked");
	}
	// add more conditions here
}

private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
{
	ApplicationBarMenuItem menu = (ApplicationBarMenuItem)sender;
	string text = menu.Text.ToLower();
	
	// your conditions here
}

Then while at run time, you can simple show the Icon Buttons or Menu Items you need for the current task in your page

this.appbar.ShowButtons(new string[] { "add", "delete", "clear" });
// or the same as
this.appbar.ShowButtons("add", "delete", "clear");
// or
this.appbar.ShowButtons("add", "clear");

and the same way with Menu Items. One important to note is, the Text you give to the Icon Button or Menu Items acts as a Key and it's case sensitive.

Download the code here

http://www.codeproject.com/Articles/470063/Windows-Phone-ApplicationBar-Controller

Click here to expand the blog post

C# Passing Values Between Multiple Projects using Interface

Earlier when I was doing some major update on a project I was working on for a client, I was also thinking how to optimize the code, not just by using MVP pattern and also the way of passing values between projects. Some of my class libraries where using the same type of property and then gets updated in the main form. I noticed though that setting the same value into the multiple objects with one type of property is pretty hard and unmanageable and also producing a lot of lines of codes. So I experimented a little bit and made an proof on concept how to pass values into multiple projects with minimal coding and using Interface

Let's see the sample animation below. What was shown there is we have satellite that moves in the form and there are 3 child forms. Those 3 child forms are the other 3 projects which are PlanetEarth, PlanetMars, and PlanetSaturn project and the big the form is our Main project. You'll notice that the 3 forms are getting updated everytime the satellite make its next move.

What is so interesting in using an Interface is you can share its values to whoever uses it. Like what I did on that simple P.O.S. project. Those 3 forms, PlanetEarth, PlanetMars, and PlanetSaturn is using one interface but they all get the update.

So why Interface instead of making a property for each project?

Because like I said, you can share the values between multiple projects or whoever uses it.

Let's get into the code

In this sample VS solution. We have 5 projects.

GlobalInterface class library project which contains the Interface code which have an NextPosition property signature what we're going to use later on the Main Project

public interface iSatellite
{
	Point NextPosition { get; set; }
}

Then we have 3 projects that has the same code (For demo only) which is using this iSatellite interface. These are the PlanetEarth, PlanetMars, and PlanetSaturn. Let's take PlanetEarth for example

GlobalInterface.iSatellite Satellite;

public Form1()
{
	InitializeComponent();

	timer1.Interval = 100;
	timer1.Tick += new EventHandler(timer1_Tick);
}

void timer1_Tick(object sender, EventArgs e)
{
	// update the location information of the satellite
	label2.Text = string.Format("X: {0}\r\nY:{1}", this.Satellite.NextPosition.X, this.Satellite.NextPosition.Y);
}

public void InitializeSatellite(GlobalInterface.iSatellite satellite)
{
	this.Satellite = satellite;
	this.timer1.Start();
}

As you noticed, we used Timer object to show the next location of the satellite. We could also use Event to shout that the satellite is making a next move.

InitializeSatellite(GlobalInterface.iSatellite satellite) will be called on our Main Project to bind the "this.Satellite" into our Main project.

Next is our Main project that implements iSatellite interface

public partial class MainController : Form, GlobalInterface.iSatellite
{
	TweenLibrary tween;
	Random destXY = new Random(DateTime.Now.Millisecond);
	List<Form> forms;

	public MainController()
	{
		InitializeComponent();
		InitializeControls();
		InitializeControlEvents();
	}

	public void InitializeControls()
	{
		// show our 3 forms
		PlanetEarth.Form1 earth = new PlanetEarth.Form1();
		earth.InitializeSatellite(this);
		earth.Show();

		PlanetMars.Form1 mars = new PlanetMars.Form1();
		mars.InitializeSatellite(this);
		mars.Show();

		PlanetSaturn.Form1 saturn = new PlanetSaturn.Form1();
		saturn.InitializeSatellite(this);
		saturn.Show();

		// then put them on the list to update their location
		forms = new List<Form>()
		{
			earth, mars, saturn
		};

		tween = new TweenLibrary();

		timer1.Interval = Convert.ToInt32(TimeSpan.FromSeconds(3).TotalMilliseconds);
		timer1.Tick += new EventHandler(timer1_Tick);
		timer1.Start();
	}

	public void InitializeControlEvents()
	{
		this.LocationChanged += new EventHandler(Form1_LocationChanged);
	}

	/// <summary>
	/// update child form positions
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void Form1_LocationChanged(object sender, EventArgs e)
	{
		int last_y = this.Location.Y;

		foreach (Form frm in forms)
		{
			frm.Location = new Point(this.Location.X + this.Size.Width, last_y);
			last_y = frm.Location.Y + frm.Size.Height;
		}
	}

	void timer1_Tick(object sender, EventArgs e)
	{
		this.NextPosition = new Point()
		{
			X = destXY.Next(this.ClientSize.Width),
			Y = destXY.Next(this.ClientSize.Height)
		};

		tween.startTweenEvent(picSatellite, this.NextPosition.X, this.NextPosition.Y, "easeinoutcubic", 100);
	}

	/// <summary>
	/// Implement GlobalInterface.iSatellite property
	/// </summary>
	public Point NextPosition { get; set; }
}

As you can see just below on that code, we implemented iSatellite interface with NextPosition property with a Point type which we're going to use to update the location of the satellite. In the timer1_Tick event, this gets triggered every 3 seconds and you can see, we update the "NextPosition" X and Y values. The 3 projects that is bound in the interface are automatically updated.

So what is the benefit of the Interface in this type of problem about passing values between multiple visual studio projects?

  • Lesser code
  • We do not need to update the values for each project.
  • Easy to manage
  • More structured.

Comparing the usage of Property vs Interface

Let's say each projects PlanetEarth, PlanetMars, and PlanetSaturn are using NextPosition Property

void timer1_Tick(object sender, EventArgs e)
{
	Point newXY = new Point()
	{
		X = destXY.Next(this.ClientSize.Width),
		Y = destXY.Next(this.ClientSize.Height)
	};
	
	this.earth.NextPosition = newXy;
	this.mars.NextPosition = newXy;
	this.saturn.NextPosition = newXy;
}

But when we use Interface

void timer1_Tick(object sender, EventArgs e)
{
	this.NextPosition = new Point()
	{
		X = destXY.Next(this.ClientSize.Width),
		Y = destXY.Next(this.ClientSize.Height)
	};

	tween.startTweenEvent(picSatellite, this.NextPosition.X, this.NextPosition.Y, "easeinoutcubic", 100);
}

We only update the property we implemented from iSatellite and all 3 projects are automatically updated as well.

Hope you learned about another special way of implementing Interface in your projects, not only in Windows Forms, but in Windows Phone, Windows 8, Silverlight, and WPF projects as well.

Here's the a sample project that you can play with.

Click here to expand the blog post

WPF Triggered Events Before The Window Shows and Closed

I was doing some WPF application and I needed to check the window size. So I experimented a little bit with the Window events and the methods we can override and, set the window style as Maximized and added Close button control and this is what I got. 

Custom: MainWindow() 				| window size: w-NaN, h-NaN
Custom: InitializeComponent() 		| window size: w-NaN, h-NaN
override: OnContentChanged() 		| window size: w-525, h-350
override: OnInitialized() 			| window size: w-525, h-350
override: OnTemplateChanged() 		| window size: w-525, h-350
Custom: InitializeControlEvents() 	| window size: w-525, h-350
Custom: InitializeControls() 		| window size: w-525, h-350
override: OnVisualChildrenChanged() | window size: w-1829, h-1010
override: OnApplyTemplate() 		| window size: w-1829, h-1010
event: SizeChanged 					| window size: w-1829, h-1010
event: LayoutUpdated 				| window size: w-1829, h-1010
event: LayoutUpdated 				| window size: w-1829, h-1010
override: OnActivated() 			| window size: w-1829, h-1010
event: Activated 					| window size: w-1829, h-1010
event: SizeChanged 					| window size: w-1827, h-1036
event: LayoutUpdated 				| window size: w-1827, h-1036
event: LayoutUpdated 				| window size: w-1827, h-1036
event: Loaded 						| window size: w-1827, h-1036
override: OnContentRendered() 		| window size: w-1827, h-1036
event: LayoutUpdated 				| window size: w-1827, h-1036
event: LayoutUpdated 				| window size: w-1827, h-1036
event: btnClose_Click 				| window size: w-1827, h-1036
override: OnClosing() 				| window size: w-1827, h-1036
override: OnClosed() 				| window size: w-1827, h-1036
Click here to expand the blog post

WPF How to create a Metro or Windows 8 Style way of closing a window

We all know (well not really all) how easy it is to close an Metro Windows 8 application. You just have to put your beautiful finger on top and slide it all the way to the bottom, the same way with the mouse. Of course there are other ways to close an Windows 8 application but am not going further with that. Will only just cover the slide and close tutorial.

The image below is an example of closing an Windows 8 application using mouse by sliding (more like dragging) from top to bottom.

In this WPF and C# tutorial. We're going to do the same (not exactly) effect. 90% close to the original. The same idea I made for System Power Shortcuts

Start by watching this video

Here are the codes

MainWindow.xaml

<Grid>
	<Canvas>
		<Grid x:Name="MainContent" Canvas.Top="0" Canvas.Left="0" Width="500">
			<!--
				your super XAML codes here. But for the mean time
			
				we're going to use Image element
			-->
			
			<Image x:Name="img" Source="/WpfW8MetroStyleSlideToClose;component/imageres/img1.jpg" />
		</Grid>

		<Grid x:Name="DragBar" Height="32" Canvas.Top="0" Canvas.Left="0" Background="Transparent" Cursor="Hand" />
	</Canvas>
</Grid>

Codes for dragging

bool isMouseCaptured = false;
double mouseVerticalPosition = 0;
double mouseHorizontalPosition = 0;
		
void DragBar_MouseUp(object sender, MouseButtonEventArgs e)
{
	isMouseCaptured = false;
	DragBar.ReleaseMouseCapture();
	mouseVerticalPosition = -1;
	mouseHorizontalPosition = -1;
}

void DragBar_MouseMove(object sender, MouseEventArgs e)
{
	if (isMouseCaptured)
	{
		// Calculate the current position of the object.
		double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
		double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
		double newTop = deltaV + (double)DragBar.GetValue(Canvas.TopProperty);
		double newLeft = deltaH + (double)DragBar.GetValue(Canvas.LeftProperty);

		// Set new position of object.
		DragBar.SetValue(Canvas.TopProperty, newTop);
		DragBar.SetValue(Canvas.LeftProperty, newLeft);

		MainContent.SetValue(Canvas.TopProperty, newTop);
		MainContent.SetValue(Canvas.LeftProperty, newLeft);

		// Update position global variables.
		mouseVerticalPosition = e.GetPosition(null).Y;
		mouseHorizontalPosition = e.GetPosition(null).X;
	}
}

void DragBar_MouseDown(object sender, MouseButtonEventArgs e)
{
	mouseVerticalPosition = e.GetPosition(null).Y;
	mouseHorizontalPosition = e.GetPosition(null).X;
	isMouseCaptured = true;
	DragBar.CaptureMouse();
}

Method used for animated scaling

void ScaleTransformAnimation(UIElement element, double fromValue, double toValue, double centerX, double centerY, int duration_ms)
{
	ScaleTransform scale_trans = new ScaleTransform()
	{
		ScaleX = toValue,
		ScaleY = toValue
	};
	DoubleAnimation danim = new DoubleAnimation()
	{
		From = fromValue,
		Duration = TimeSpan.FromMilliseconds(duration_ms)
	};

	element.RenderTransformOrigin = new Point(centerX, centerY);
	element.RenderTransform = scale_trans;

	scale_trans.BeginAnimation(ScaleTransform.ScaleXProperty, danim);
	scale_trans.BeginAnimation(ScaleTransform.ScaleYProperty, danim);
}

Pythagorean Theorem

public int Distance2D(int x1, int y1, int x2, int y2)
{
	//Our end result
	int result = 0;
	//Take x2-x1, then square it
	double part1 = Math.Pow((x2 - x1), 2);
	//Take y2-y1, then sqaure it
	double part2 = Math.Pow((y2 - y1), 2);
	//Add both of the parts together
	double underRadical = part1 + part2;
	//Get the square root of the parts
	result = (int)Math.Sqrt(underRadical);
	//Return our result
	return result;
}

Entire MainWindow.xaml.cs code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace WpfW8MetroStyleSlideToClose
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        bool isMouseCaptured = false;
        double mouseVerticalPosition = 0;
        double mouseHorizontalPosition = 0;

        public MainWindow()
        {
            InitializeComponent();
            InitializeControlEvents();
            InitializeControls();
        }

        void InitializeControls()
        {
        }

        void InitializeControlEvents()
        {
            this.SizeChanged += new SizeChangedEventHandler(MainWindow_SizeChanged);

            this.DragBar.MouseDown += new MouseButtonEventHandler(DragBar_MouseDown);
            this.DragBar.MouseMove += new MouseEventHandler(DragBar_MouseMove);
            this.DragBar.MouseUp += new MouseButtonEventHandler(DragBar_MouseUp);
        }

        void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            DragBar.Width = SystemParameters.FullPrimaryScreenWidth;

            MainContent.Width = SystemParameters.FullPrimaryScreenWidth;
            MainContent.Height = this.Height;
        }

        void DragBar_MouseUp(object sender, MouseButtonEventArgs e)
        {
            ScaleTransformAnimation(MainContent, 0.3, 1, 0.5, 0, 150);
            ScaleTransformAnimation(DragBar, 0.3, 1, 0.5, 0, 150);

            isMouseCaptured = false;
            DragBar.ReleaseMouseCapture();
            mouseVerticalPosition = -1;
            mouseHorizontalPosition = -1;

            Canvas.SetTop(DragBar, 0);
            Canvas.SetLeft(DragBar, 0);
            Canvas.SetTop(MainContent, 0);
            Canvas.SetLeft(MainContent, 0);
        }

        void DragBar_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseCaptured)
            {
                // Calculate the current position of the object.
                double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
                double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
                double newTop = deltaV + (double)DragBar.GetValue(Canvas.TopProperty);
                double newLeft = deltaH + (double)DragBar.GetValue(Canvas.LeftProperty);

                // Set new position of object.
                DragBar.SetValue(Canvas.TopProperty, newTop);
                DragBar.SetValue(Canvas.LeftProperty, newLeft);

                MainContent.SetValue(Canvas.TopProperty, newTop);
                MainContent.SetValue(Canvas.LeftProperty, newLeft);

                int distance = Distance2D(0, Convert.ToInt32(MainContent.Height), 0, Convert.ToInt32(mouseVerticalPosition));

                if (distance < 30)
                {
                    this.Close();
                }

                // Update position global variables.
                mouseVerticalPosition = e.GetPosition(null).Y;
                mouseHorizontalPosition = e.GetPosition(null).X;
            }
        }

        void DragBar_MouseDown(object sender, MouseButtonEventArgs e)
        {
            mouseVerticalPosition = e.GetPosition(null).Y;
            mouseHorizontalPosition = e.GetPosition(null).X;
            isMouseCaptured = true;
            DragBar.CaptureMouse();

            ScaleTransformAnimation(MainContent, 1, 0.3, 0.5, 0, 150);
            ScaleTransformAnimation(DragBar, 1, 0.3, 0.5, 0, 150);
        }

        void ScaleTransformAnimation(UIElement element, double fromValue, double toValue, double centerX, double centerY, int duration_ms)
        {
            ScaleTransform scale_trans = new ScaleTransform()
            {
                ScaleX = toValue,
                ScaleY = toValue
            };
            DoubleAnimation danim = new DoubleAnimation()
            {
                From = fromValue,
                Duration = TimeSpan.FromMilliseconds(duration_ms)
            };

            element.RenderTransformOrigin = new Point(centerX, centerY);
            element.RenderTransform = scale_trans;

            scale_trans.BeginAnimation(ScaleTransform.ScaleXProperty, danim);
            scale_trans.BeginAnimation(ScaleTransform.ScaleYProperty, danim);
        }

        public int Distance2D(int x1, int y1, int x2, int y2)
        {
            //Our end result
            int result = 0;
            //Take x2-x1, then square it
            double part1 = Math.Pow((x2 - x1), 2);
            //Take y2-y1, then sqaure it
            double part2 = Math.Pow((y2 - y1), 2);
            //Add both of the parts together
            double underRadical = part1 + part2;
            //Get the square root of the parts
            result = (int)Math.Sqrt(underRadical);
            //Return our result
            return result;
        }
    }
}

and finally the download visual studio solution in my SkyDrive and play with

 WpfW8MetroStyleSlideToClose.zip (659kb)

Click here to expand the blog post

About Jayson Ragasa

Jayson Ragasa is an Applications Developer and founder of CAPPLOUD.

Badges

Free Page Rank Tool

wall.jaysonragasa.net Webutation
Uptime Report for http://wall.jaysonragasa.net/: Last 30 days