Karsten wrote a great sample on getting a gadget working in Windows Presentation Foundation. Unfortunately if you are starting from scratch there are a lot of pieces needed to get this working ; so i thought i would rewrite his sample in VB -and supply a set of simple 1-2-3 how to directions.
Step one:
Create a Windows Presentation Foundation User Control to be displayed in your Windows Side bar gadget.
Keeping mine really simply; just a button that pulses:
<UserControl x:Class="UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><UserControl.Resources><Storyboard x:Key="Timeline1"><ColorAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="button" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)"><SplineColorKeyFrame Value="#FFCDCDCD" KeyTime="00:00:00"/><SplineColorKeyFrame Value="#FFB92121" KeyTime="00:00:01"/><SplineColorKeyFrame Value="#FF2921B9" KeyTime="00:00:02"/></ColorAnimationUsingKeyFrames></Storyboard></UserControl.Resources><UserControl.Triggers><EventTrigger RoutedEvent="FrameworkElement.Loaded"><BeginStoryboard Storyboard="{StaticResource Timeline1}"/></EventTrigger><EventTrigger RoutedEvent="FrameworkElement.Loaded"/></UserControl.Triggers><Grid> <Button x:Name="button">WPF</Button> </Grid></UserControl>
<UserControl x:Class="UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><UserControl.Resources><Storyboard x:Key="Timeline1"><ColorAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="button" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)"><SplineColorKeyFrame Value="#FFCDCDCD" KeyTime="00:00:00"/><SplineColorKeyFrame Value="#FFB92121" KeyTime="00:00:01"/><SplineColorKeyFrame Value="#FF2921B9" KeyTime="00:00:02"/></ColorAnimationUsingKeyFrames></Storyboard></UserControl.Resources><UserControl.Triggers><EventTrigger RoutedEvent="FrameworkElement.Loaded"><BeginStoryboard Storyboard="{StaticResource Timeline1}"/></EventTrigger><EventTrigger RoutedEvent="FrameworkElement.Loaded"/></UserControl.Triggers><Grid>
<Button x:Name="button">WPF</Button>
</Grid></UserControl>
Step Two:
Create a Windows Control to Host the Windows Presentation Control.
Since you can not host WPF Control directly in Internet Explorer we need a Windows Control to do this. After creating the Windows Control set the register for COM interop on the compile tab of your Windows Control Project Properties.
Add refrences to the assemblies and namespaces namely:
The next thing needed is to import in the Runtime.InteropServices and Windows Presentation Foundation name spaces:
Imports System.Runtime.InteropServices Imports System.Windows.Forms.Integration
Imports System.Runtime.InteropServices
Imports System.Windows.Forms.Integration
Set the classid of the Windows Control to match the one requested in the Object tag above:
<ProgId("Thanks.KarstenJ"), _GuidAttribute("AF52C145-235E-4604-B18A-E5B77080B15F"), _ComVisible(True)> _
Create an instance of the WPF Control
Dim ctrlHost As ElementHostDim ctl As CustomControlLibrary1.UserControl1
Finally host the WPF Control on the Windows Control Surface.
ctrlHost = New ElementHost()ctrlHost.Dock = DockStyle.Fillctl = New CustomControlLibrary1.UserControl1()ctl.InitializeComponent()ctrlHost.Child = ctlMe.Controls.Add(ctrlHost)
So the entire Windows Control looks like:
Imports System.Windows.Forms.IntegrationImports System.Runtime.InteropServices <ProgId("Thanks.KarstenJ"), _GuidAttribute("AF52C145-235E-4604-B18A-E5B77080B15F"), _ComVisible(True)> _Public Class UserControl1 Dim ctrlHost As ElementHostDim ctl As CustomControlLibrary1.UserControl1 Private Sub UserControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadctrlHost = New ElementHost()ctrlHost.Dock = DockStyle.Fillctl = New CustomControlLibrary1.UserControl1()ctl.InitializeComponent()ctrlHost.Child = ctlMe.Controls.Add(ctrlHost)End SubEnd Class
Imports System.Windows.Forms.IntegrationImports System.Runtime.InteropServices
<ProgId("Thanks.KarstenJ"), _GuidAttribute("AF52C145-235E-4604-B18A-E5B77080B15F"), _ComVisible(True)> _Public Class UserControl1
Private Sub UserControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadctrlHost = New ElementHost()ctrlHost.Dock = DockStyle.Fillctl = New CustomControlLibrary1.UserControl1()ctl.InitializeComponent()ctrlHost.Child = ctlMe.Controls.Add(ctrlHost)End SubEnd Class
Step Three:
Create a gadget to host the Windows Control.
To make life easier on myself I started with the clock gadget and simply copied the whole directory to NewGadget.Gadget directory and opened this directory in Visual Studio as a file based website. I then changed the Clock.HTML; starting with the Head tag to set the size appropriate for a gadget:
<style>body { width:100;height:100; margin:0px; }</style>
Then set the body of the HTML to render the Windows Control. This accomplised by using an object tag outlined in the KB article: COM-Callable .NET Controls in Internet Explorer. The clsid was generated with GuidGen and needs to be the same as the Guild specified by the Windows Control.
<object id="Id_name" classid="clsid:AF52C145-235E-4604-B18A-E5B77080B15F"height="150"width="130" style="background-color:Transparent;"> </object>
The ENTIRE Clock.HTML Page now looks like:
<html><head><style>body { width:100;height:100; margin:0px; }</style></head><body><object id="Id_name" classid="clsid:AF52C145-235E-4604-B18A-E5B77080B15F"height="150"width="130" style="background-color:Transparent;"> </object></body></html>
To determine this gadget versus the real clock gadget you should also change the gadget.xml name tag from
<name>Clock</name>
To something like
<name>WPF</name>
Viola, go into Vista add the Windows Sidebar gadget and you should see a button pulsing from WPF!