Faux Giant Application Icon with Extended Aero Glass in WPF
Maybe not the best title to describe the post. Anyway, I was looking at some of the apps the other teams did for PhizzPop. Kudos to all the regional winners. Great stuff. In particular, thirteen23 had this cool effect.
I'm not entirely sure how they get the chair to look like that. It's almost like magic. My initial thought was that WPF allowed you to set a ClipToBounds = false on a window and place a control partially outside the bounds of the window. I've never heard of that and it doesn't look like you can do it either. Then I thought it might be some type of custom border like this or some use of the DWM functions. That's probably more pinvoking than I'd like to do in one evening. There has to be an easy way to do that effect. I'm looking for about 5 mins of coding. Then I realized I could just add a second window on top of the first, relatively position it, set the window style to none, allow transparency, and make the background transparent. Done. Here is how mine looks.
There is probably a better way. Not sure. A magician never reveals his secrets.
So here's how I did it. Make a new form in WPF and set the WindowStyle to none . To get the extended aero glass for the form, I used Adam Nathan's GlassHelper class. Then make a second window and set
WindowStyle="None" AllowsTransparency="True" Background="Transparent" IsEnabled="False" ShowInTaskbar="False"
Next add an image that you want to serve as your giant faux application icon. I chose a nice Vista coffee icon I found here.
In code behind I set the owner of the 2nd window to the main window. I also positioned it accordingly. Something new I learned today was how to listen to dependency property changed events from the DependencyProprtyDescriptor. Awesome. I had never tried to do that before. I listen for the Top and Left property changes of the main window so I can keep the 2nd window in the same relative position. That way the illusion works even as you drag the main window around. It's not perfect as sometimes you notice a slight delay before it moves. At least the coffee cup isn't off floating on monitor #1 while the rest of the application has migrated to monitor #4. I also added some simple drag code since there isn't a border at the top to grab.
1: private void Window_Loaded(object sender, RoutedEventArgs e)
2: {
3: window2 = new Window2();
4: window2.Top = this.Top - 40;
5: window2.Left = this.Left + 30; ;
6: window2.Owner = this;
7: window2.Show();
8:
9:
10: DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Window.TopProperty, typeof(Window));
11:
12: if (dpd != null)
13: {
14: dpd.AddValueChanged(this, delegate
15: {
16: window2.Top = this.Top - 50;
17: });
18:
19: dpd.AddValueChanged(this, delegate
20: {
21: window2.Left = this.Left + 30; ;
22: });
23: }
24:
25: }
26:
27: private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
28: {
29: this.DragMove();
30: }
The full source code is here.
Like I said earlier, probably not the most elegant solution, but I think it looks cool. I'd be curious to see how thirteen23 did it.
Oh, I also uploaded a video of our PhizzPop application to Clarity TV.