Saturday, March 23, 2013

Convert WinForm to WPF Metro Style


With the launch of Windows 8, everybody is moving to Metro Style application development. Even myself I have a couple of application for personal and office use. I want to convert these Windows Form (WinForm) applications to Metro Style.

* Source Code / Visual Studio Project file available at the end of the post.

Before you can continue, you might need the following:
  1. Visual Studio Express 2012 for Windows Desktop
  2. Basic C# Programming Skill
  3. Active Internet Connection
I will assume that you already know how to create a Windows Form interface as follows:
First step, you need to add a WPF User Control and create a similar template above:

Now, in order to convert this WPF Interface to a Metro Style, we need to use NuGet Tool to install additional package called MahApps.Metro:
After that, we need to alter the .xaml (layout) file to include the Metro Style:

Add xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro", so that the original:
 <UserControl x:Class="MyWinFormApp.UserControl1"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
become:
 <controls:MetroWindow x:Class="MyWinFormApp.UserControl1"  
        xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
Please don't forget to change the closing tag from </UserControl> to </controls:MetroWindow> as well.

Edit the .xaml.cs (C# code file), so that the original:
 public partial class UserControl1 : UserControl  
   {  
     public UserControl1()  
     {  
       InitializeComponent();  
     }  
   }  
become:
 public partial class UserControl1  
   {  
     public UserControl1()  
     {  
       InitializeComponent();  
     }  
   }  

During this time, if you try to compile, you might get the following error:
It is due to the original Windows Form template does not include reference to .xaml. So now we need to include that reference:
In order to disable the WinForm and instead launch the WPF Metro Style that we just created, the following need to be changed in Program.cs:
Originally:
 static void Main()  
     {  
       Application.EnableVisualStyles();  
       Application.SetCompatibleTextRenderingDefault(false);  
       Application.Run(new Form1());   
     }  
Become:
 static void Main()  
     {  
       UserControl1 uc1 = new UserControl1();  
       uc1.ShowDialog();  
     }  

Upon debugging (or run without debugging), the following result will be obtained:
Ok... what wrong now?? It is because the default color for this style is white over black. In order to reverse it, we need to add a couple of lines into the .xaml file:
Add the following before <Grid>
   <controls:MetroWindow.Resources>  
     <ResourceDictionary>  
       <ResourceDictionary.MergedDictionaries>  
         <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colours.xaml" />  
         <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />  
         <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />  
         <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />  
         <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />  
       </ResourceDictionary.MergedDictionaries>  
     </ResourceDictionary>  
   </controls:MetroWindow.Resources>  

Now, the windows will appear as follow:
Ok, good! Now the interface is more or less Metro. But we can still customize more. Let say, I want to change the button to become square button. I need to add Style="{DynamicResource SquareButtonStyle}" as shown below:
 <Button Content="Button" HorizontalAlignment="Left" Margin="189,225,0,0" VerticalAlignment="Top" Width="75" Style="{DynamicResource SquareButtonStyle}"/>  

Actually there many more features can be explored through the MahApps.Metro package. For example, I add a toggle switch as shown below:


You can view more opportunities at MapApps.Metro package documentation page.

 You can download source code/Visual Studio Project File in my Windows Apps page as well.

Happy coding!
-p/s: I use codefomatter.blogspot.com to insert code into this post.

:: aerobrainTech ::

2 comments:

  1. Hello! You can also use Elysium (elysiumproject.net).

    ReplyDelete
  2. Hello! Glad you share that. I'll try it out soon. Thanks!

    ReplyDelete