Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF Masala - The Sliding and Flying Windows

0.00/5 (No votes)
14 Sep 2011 1  
Experiments with WPF animation to recreate some of Microsoft Health Common User Interface magic!

Introduction and Background

Anyone who has seen the fantastic user interface developed by Microsoft folks - Microsoft Health Common User Interface, can't remain unimpressed to say the least. Hats off to the fantastic work done by the designers and developers there. As part of my WPF learning, I thought why not try to recreate some of the magic. This was looking promising so I thought I would share this with CodeProject friends. Here is the first cut: Youtube video.

Using the Code

Just unzip the file and take a look at the WindowsContainer class. The only logical block worth looking at is the tiling logic:

private void TileWindows(double left, double top, double width,
	double height, double margin, double childAspectRatio)
{
    // Get the no of child windows to tile:
    int windowsCount = _ListWindows.Where(s => s.Mode == WindowLayoutMode.Tiled).Count();
    if (windowsCount == 0) throw new InvalidOperationException
					("No child windows to tile");

    // Now calculate the optimum size for each window:
    double parentAspectRatio = width / height;// this.Width / this.Height;

    if (childAspectRatio <= 0)
    {
        double childHeight = height / windowsCount;
        childAspectRatio = width / childHeight;
    }

    double sqrtN = Math.Sqrt((double)windowsCount);
    double sqrtAspectRatioRatio = Math.Sqrt(parentAspectRatio / childAspectRatio);
    double childWindowHeight = height * sqrtAspectRatioRatio / sqrtN;
    double childWindowWidth = childAspectRatio * childWindowHeight;
    double rowCountDouble = height / childWindowHeight;
    double columnCountDouble = width / childWindowWidth;

    int columnCount = (int)columnCountDouble;
    double colDiscrepancy = (columnCountDouble - columnCount) / columnCountDouble;
    int rowCount = (int)rowCountDouble;
    double rowDiscrepancy = (rowCountDouble - rowCount) / rowCountDouble;

    if (colDiscrepancy > rowDiscrepancy)
    {
        //shrink column width
        columnCount++;
        childWindowWidth = width / columnCount;
        childWindowHeight = childWindowWidth / childAspectRatio;

        if (columnCount * rowCount < windowsCount)
        {
           //shrink row height
           rowCount++;
           childWindowHeight = height / rowCount;
           childWindowWidth = childWindowHeight * childAspectRatio;
        }
    }
    else if (rowDiscrepancy > colDiscrepancy)
    {
        //shrink row height
        rowCount++;
        childWindowHeight = height / rowCount;
        childWindowWidth = childWindowHeight * childAspectRatio;
        if (columnCount * rowCount < windowsCount)
        {
            //shrink column width
            columnCount++;
            childWindowWidth = width / columnCount;
            childWindowHeight = childWindowWidth / childAspectRatio;
        }
    }

    int index = 0;
    int indexRow = 0;
    int indexColumn = 0;
    List<storyboard> listStoryboard = new List<storyboard>();
    foreach (ChildWindow window in _ListWindows)
    {
        if (window.Mode == WindowLayoutMode.Tiled)
        {
            indexColumn = index % columnCount;
            indexRow = (int)(index / columnCount);

            Rect targetRect = new Rect(
            left + indexColumn * childWindowWidth + margin,
            top + indexRow * childWindowHeight + margin,
            childWindowWidth - 2 * margin,
            childWindowHeight - 2 * margin);
            listStoryboard.Add(GetStoryboard(window, targetRect));

            window.SetVerticalTitle(targetRect.Width <= window.Title.Height + 15);

            index++;
        }
        else
        {
            window.SetVerticalTitle(false);
        }
    }
    foreach (Storyboard sb in listStoryboard)
    {
        LayoutRoot.Resources.Add(sb.Name, sb);

        sb.Begin(LayoutRoot);

        LayoutRoot.Resources.Remove(sb.Name);
    }
}</storyboard></storyboard>

Windows container uses a Canvas to place the child windows on it. I think there may be a possibility of using Grid there. I am not too sure.

I have used multiple borders with varying opacity and margins to create the shade effect on the child windows:

FlyingWindows1.jpg

Most of the code in this project is self explanatory. However, I would be happy to beef up this article with more explanation if required.

Points of Interest

I am planning to add more windowing effects and port it to Silverlight too. I'll keep you posted.

History

  • 15th November, 2008: Initial post

Awaiting feedback!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here