Nico's digital footprint

I grew up in the nineties, that makes me awesome by default

Comic Organizer part II: Going metro

by Nico

In part 1 I talked about MVVM and MVVM Light, I hope you learned something from it. Now it’s time to move on to the next part, we’re going to start building a WPF application.

First things first, here are the tools I’m going to use:

The WPF toolkit is a set of controls that extend the default WPF controls, it’s build by Microsoft and updated a few times a year.

If the MVVM Light toolkit is installed you should see new project types when creating a new project in Visual Studio. I’m going to create a new WPF 4 project.

Now that the project is created, take a look at the solution explorer, there you will find the MVVM parts nicely ordered in separate folders. If you want you can take them and put every part in a separate project, I won’t be doing that for my application since it’s pretty small.

 

Now that we got our project, let’s metronize it. For this we need to open the solution in Expression Blend. The best way to work on XAML based projects is to open the solution in both Visual Studio and Expression Blend, changes made in one will automatically be reflected in the other.

Metro isn’t a style that is out of the box available for WPF. While searching for a way to imitate the Metro windows like Microsoft uses it in Zune I stumbled upon the blog of Steven Hook. He had the idea of using the Wingdings font for the upper right buttons. Sounds weird? Let me show you how it works.

In Expression Blend I’ve set the WindowsStyle property to “None” and ResizeMode to “ResizeWithGrip”, the generated XAML looks like this

Code Snippet
  1. <Window x:Class="ComicOrganizer.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         mc:Ignorable="d"
  7.         Title="Comic Organizer"
  8.         DataContext="{Binding Main, Source={StaticResource Locator}}" WindowStyle="None" ResizeMode="CanResizeWithGrip" AllowsTransparency="True">

This gives a clean white window without borders that can be resized by using the grip in the lower right corner. Next step is adding the controls for closing, maximizing and minimizing the window. This is the XAML responsible for those buttons

Code Snippet
  1. <Grid
  2.     x:Name="HeaderGrid"
  3.     Height="50"
  4.     VerticalAlignment="Top" Grid.ColumnSpan="2">
  5.     <Grid
  6.         x:Name="DragableArea"
  7.         Background="White"
  8.         MouseDown="DragableGridMouseDown"/>
  9.     <StackPanel
  10.         Orientation="Horizontal"
  11.         Margin="0,5,5,0"
  12.         HorizontalAlignment="Right"
  13.         VerticalAlignment="Top"
  14.         Background="White">
  15.         <TextBlock
  16.             x:Name="ChangeViewButton"
  17.             Text="2"
  18.             FontFamily="Webdings"
  19.             Foreground="Gray"
  20.             Margin="0"
  21.             VerticalAlignment="Top"
  22.             HorizontalAlignment="Right"
  23.             MouseLeftButtonUp="ChangeViewButtonMouseLeftButtonUp" />
  24.         <TextBlock
  25.             x:Name="MinimizeButton"
  26.             Text="0"
  27.             FontFamily="Webdings"
  28.             Foreground="Gray"
  29.             Margin="5,0,0,0"
  30.             HorizontalAlignment="Right"
  31.             VerticalAlignment="Top"
  32.             MouseLeftButtonUp="MinimizeButtonMouseLeftButtonUp" />
  33.         <TextBlock
  34.             x:Name="MaximizeButton"
  35.             Text="1"
  36.             FontFamily="Webdings"
  37.             Foreground="Gray"
  38.             Margin="5,0,0,0"
  39.             HorizontalAlignment="Right"
  40.             VerticalAlignment="Top"
  41.             MouseLeftButtonUp="MaximizeButtonMouseLeftButtonUp" />
  42.         <TextBlock
  43.             x:Name="CloseButton"
  44.             Text="r"
  45.             FontFamily="Webdings"
  46.             Foreground="Gray"
  47.             Margin="5,0,0,0"
  48.             HorizontalAlignment="Right"
  49.             VerticalAlignment="Top"
  50.             MouseLeftButtonUp="CloseButtonMouseLeftButtonUp" />
  51.     </StackPanel>
  52. </Grid>

The “DragableArea” grid will allow the application to be dragged around the screen by the user, just like any app does. The Stackpanel takes care of the 4 buttons in the upper right corner.

Now we need to implement the logic for these buttons, the buttons are actually textblocks but will behave like buttons. The blog that I got this idea from said that the logic of the buttons is the responsibility of the view, so even in an MVVM application it could be placed in the code behind file of the view. I tend to agree with this logic so I’m going to place it in the code behind as well, although it’s perfectly possible to put it in the ViewModel.

The complete code behind file looks like this:

Code Snippet
  1. using System.Windows;
  2. using System.Windows.Input;
  3. using ComicOrganizer.ViewModel;
  4.  
  5. namespace ComicOrganizer
  6. {
  7.     /// <summary>
  8.     /// Interaction logic for MainWindow.xaml
  9.     /// </summary>
  10.     public partial class MainWindow : Window
  11.     {
  12.         /// <summary>
  13.         /// Initializes a new instance of the MainWindow class.
  14.         /// Metro style logic is done here because it's the responsibility of the View
  15.         /// idea found on http://stevenhook.blogspot.com/2011/01/wpf-borderless-window-controls.html
  16.         /// </summary>
  17.         public MainWindow()
  18.         {
  19.             InitializeComponent();
  20.             Closing += (s, e) => ViewModelLocator.Cleanup();
  21.         }
  22.  
  23.         private void CloseButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  24.         {
  25.             Close();
  26.         }
  27.  
  28.         private void MaximizeButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  29.         {
  30.             WindowState = WindowState.Maximized;
  31.         }
  32.  
  33.         private void ChangeViewButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  34.         {
  35.             WindowState = WindowState.Normal;
  36.         }
  37.  
  38.         private void MinimizeButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  39.         {
  40.             WindowState = WindowState.Minimized;
  41.         }
  42.  
  43.         private void DragableGridMouseDown(object sender, MouseButtonEventArgs e)
  44.         {
  45.             if (e.ChangedButton == MouseButton.Left)
  46.                 DragMove();
  47.         }
  48.     }
  49. }

 

These little methods speak for themselves, if you have any questions about them feel free to leave a comment or contact me via mail, twitter, …

That was it for this second part, we now have a running WPF application in Metro style using some easy tricks. I believe that Microsoft will give a real Metro style out to the community, when they do I’ll probably convert this app to use the real style.

In part III we’ll start receiving data and maybe some databinding as well, who knows? Glimlach

Stay tuned for part III in a couple of weeks!


Tags:

.Net | Windows programming

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

  Log in

About the author

Hi,

My name is Nico, I’m an MCP living in Belgium.
I’m currently employed as a consultant in the Mobile Solution Center at RealDolmen, one of Belgium’s leading IT single source providers, where I focus on Windows Phone and Windows 8 development.

I'm also founding member and board member of the Belgian Metro App Developer Network, a user group focussed on Windows 8 and Windows Phone development. If you're in Belgium feel free to drop by if we're doing an event. http://www.madn.be

Since June 2012 I'm a proud member of Microsoft's Extended Experts Team Belgium. And in February 2013 I became a member of DZone's Most Valuable Bloggers family.

This blog will be about Windows Phone 7, C#, XNA , WPF, Silverlight, and much more!

I hope to get feedback from my readers either through comments, mail (nico_vermeir@hotmail.com), twitter, facebook, …

 

 

MeetLogo

 

MVBLogo

mybook

 

mybook

 

Month List