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)
{
int windowsCount = _ListWindows.Where(s => s.Mode == WindowLayoutMode.Tiled).Count();
if (windowsCount == 0) throw new InvalidOperationException
("No child windows to tile");
double parentAspectRatio = width / 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)
{
columnCount++;
childWindowWidth = width / columnCount;
childWindowHeight = childWindowWidth / childAspectRatio;
if (columnCount * rowCount < windowsCount)
{
rowCount++;
childWindowHeight = height / rowCount;
childWindowWidth = childWindowHeight * childAspectRatio;
}
}
else if (rowDiscrepancy > colDiscrepancy)
{
rowCount++;
childWindowHeight = height / rowCount;
childWindowWidth = childWindowHeight * childAspectRatio;
if (columnCount * rowCount < windowsCount)
{
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:
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!