Monthly Archives: July 2013

Localizable Balloon Tooltip Control

I wanted to create a tooltip in the style of the balloons used in Windows Phone apps like Messaging. Almost immediately, I realized it needed to be localizable, which would mean adjustable in width to accomodate text lengths in different languages.

In the past I’ve bound XAML elements, such as WPF menus to the ActualWidth of another element, e.g:

Width="{Binding ActualWidth, ElementName=window, Mode=Oneway}"

However, in this case I couldn’t get the desired result, which is to have a bit of padding on either side of the text. What documentation I read suggested that ActualWidth would take into account Margin settings. But I had to resort to a hack in the code-behind, adding a line to the constructor:

public MessageBoxControl()

TextGrid.Width = MsgText.ActualWidth + 16;

Here’s the XAML:

<UserControl x:Class="Controls.MessageBoxControl"
 FontFamily="{StaticResource PhoneFontFamilyNormal}"
 FontSize="{StaticResource PhoneFontSizeNormal}"
 Foreground="{StaticResource PhoneForegroundBrush}"
 d:DesignHeight="56" d:DesignWidth="440">

<Grid x:Name="LayoutRoot" Background="Transparent" IsHitTestVisible="False" Height="56"
 Width="{Binding ActualWidth, ElementName=TextGrid, Mode=OneWay}" MaxWidth="440">

 <RowDefinition Height="32" />
 <RowDefinition Height="24" />

<Grid Name="TextGrid" Background="#FFD68B" Grid.Row="0" MinWidth="200" MaxWidth="440">
 <TextBlock Name="MsgText" Foreground="#2368B0" FontSize="24" Height="32" MaxWidth="424"
 HorizontalAlignment="Center" TextTrimming="WordEllipsis"
 Text="{Binding Path=LocalizedResources.ResetMessage, Source={StaticResource LocalizedStrings}}"/>

<Grid Grid.Row="1">
 <Path Name="Tail" Fill="#FFD68B" Data="M-1,-1,24,24,24,-1,-1,-1"
 HorizontalAlignment="Left" Width="24" Height="24" Margin="24 0" />


Note that a MaxWidth is assigned to Grid and Text elements. Also, the TextTrimming attribute is set. This is meant to safeguard against exceeding the width of the display in Portrait mode. 

And a sample screen shot of a (hopefully accurate) French translation of “Hold to reset to 0:00”: