The result looks like this:


Step 1 - preparations:
Create a new WPF application and set the window properties "WindowStyle" and "Background" to "None" and "Transparent" respectively.
Now you should end up with a completely transparent window, when running the project.
Step 2 - Create the actual title bar:
Now we need to switch to "xaml view" and add some rectangles:
<!--this goes into the "<grid>" section --> <Rectangle Height="77" Width="5" VerticalAlignment="Top" HorizontalAlignment="Left" MouseDown="move_window"> <Rectangle.Fill> <ImageBrush ImageSource="UI_RES\Title_top_left.png" /> <!-- could be solidcolor as well --> </Rectangle.Fill> </Rectangle> <Rectangle Height="77" Margin="5,0,5,0" VerticalAlignment="Top" HorizontalAlignment="Stretch" MouseDown="move_window"> <Rectangle.Fill> <ImageBrush ImageSource="UI_RES\Title_top_middle.png" /> <!-- could be solidcolor as well --> </Rectangle.Fill> </Rectangle> <Rectangle Height="77" Width="5" VerticalAlignment="Top" HorizontalAlignment="Right" MouseDown="move_window"> <Rectangle.Fill> <ImageBrush ImageSource="UI_RES\Title_top_right.png" /> <!-- could be solidcolor as well --> </Rectangle.Fill> </Rectangle>
As you can see I added three rectangles (because I wanted rounded corners) and set the center rectangle to "stretch" (this way you can maximize without loosing your title bar). Now we need some C# code (yourwindow.xaml.cs) to move the window:
using System.Runtime.InteropServices;
using System.Windows.Interop;
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg,
int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
public void move_window(object sender, MouseButtonEventArgs e)
{
ReleaseCapture();
SendMessage(new WindowInteropHelper(this).Handle,
WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
Step 3 - Adding icons to close, maximize and minimize:
Now we add the xaml code to create the three buttons and add the events. I decided to go for brushes in the resource section to describe the different states...
<!--this goes into the "<window>" section -->
<Grid.Resources>
<ImageBrush x:Key="Close_inact" ImageSource="UI_RES\Close_inact.png" />
<ImageBrush x:Key="Min_inact" ImageSource="UI_RES\Minimize_inact.png" />
<ImageBrush x:Key="Max_inact" ImageSource="UI_RES\Maximize_inact.png" />
<ImageBrush x:Key="Close_act" ImageSource="UI_RES\Close_act.png" />
<ImageBrush x:Key="Min_act" ImageSource="UI_RES\Minimize_act.png" />
<ImageBrush x:Key="Max_act" ImageSource="UI_RES\Maximize_act.png" />
<ImageBrush x:Key="Close_pr" ImageSource="UI_RES\Close_pr.png" />
<ImageBrush x:Key="Min_pr" ImageSource="UI_RES\Minimize_pr.png" />
<ImageBrush x:Key="Max_pr" ImageSource="UI_RES\Maximize_pr.png" />
</Grid.Resources>
<!--this goes into the "<grid>" section -->
<Rectangle Margin="8,4,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
Width="56" Height="15" Fill="Transparent"
MouseEnter="Activate_Title_Icons" MouseLeave="Deactivate_Title_Icons" />
<Ellipse Margin="8,4,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
Width="14" Height="15" MouseLeftButtonUp="EXIT"
MouseEnter="Activate_Title_Icons" MouseLeave="Deactivate_Title_Icons"
MouseLeftButtonDown="Close_pressing" Name="Close_btn"
Fill="{DynamicResource Close_inact}" />
<Ellipse Margin="29,4,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
Width="14" Height="15" MouseLeftButtonUp="MINIMIZE"
MouseEnter="Activate_Title_Icons" MouseLeave="Deactivate_Title_Icons"
MouseLeftButtonDown="Min_pressing" Name="Min_btn"
Fill="{StaticResource Min_inact}" />
<Ellipse Margin="50,4,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
Width="14" Height="15" MouseLeftButtonUp="MAX_RESTORE"
MouseEnter="Activate_Title_Icons" MouseLeave="Deactivate_Title_Icons"
MouseLeftButtonDown="Max_pressing" Name="Max_btn"
Fill="{StaticResource Max_inact}" />
I added an additional rectangle to describe the hover effect on all three icons(just like the real osx does it).
Now we need the c# code to handle all those events.
private void EXIT(object sender, MouseButtonEventArgs e)
{
Environment.Exit(0);
}
private void MINIMIZE(object sender, MouseButtonEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void MAX_RESTORE(object sender, MouseButtonEventArgs e)
{
if (this.WindowState == WindowState.Normal) this.WindowState = WindowState.Maximized;
else this.WindowState = WindowState.Normal;
}
private void Activate_Title_Icons(object sender, MouseEventArgs e)
{
//hover effect, make sure your grid is named "Main" or replace "Main" with the name of your grid
Close_btn.Fill = (ImageBrush)Main.Resources["Close_act"];
Min_btn.Fill = (ImageBrush)Main.Resources["Min_act"];
Max_btn.Fill = (ImageBrush)Main.Resources["Max_act"];
}
private void Deactivate_Title_Icons(object sender, MouseEventArgs e)
{
Close_btn.Fill = (ImageBrush)Main.Resources["Close_inact"];
Min_btn.Fill = (ImageBrush)Main.Resources["Min_inact"];
Max_btn.Fill = (ImageBrush)Main.Resources["Max_inact"];
}
private void Close_pressing(object sender, MouseButtonEventArgs e)
{
Close_btn.Fill = (ImageBrush)Main.Resources["Close_pr"];
}
private void Min_pressing(object sender, MouseButtonEventArgs e)
{
Min_btn.Fill = (ImageBrush)Main.Resources["Min_pr"];
}
private void Max_pressing(object sender, MouseButtonEventArgs e)
{
Max_btn.Fill = (ImageBrush)Main.Resources["Max_pr"];
}
I hope this tutorial helped you on your journey away from crappy windows classic design.
And the visual studio solution:
Custom_title_bar.zip (120.57K)
Number of downloads: 3630
This post has been edited by ls_nerd: 22 August 2009 - 01:39 AM





MultiQuote




|