Tuesday, October 10, 2006

The next challenge that I am going to share my solution with you is the Office 2007 like window style. As you know, the Office 2007 applications are using the layered windows functionality to display rounded corners and a custom title bar. This is how the typical  window in the new Office looks like:

 

Since the June CTP, WPF allows you to create layered windows by setting the AllowsTransparency to true, Background to Transparent and WindowsStyle to none. Result of that will be a transparent window with no titlebar or borders, so it is our task to draw a non-client area. It didn’t take long time for me to create XAML to display a titlebar with images on a particular window, but what do I do in order to re-use this style on any window in my app? It took me a while to figure out (trial and error again and again…) that the only way right now to declare a style/template for a Window is to do it in the App.xaml, so my first version contained all the xaml and a code in the App.xaml and App.xaml.cs which I didn’t feel was a good way to encapsulate your logic in a re-usable component. Luckily for me, I got to work with Josh Smith who knows quite a few things about WPF, showed me a way how to move my logic into a separate re-usable files. Which is to create XAML file as a ResourceDictionary and a corresponding code file. Don’t forget to declare x:Class attribute in order to associate the code file with this XAML:

  x:Class="OfficeStyleWindowProject.OfficeStyleWindow"
  xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml
   xmlns:ctl="clr-namespace:Controls.Local"
    >

The App.xaml will have to be changed as well:


<Application.Resources>
   <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="OfficeStyleWindow.xaml" />
       <ResourceDictionary.MergedDictionaries>
   <ResourceDictionary>
                     

Of course as soon as I moved to the “templated” world, the event handlers stopped working and I had to do the following: First of all, I created a few custom controls: ImageButton and TitleBar. I would imagine the ImageButton should be a pretty useful control on its own. It implements a few dependency properties ImageNormal, ImageOver and ImageDown which you would use to assign an appropriate images to a button. This control provides similar functionality to what Josh had described in his blog.
There is nothing too fancy in the TitleBar except for a way to hook up into the CloseButton, MinButton and MaxButton Click events. Here’s a snippet that shows how I did it:

First we need to hook up into the control’s Loaded event:

public TitleBar()
{

   this.MouseLeftButtonDown += new MouseButtonEventHandler(OnTitleBarLeftButtonDown);                   

this.MouseDoubleClick += new MouseButtonEventHandler(TitleBar_MouseDoubleClick);
   this.Loaded += new RoutedEventHandler(TitleBar_Loaded);

}

Second, in the loaded event we need to use the FindName method to get to the instances of the buttons:

void TitleBar_Loaded(object sender, RoutedEventArgs e)
{
      closeButton = (ImageButton)this.Template.FindName("CloseButton", this);
      minButton = (ImageButton)this.Template.FindName("MinButton", this);
      maxButton = (ImageButton)this.Template.FindName("MaxButton", this);
 
      closeButton.Click += new RoutedEventHandler(CloseButton_Click);
      minButton.Click += new RoutedEventHandler(MinButton_Click)
      maxButton.Click += new RoutedEventHandler(MaxButton_Click);
}

Overall I am pretty happy with the result. The code has become completely encapsulated in a separate and re-usable files and can be easily added to any project. Here's how the window looks in the test project:

You can download the project with the complete source code from here:

OfficeStyleWindow.zip (39.66 KB)
WPF
10/10/2006 5:43:35 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Wednesday, August 30, 2006

In the previous entry I mentioned that the project’s UI design required me to create an interface similar to the Office 2007 UI. I decided to start with seems to be a simple part: tab control. In the proposed design it looks like that:

While the standard Tab looks like this:

So I started to play with the available properties of the Tab control in XAML. While I managed to apply the appropriate gradient backgrounds, I still needed to modify the shape of the tabs and the background of selected tabs.
The internet search yielded the suggestion to use the Interactive Designer to create a custom template and style for the standard WPF’s TabControl. And I desided to fiddle with the Interactive Designer, thinking that if this tool is created for a non programmer type in mind, I should be able to figure it out pretty easy. I took the Martin’s guide for creation of a glass button and tried to follow the steps to create a required style for the Tab.  That was a mistaken assumption. I immediately got lost in the hierarchy of the objects. After many tries, I finally came upon the SimpleStyles sample which is a part of the .NET 3.0 SDK.  It is located in the Controls\ControlTemplateExamples\XAML folder and contains minimal templates for all standard controls. So I took the template for the Tab control as a base and using the VS started modifying XAML by hand. As it occurred later, this was the best decision for me to get things done. Every time I needed to get the custom style for a standard control, the SimpleStyles sample proved to be the best way to approach creation of the custom templates.

You can download the resulting XAML from here:

TabControlCustom.zip (1.46 KB)

WPF
8/30/2006 3:17:06 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Tuesday, August 29, 2006

Recently I was submerged into the WPF. I had to create a proof of concept screens for one of the clients. The UI that was designed closely resembled the Office 2007 interface with Ribbon and such.

So I bravely jumped into WPF. Installed .NET 3.0, Orcas extensions for VS, Interactive Designer and started on the UI. It is only after I jumped, I realized that am in a completely new world of the client development, that the learning curve has become a “learning cliff” and all of the tricks that I had learned when developing WinForm applications don't work here anymore. I had to start learning basics. Layouts and positioning, coloring, fonts and text etc... And as an early adapter you encounter with limited information available on the subject. There's only one book exists at this time (Chris Sells and Ian Griffits). Everything else is spread around in the WPF blogs, MSDN forums and documentation.

When starting development with WPF you are presented with just a somewhat XP like looking standard controls. How do you change the look and feel of the control? Umm... inherit from the control and override some painting procedure... Right? - Nope, wrong! You create your own template and style in XAML! After 4 days of intensive “how do I do that, try, learn, search, download sample, try again...”, I started to see the light. The bits started to fall into pieces and the world had become a logical place to live again. With a mix of amusement and excitement I realized that MS had finally achieved its long winding goal - separate the presentation code from the functionality. A somewhat sophisticated UI that I have created had almost non existent C# code. Everything else has been done in XAML.


In the next posts I'll try to share a few tips that I learned during this process and hope they'll help somebody ease up the transition. 

WPF
8/29/2006 1:43:28 PM (GMT Daylight Time, UTC+01:00)  #     |