Click here to Skip to main content
15,444,203 members
Articles / Desktop Programming / WPF
Posted 6 Mar 2009

Tagged as


51 bookmarked

WPF Gadget Container Control

Rate me:
Please Sign up or sign in to vote.
4.00/5 (13 votes)
6 Mar 2009CPOL3 min read
A Vista-styled gadget container control.



I recently had a requirement to create a Gadget-like control, similar to the desktop gadgets found in Vista and Windows 7. After years of lurking on CodeProject (and benefiting), I decided to post my results.


In researching this requirement, CodeProject was my first stop, where I found Josh Smith's excellent article on the DragCanvas (Dragging Elements in a Canvas). Josh provided the foundation of dragging UIElements around on a canvas, so I turned my attention to creating the actual Gadget control.

Using the code

I wanted a fairly generic container control which provided the look and feel and behaviour of a gadget, while allowing me to insert my own content in the form of a UserControl or custom control. After much deliberation, I decided on this control structure:


  • GadgetContainer – this is the custom control
  • PART_Gadget – this is a ContentControl which is used to host the gadget
  • PART_ControlBarGrid – this is a Grid control used to house gadget controls
  • PART_CloseButton – this is the button used to close or unload a gadget
  • PART_OptionButton – is the button used to provide settings or resizing functionality
  • Grip – provides the gripper bar for dragging the gadget

The SnapCanvas control is a modified version of Josh’s DragCanvas. The main difference is the SnapCanvas sets up “snap regions” running along the left, top, right, and bottom areas of the canvas. When dragging a gadget, if you cross the SnapThreshold (a property on the SnapCanvas which determines whether snapping should occur), the gadget will snap into place.


As you may have guessed, there is a strong relationship between the SnapCanvas and the GadgetContainer. I have included the SnapCanvas in the GadgetLibrary project, as the GadgetContainer is pretty much useless without it.

Because the SnapCanvas does the “snapping”, the GadgetContainer needs to know whether it’s been snapped. This is accomplished by implementing the IGadgetContainer interface:

namespace GadgetLibrary
     public interface IGadgetContainer
          SnapRegions SnapRegion { get; set; }

When the SnapCanvas snaps a gadget, it sets the SnapRegion property on the control. This is needed when the SnapCanvas is resized...

private void SnapCanvas_SizeChanged(object sender, SizeChangedEventArgs e)

SetSnapRectangles recalculates the snap regions based on the new size of the canvas. RelocateShappedContainers cycles through the children looking for IGadgetContainers that have been snapped, and relocates them accordingly.

The GadgetPrototype project includes a basic demonstration of how to use and wire-up the GadgetContainer. The sample gadgets included are useless and simply illustrate use.

In the Window1.xaml file, you will find:

<GadgetLibrary:SnapCanvas x:Name="_SnapCanvas"

SnapThreshold is set to 20 pixels, which feels right to me. The menu handler for the Add Gadget | Weather menu item looks like this:

private void _AddWeatherGadget_Click(object sender, RoutedEventArgs e)
    var gadgetContainer = new GadgetContainer();
    Canvas.SetTop(gadgetContainer, 100);
    Canvas.SetLeft(gadgetContainer, 100);
    gadgetContainer.OptionButtonType = OptionButtonTypes.Settings;
    gadgetContainer.Close += OnGadgetClose;
    var weatherGadget = new WeatherGadget();
    gadgetContainer.Gadget = weatherGadget;

So, we create a new GadgetContainer, set its Top and Left properties, set the OptionButtonType to OptionButtonTypes.Settings (Settings, Resize, and Other), create an event handler for the Close event and then, set the Gadget property to the WeatherGadget UserControl. And lastly, add it to the SnapCanvas' Children collection.

Responding to the OptionButton Click event

Just below the Close button in the ControlBar is the OptionButton. The OptionButton can serve different purposes depending on your gadget. Most commonly, it is used to launch a settings dialog window; in Windows 7, it can also resize or enlarge the gadget.

I wanted the gadget itself to respond to this event. I ended up doing this through the IGadget interface, which is implemented by the gadget.

public interface IGadget
    void OnShowOptions(OptionButtonTypes type);

When the OptionButton is clicked, the GadgetContainer will call the OnShowOptions method of the gadget.

In WeatherGadget.cs, we find:

public void OnShowOptions(OptionButtonTypes type)
        WeatherGadgetSettings settings = new WeatherGadgetSettings();

which displays a settings window for the gadget. The PictureGadget uses the Resize option, and very crudely resizes its contents in response to this event.

Points of interest

I think that’s pretty much all I have to say about this. I hope someone finds some use for it. As always with WPF, I’m sure there are better, more efficient ways of skinning this cat. Any and all comments/questions welcome.

More info


  • Version 1.0 posted on 6 March 2009.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer (Senior)
United Kingdom United Kingdom
I'm a software developer living in Northampton, UK, and enjoy working with the latest .Net technologies.

Comments and Discussions

QuestionCan gadget snap each other ? Pin
Cyril03515-Jun-16 10:27
MemberCyril03515-Jun-16 10:27 
GeneralMy vote of 5 Pin
Simon Raffl23-Jan-13 2:28
MemberSimon Raffl23-Jan-13 2:28 
QuestionHi Pin
Member 426405528-Mar-12 11:56
MemberMember 426405528-Mar-12 11:56 
AnswerRe: Hi Pin
Ron Gramann29-Mar-12 12:54
MemberRon Gramann29-Mar-12 12:54 
Hi Girish,
The gadgets included in the sample are not Windows gadgets, but replicate gadget-like components. Your application would need to supply the hosting canvas where the gadgets would reside. Your custom gadgets could access a database, since they are simply UserControls.

I'm not sure if that answers your question or not.


GeneralRe: Hi Pin
Member 42640553-Apr-12 16:52
MemberMember 42640553-Apr-12 16:52 
GeneralRe: Hi Pin
Ron Gramann4-Apr-12 8:06
MemberRon Gramann4-Apr-12 8:06 
QuestionI have the following error when moving an item thru the canvas ... Pin
s0m0s20-Sep-11 22:14
Members0m0s20-Sep-11 22:14 
Generalprevent minimizing the gadget [modified] Pin
Padmanabh Ganorkar12-Aug-10 12:19
MemberPadmanabh Ganorkar12-Aug-10 12:19 
GeneralRe: prevent minimizing the gadget Pin
Ron Gramann17-Aug-10 21:50
MemberRon Gramann17-Aug-10 21:50 
Generalnot a bad job, though it would be better if you had Pin
Sacha Barber6-Mar-09 21:04
MemberSacha Barber6-Mar-09 21:04 
GeneralRe: not a bad job, though it would be better if you had Pin
Ron Gramann7-Mar-09 0:03
MemberRon Gramann7-Mar-09 0:03 
GeneralRe: not a bad job, though it would be better if you had Pin
Sacha Barber7-Mar-09 0:50
MemberSacha Barber7-Mar-09 0:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.