Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  Framework 3.5  »  Creating a ComboBox with Individual ToolTips for each Item  »  DataBinding and DataTemplate
 »  Home  »  .NET Intermediate  »  Creating a ComboBox with Individual ToolTips for each Item  »  DataBinding and DataTemplate
 »  Home  »  Windows Development  »  Interop  »  Creating a ComboBox with Individual ToolTips for each Item  »  DataBinding and DataTemplate
 »  Home  »  Windows Development  »  Windows Presentation Foundation  »  Creating a ComboBox with Individual ToolTips for each Item  »  DataBinding and DataTemplate
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...
DataBinding and DataTemplate

DataBinding and DataTemplate

Now that we have a data source – the DataContext – the ComboBox can be bound to it.  The syntax is very simple and requires only that you point the ItemsSource property of the ComboBox to the Binding.

     ItemsSource="{Binding}"

The word ‘Binding’ is placed inside the curly braces to signify that this is a markup extension in XAML. 

If you were to run the project now you would actually have some bound data.   However, it isn’t yet in a format that is useful to  users:

 

 

This will be an issue you are familiar with if you have done data binding in the past.  At this stage, all that is capable of being displayed is the ToString representation of the  Person instances.   Without more detailed instructions, the application has no way of knowing which specific part(s) of the data should be listed in the ComboBox.    The easiest way of doing this is to create a DataTemplate for the ComboBoxItems. 

You make this as plain or fancy as you like.  For demo purposes I have just placed the string representation of the FullName property in a TextBlock and then surrounded this with a Border.

Here is the XAML used to create the first part of the DataTemplate, which I’ve placed in the Resources collection of the Grid:

    <Grid.Resources>

      <DataTemplate x:Key="StatusToolTip">

        <TextBlock Text="{Binding Path=FullName}">

 

        </TextBlock>

      </DataTemplate>

    </Grid.Resources>

The TextBlock is bound to the FullName property of those Person instances.

The next step is to point the ItemTemplate property of the ComboBox to this DataTemplate, which has a Key named StatusToolTip.  The final version of the markup for the ComboBox looks like this:

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

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

       ItemsSource="{Binding}"               

       ItemTemplate="{StaticResource StatusToolTip}"/>

 

Running the application again will produce the list of names in the ComboBox:

 

 

All that remains to do is to add a ToolTip to the TextBlock:

        <TextBlock.ToolTip>

            <Border BorderBrush="Navy" BorderThickness="2"

               CornerRadius="4">

                <TextBlock Text="{Binding Path=Status}" Margin="3"/>

            </Border>

        </TextBlock.ToolTip>

 

This time the Binding Path points to the Status property of those Person instances.

Now when the application runs and the mouse hovers over the name of a Person, the ToolTip showing the status of that Person will display:

 

 

Here is the complete XAML for the UserControl:

<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">

    <Grid Height="70">

    <Grid.Resources>

      <DataTemplate x:Key="StatusToolTip">

        <TextBlock Text="{Binding Path=FullName}">

        <TextBlock.ToolTip>

            <Border BorderBrush="Navy" BorderThickness="2"

               CornerRadius="4">

                <TextBlock Text="{Binding Path=Status}" Margin="3"/>

            </Border>

        </TextBlock.ToolTip>

        </TextBlock>

      </DataTemplate>

    </Grid.Resources>

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

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

       ItemsSource="{Binding}"               

       ItemTemplate="{StaticResource StatusToolTip}"/>

  </Grid>

</UserControl>

The glitch that caught me out was that I thought it would be logical to use a ComboBoxItem in the DataTemplate and have a TextBlock inside that ComboBoxItem.   However when I did that, the names and the ToolTips would appear,  but the ComboBox wouldn’t collapse if the user clicked on the actual name.   The mouse had to be clicked on a blank area anywhere to the right of the name.  This obviously would be confusing and unacceptable to most users, so I had to get some outside help on this - Thanks, Sirga and Jie Wang for showing me the workaround.     Surprisingly, it turns out that if you include a ComboBoxItem in the DataTemplate then it stops working correctly in this kind of scenario.   The markup above will cause the ToolTip to display whenever the mouse hovers over a name (that is specifically the string representation of the name, but not any of the blank space to the right on the line).

If you want the ToolTip to appear, no matter where on the ComboBox line the mouse hovers, then this alternative markup will produce the desired result:

    <Grid Height="70">

    <Grid.Resources>

      <DataTemplate x:Key="StatusToolTip">

        <TextBlock Text="{Binding Path=FullName}" />

      </DataTemplate>

 

       <Border x:Key="ToolTipContent" BorderBrush="Navy"

           BorderThickness="2"  CornerRadius="4">

        <TextBlock Text="{Binding Path=Status}" Margin="3"/>

      </Border>

    </Grid.Resources>

 

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

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

       ItemsSource="{Binding}"               

       ItemTemplate="{StaticResource StatusToolTip}">

     <ComboBox.ItemContainerStyle>

        <Style TargetType="{x:Type ComboBoxItem}">

          <Setter Property="ToolTip" Value="{StaticResource ToolTipContent}" />

        </Style>

      </ComboBox.ItemContainerStyle>

    </ComboBox>

  </Grid>

 

As the highlighting shows, The ToolTip has been pulled out of the DataTemplate.   The Border and TextBlock that comprise the ToolTip visuals are stored as a Resource and given a Key.  This keyed resource is then used directly in the ComboBox’s ItemContainerStyle to style the individual ComboBoxItems.

Apart from my little tussle with the ComboBoxItem template, this was a very easy solution overall.   A few lines of XAML together with the use of an ElementHost in the Windows Form and the job’s done.   Another good example of how WPF and Windows Forms Interop can help achieve GUI enhancements more easily than trying to hack or extend WinForms controls.

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:3.18461538461537 out of 5
 65 people have rated this page
Article Score21039
Sponsored Links