Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  Framework 3.5  »  Creating a ComboBox with Individual ToolTips for each Item
 »  Home  »  .NET Intermediate  »  Creating a ComboBox with Individual ToolTips for each Item
 »  Home  »  Windows Development  »  Interop  »  Creating a ComboBox with Individual ToolTips for each Item
 »  Home  »  Windows Development  »  Windows Presentation Foundation  »  Creating a ComboBox with Individual ToolTips for each Item
Creating a ComboBox with Individual ToolTips for each Item
by Ged Mead | Published  02/24/2010 | Framework 3.5 .NET Intermediate Interop Windows Presentation Foundation | Rating:
Ged Mead

Ged Mead (XTab) is a Microsoft Visual Basic MVP who has been working on computer software and design for more than 25 years. His journey has taken him through many different facets of IT. These include training as a Systems Analyst, working in a mainframe software development environment, creating financial management systems and a short time spent on military laptop systems in the days when it took two strong men to carry a 'mobile' system.

Based in an idyllic lochside location in the West of Scotland, he is currently involved in an ever-widening range of VB.NET, WPF and Silverlight development projects. Now working in a consultancy environment, his passion however still remains helping students and professional developers to take advantage of the ever increasing range of sophisticated tools available to them.

Ged is a regular contributor to forums on vbCity and authors articles for DevCity. He is a moderator on VBCity and the MSDN Tech Forums and spends a lot of time answering technical questions there and in several other VB forum sites. Senior Editor for DevCity.NET, vbCity Developer Community Leader and Admin, and DevCity.NET Newsletter Editor. He has written and continues to tutor a number of free online courses for VB.NET developers.

 

View all articles by Ged Mead...
Interop with a WPF UserControl

Introduction
This came up as a Windows Forms question a short while ago.   Someone wanted to create a data bound ComboBox and have a relevant tooltip appear whenever the user hovered any of the items in the list.  The strings for the tooltips would be stored in the database along with all the other data.

I’ve seen the proposed WinForms way of creating this result and, although I‘m sure it works fine, it really did look like a very complicated way of solving a relatively simple request.   My immediate reaction was to think that there is probably an easy way of producing this result in WPF and hosting the resulting ComboBox-With-Tooltip control inside a Windows Form.

As it turned out, this is easily achievable with a very small amount of XAML .  I did have an annoying little problem at one stage and made a rather strange discovery which I’ll describe later.  Here’s the end result of the ComboBox:

 

The above screenshot is from a WPF application, but the task requires for the ComboBox to be hosted in a Windows Forms application, so let’s deal with that first.

 

Setting Up the Windows Forms Project
Start a new Windows Forms Application.  In Form1, add some WinForms controls of your choice.  I have added three buttons.  They have no functionality and I only include them to emphasise that you can have WinForms and WPF hosted content in the same Form.

 

ComboWithTips004

 

If you are using VB 2008 Express Edition, you should find a tab named ‘WPF Interoperability’ in the Toolbox.  Inside this tab there will be control named ElementHost. 

ComboWithTips005

 

This tab may not be available in other editions.  In the Pro edition, for example, you will need to add the ElementHost to the toolbox in the usual way:

 

ComboWithTips005

 

Drag this control from the Toolbox and drop it on to your Form. 

 

 

The smart tag will invite you to select the hosted content (currently set to none).  As you haven’t created the content yet, just click anywhere on the Form’s surface to close the smart tag dialog box.

Add a WPF UserControl
To add a WPF UserControl to the Windows Forms project, Select Project > Add New Item… from the IDE main menu.  

 

In the Add New Item dialog which appears, select WPF from the categories list, then click on User Control (WPF).   Assign a name of your choice to this new user control.

 

 

Adding this WPF User Control automatically causes some new References to be added to your project – most notably PresentationCore and PresentationFramework.  These are core WPF namespaces.  If you select the UserControl by double clicking on it in the Solution Explorer, you will see that the Toolbox has now changed and you are offered a list of WPF controls instead of the Windows Forms ones. 

Create the UserControl Content
Resize the UserControl boundaries so that it measures 100 x 70.   You can do this in the XAML pane:

<UserControl x:Class="ComboWithToolTips"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="100" Height="70">

 

Or in the Properties pane.  The screenshot shows the Height setting.  The Width property is also available, although the WPF Properties pane doesn’t offer you the Size property you may be used to in Windows Forms:

 

Drag a WPF ComboBox on to the surface of the WPF UserControl.  It will be given some default values, not all of which suit our purposes, so manually change the XAML for the ComboBox so that it looks like the following:

    <ComboBox Height="23" HorizontalAlignment="Left" 

       Name="ComboPerson" VerticalAlignment="Top" Width="100" />

 

The UserControl should now look like this in the Design Pane:

 

Assign the UserControl to the Windows Forms ElementHost
Now that you have a UserControl built, you can assign this to the ElementHost previously added to the Windows Form.

Rebuild the project to ensure that the UserControl is fully built.   Select the Windows Form and click on the ElementHost.  Click on the smart tag arrowhead and you will see the ElementHost Tasks dialog.

Click on the dropdown arrow at the right hand side of the ‘Select Hosted Content’ combo and you will see that the new UserControl has now been added to the list.

 

  Select this control, then click anywhere on the Form to close the smart tag dialog.  You will probably see an exclamation mark icon inside the ElementHost, possibly with some additional text, depending on the size of the host.   Although this may make you think there is a problem, the UserControl will in fact display OK at run time.   If you want to test things so far you can hit F5.   The WPF ComboBox will be visible and will drop down when its arrow is clicked  Of course as we haven’t bound the data yet or finished the look of the ComboBox there will be nothing to see.

Add a Data Source to the Application
The demonstration data that will be displayed in the ComboBox is provided by a simple class named ‘Person’.   The class has three properties – FullName, Status and Category – although we only use two of these in the ComboBox.  The class contains a function which creates a List of Type Person.  You can of course use any data source you want, as long as it has at least two properties defined – one to populate the ComboBox list and one to be used as the ToolTip.   Here is the class definition I have used:

 

Imports System.ComponentModel

Imports System.Collections.ObjectModel

 

Public Class Person

    Implements INotifyPropertyChanged

 

    Sub New(ByVal personname As String, ByVal personstatus As String, ByVal personsgroup As String)

        Me.FullName = personname

        Me.Status = personstatus

        Me.Category = personsgroup

    End Sub

 

    Private _name As String

    Public Property FullName() As String

        Get

            Return _name

        End Get

        Set(ByVal value As String)

            _name = value

            OnPropertyChanged(New PropertyChangedEventArgs("FullName"))

        End Set

    End Property

 

    Private _status As String

    Public Property Status() As String

        Get

            Return _status

        End Get

        Set(ByVal value As String)

            _status = value

            OnPropertyChanged(New PropertyChangedEventArgs("Status"))

        End Set

    End Property

 

    Private _Category As String

    Public Property Category() As String

        Get

            Return _Category

        End Get

        Set(ByVal value As String)

            _Category = value

            OnPropertyChanged(New PropertyChangedEventArgs("Category"))

        End Set

    End Property

 

    Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)

        If Not PropertyChangedEvent Is Nothing Then

            RaiseEvent PropertyChanged(Me, e)

        End If

    End Sub

 

 

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

 

 

    Public Shared Function GetPersons() As List(Of Person)

        Dim GP As New List(Of Person)

        GP.Add(New Person("Neil Birch", "Available", "My Friends"))

        GP.Add(New Person("Joe Brown", "On Site", "Work Colleagues"))

        GP.Add(New Person("Larry Blake", "Available", "VB City"))

        GP.Add(New Person("Fran Mead", "At Work", "Family"))

        GP.Add(New Person("Elaine Javan", "On Vacation", "Work Colleagues"))

        GP.Add(New Person("Matt Higginbotham", "On Line", "VB City"))

        GP.Add(New Person("Zoe Flint", "On Site", "Work Colleagues"))

        Return GP

    End Function

 

End Class

I’m not going to look  at this class in detail because it isn’t really part of the ‘ComboBox with ToolTips’ concept.  As I’ve mentioned, it doesn’t matter how you get the data, so long as it has two public properties you can use.  

The GetPersons function at the bottom of the code generates a List of 7 Person objects.   This function is called from the code-behind of the WPF UserControl:

 

Partial Public Class ComboWithToolTips

    Dim ComboData As New List(Of Person)

 

    Private Sub ComboWithToolTips_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        ComboData = Person.GetPersons

        Me.DataContext = ComboData

    End Sub

End Class

The code snippet above creates an empty List (Of Person).  When the user control is loaded, it then accesses the GetPersons function in the Person Class and populates that ComboData List with the details of the seven Persons.   The final code line sets the DataContext of the user control to that List.   This automatically links all the data in that List to any control or element inside the user control that wishes to be bound to it.  You will see this data binding in action next.

Sponsored Links