Creating a Gadget style window with WPF and Visual Basic.NET 2008
I don’t know if it is a case of my actually knowing more or the fact that doing stuff with
Windows Presentation Foundation (WPF) is easier. To me it seems doing what I want
is getting quicker these days.
The ability to create and use semi-transparent forms has been around for a while now,
but the process to creating these types of forms has not been the easiest.
Visual Basic.NET 2005 gave us access to the opacity property of a Windows form.
The down side of this was that it made the whole form, including any controls on the
form, opaque thus still showing some of the form itself.
With very little code, creating a gadget type window with WPF is relatively easy.
In fact look of the Window can be created with as few as 5 lines of code. How and
what your gadget window does is entirely up to you. (I will apologize at this point in
time for how bad my gadget will look. I am not a graphical person at all and my
colour coordination is really, really bad.)
What I decided to do was I wanted something that would play some music as I
worked on my computer. VbCity Leader and Microsoft MVP Ged Mead showed
us how to add sound to a WPF app, so I decided to incorporate that idea to my project.
Now admittedly what we will end up at the end of this post is not very exciting or
versatile, but it is a start and can be expanded on to suit your wishes. I just
want to show the basics on how to create the gadget window.
The first thing we need to do is create a new WPF Application and the XAML for
it is pretty basic.

Before you can start adding code to the code behind page there is one thing that
you must do and that is you must add a Name property to the XAML of the Window.
Until you do that you don’t have, on the code behind page, access to the Events
of the window.

I know that it looks like can get to the Window1 Events, but if you tried to set or change
any settings for Window1 you would get errors.
So in the XAML of your page you just need to add a Name property.

I also changed the Title of the page as you can see the title in the Taskbar of your
computer.
Now that we have a name for the form we can tap into the events of the page itself
and start adding code to the code behind. This was when I ran into the first gotcha.
The first gotcha I ran across was in the placement of the code I was using. The first
time I tried to add the code I used the Form_Loaded event, an event that I have used
for setting properties of the form in the past, which has always worked like a charm.
The code I used was:

What happened, however, when I tried to run my project to see what happened was
I got an InvalidOperationException . The reason this exception was thrown is because
you can not set the AllowsTransparency property of a form once the window has
been shown.
To get around this problem I put the code in the Initialize event of the form which let
me set all the properties of the form that I wanted.
As you can see by the code above, I have set the height and width of the form to 200,
then I made changes to the three properties that really make this a gadget type window.
The first property I set was to set the AllowsTransparency to True. What this
property does is indicates whether the client area of the window supports transparency.
The second property set was the Background of the form. This is set to the color Transparent.
The third property set was the WindowStyle. What the WindowsStyle property does
is tell the application what sort of border to put on the window. By setting the style
to None, the ControlBox which you would normally see at the top right of a window are
not show effectively removing the border of the form.
If you were to run the project now you would not actually see anything because your
form is transparent and there are no other controls on it just yet. You could verify
that it is running by taking a look at the Taskbar on your computer.

(You certainly don't need to set the properties of the form, then add controls like I
am doing, you could set up your form like you want it then make whatever changes
you want to make.)
On my form I decided that I am going to have an Ellipse and two Buttons. One button
is to start the music and one to exit the Application.
Let's start with the Ellipse since this will be what our "form" will end up looking like.
First off I added the Ellipse to the XAML of my form making sure that I gave it a name
so that we could set its properties on the code behind page.

Next I made the changes to the properties of the Ellipse on the code behind page. I
set the Fill property (again I apologize for any lack of graphic artistry), the Opacity,
Width, Height and because I didn't want to just have a flat Ellipse showing I added a
BitmapEffect.

The Opacity and BitmapEffect properties are the interesting ones here. By setting
the Opacity I can regulate how see through my ellipse is and the BitmapEffect has
added a beveled edge around the ellipse, just to add a little bit of depth to the graphic.
Now when the project is run you can see the ellipse on the form.

Next buttons are added to the XAML of thewindow again making sure that Names
are given to each one.

Then set the properties of the buttons on the code behind page.


The Height, Width and Content are set for both buttons as well as the VerticalAlignment
property. For the button that will exit the application the Forground property is set to
Red to have it stand out.
The last property that is assigned for the buttons is the Margin property which is used
to position the buttons where I wanted them on the form over the ellipse. Setting this
property was a little hit and miss as I was setting it via code so I could not see on the
form where the buttons were actually going to end up.

Now that I had the form looking like I wanted, all that was left was to be able to move
and position the window anywhere I wanted to put it, have music play when I clicked
the > button and to be able to quit the application.
To make the window move to a different position on the screen all that is required is
one small line of code in the MouseLeftButtonDown event of the window.

Now if the application is run and the left mouse button is held down you can move
the ellipse anywhere on your screen.
To close the application, just put the following code in the Click event of the close button.

The last thing to be done is to make music. (Thanks once again to Ged for pointing
out the pitfalls of playing music.)
(Admittedly there could be a whole lot more functionality to the application here to let,
for example, the user either enter or select a path and have the application play each
audio file in the directory one after the other, but that is more than I wanted to show
here. Maybe I will get to that in a future post.)
We start with adding the Imports Statement
Add a Variable to hold our instance of a media player
1 Dim MyPlayer As MediaPlayer
Lastly the code to play the music

So the complete XAML for the gadget is:
1 <Window Name="Win1" x:Class="Window1"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Neil's Gadget">
5 <Grid>
6 <Ellipse Name="Ellipse1" />
7 <Button Name="Button1">Button</Button>
8 <Button Name="Button2">Button</Button>
9 </Grid>
10 </Window>
and the complete code:
1 Imports System.Media
2 Class Window1
3 Dim MyPlayer As MediaPlayer
4 Private Sub Win1_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Win1.Initialized
5 With Win1.Height = 200
6 .Width = 200
7 .Background = Brushes.Transparent
8 .AllowsTransparency = True
9 .WindowStyle = Windows.WindowStyle.None
10 End With
11 With Ellipse1.Fill = Brushes.Tomato
12 .Opacity = 0.5
13 .Width = 150
14 .Height = 110
15 .BitmapEffect = New System.Windows.Media.Effects.BevelBitmapEffect
16 End With
17 With Button1.Height = 20
18 .Width = 20
19 .Content = "X"
20 .Foreground = Brushes.Red
21 .VerticalAlignment = Windows.VerticalAlignment.Center
22 .Margin = New Thickness(40, 70, 20, 20)
23 End With
24 With Button2.Height = 20
25 .Width = 20
26 .Content = ">"
27 .VerticalContentAlignment = Windows.VerticalAlignment.Center
28 .Margin = New Thickness(0, 70, 20, 20)
29 End With
30 End Sub
31
32
33 Private Sub Win1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Win1.MouseLeftButtonDown
34 Me.DragMove()
35 End Sub
36 Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
37 Me.Close()
38 End Sub
39 Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click
40 MyPlayer = New MediaPlayer
41 MyPlayer.Open(New Uri("symphony5_beethoven_radio3.mp3", UriKind.Relative))
42 MyPlayer.Play()
43 End Sub
How simple can it get?