iPhone like red badge notification in a WPF project?

Use a Border element and place your text within it. You can set the CornerRadius property for the Border appropriately so that it looks like a circle (or a rounded-rectangle shape, in case the number is bigger).

Here's a first cut, which exploits the fact that CornerRadius will get clamped to half the height or width in Y and X respectively:

 <Border Background="Red" CornerRadius="999" Padding="4">
    <TextBlock Foreground="White" FontWeight="Bold" FontSize="12">125</TextBlock>
 </Border>

I recently had the same requirement, and quickly knocked this UserControl together. It uses a short animation to draw the user's attention to the badge.

Take a look at "Big Nick's" blog to see some elegant code for applying this UserControl to another UIElement as an Adorner (exactly what a 'badge' is!): http://blog.bignickolson.com/2009/10/15/overlaying-controls-in-wpf-with-adorners/

(Thanks Nick!)

alt text

<UserControl x:Class="BadgeControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Opacity="0.8"
              ClipToBounds="False"
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <Style TargetType="Label" x:Key="BadgeLabel">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="FontSize" Value="12" />
            <Setter Property="Height" Value="22" />
            <Setter Property="MinWidth" Value="22" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Label">
                        <Border Name="badgeOuterBorder" CornerRadius="10" BorderBrush="White" BorderThickness="2" Background="#C80103">
                            <Border.RenderTransform>
                                <!-- 
                                The TranslateTransform moves the badge so that when used as an Adorner, it bleeds over the upper left
                                edge of the adorned control.
                                The ScaleTransform ensures the badge is initially invisible on load ,
                                but gives the storyboard the ability to 'animate' it into visibility (by manipulating the ScaleTransform).
                                -->
                                <TransformGroup>
                                    <TranslateTransform X="-8" Y="-8"/>
                                    <ScaleTransform ScaleX="0" ScaleY="0" />
                                </TransformGroup>
                            </Border.RenderTransform>
                            <Border.BitmapEffect>
                                <!-- Give some depth to the badge with a drop-shadow -->
                                <DropShadowBitmapEffect Color="Black" Direction="270" ShadowDepth="3" Softness="0.2" Opacity="1"/>
                            </Border.BitmapEffect>
                            <Border CornerRadius="8" Padding="5 0 5 0">
                                <Border.Background>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" Opacity="0.8">
                                        <GradientStop Color="White" Offset="0" />
                                        <GradientStop Color="Transparent" Offset="0.6" />
                                    </LinearGradientBrush>
                                </Border.Background>
                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
                            </Border>
                        </Border>
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="Loaded">
                                <EventTrigger.Actions>
                                    <BeginStoryboard>
                                        <!--
                                        The following storyboard animates the ScaleTransform in both the X and Y planes, so that the
                                        badge appears to 'pop' into visibility.
                                        The 1 second delay ensures that the parent control is fully visible before the animation begins,
                                        otherwise, the animation may actually run before the form has rendered to the screen.
                                        -->
                                        <Storyboard>
                                            <DoubleAnimation
                                        Storyboard.TargetName="badgeOuterBorder"
                                        Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)"
                                        From="0"
                                        To="0.75"
                                        BeginTime="0:0:1"
                                        Duration="0:0:0.5">
                                                <DoubleAnimation.EasingFunction>
                                                    <BackEase Amplitude='1' EasingMode='EaseOut' />
                                                </DoubleAnimation.EasingFunction>
                                            </DoubleAnimation>
                                            <DoubleAnimation
                                        Storyboard.TargetName="badgeOuterBorder"
                                        Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleY)"
                                        From="0"
                                        To="0.75"
                                        BeginTime="0:0:1"
                                        Duration="0:0:0.5">
                                                <DoubleAnimation.EasingFunction>
                                                    <BackEase Amplitude='1' EasingMode='EaseOut' />
                                                </DoubleAnimation.EasingFunction>
                                            </DoubleAnimation>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger.Actions>
                            </EventTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </UserControl.Resources>

    <Grid HorizontalAlignment="Left" VerticalAlignment="Top"  ClipToBounds="False">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Name="d" ClipToBounds="False">
            <Label Style="{StaticResource BadgeLabel}" Content="Badge Text" ToolTip="Badge Tooltip" ClipToBounds="False" />
        </Grid>
    </Grid>
</UserControl>

This is based on Chris1 answer, but this will stretch correctly when the text inside the badge is longer than one digit, I've also set the font to make it more consistent across Windows versions, changed the sizing a bit to compensate and added an outline around the badge.

I've also replaced DropShadowEffect with a Rectangle, this is because I can't use DropShadowEffect in my specific application, DropShadowEffect looks better but my Rectangle shadow is good enough, you can delete the shadow rectangle and use DropShadowEffect if you like.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <Style TargetType="Label" x:Key="CircularLabel">
      <Setter Property="Foreground" Value="White" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontSize" Value="13" />
      <Setter Property="FontFamily" Value="Arial" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Label">
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
              <Rectangle Margin="0 3 0 -3" Fill="LightGray" 
                      RadiusX="11" RadiusY="11" Opacity="0.8"/>
              <Border CornerRadius="11"
                      BorderBrush="DarkGray"
                      BorderThickness="1">
                <Border
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center" CornerRadius="10"
                        Background="#FFC90000"
                        BorderBrush="White"
                        BorderThickness="2">
                  <Grid>
                    <ContentPresenter
                            HorizontalAlignment="Center" VerticalAlignment="Center"
                            Content="{TemplateBinding Content}" Margin="5 1 6 1"/>
                    <Rectangle x:Name="TopShine" RadiusX="9" RadiusY="9"
                            VerticalAlignment="Stretch">
                      <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" Opacity="0.6">
                          <GradientStop Color="White" Offset="0.2" />
                          <GradientStop Color="Transparent" Offset="0.7" />
                        </LinearGradientBrush>
                      </Rectangle.Fill>
                    </Rectangle>
                  </Grid>
                </Border>
              </Border>
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Page.Resources>
  <Grid>
    <UniformGrid>
      <Label Style="{StaticResource CircularLabel}">4</Label>
      <Label Style="{StaticResource CircularLabel}">100000</Label>
      <Label Style="{StaticResource CircularLabel}">CLICK HERE</Label>
    </UniformGrid>
  </Grid>
</Page>

Tags:

C#

Wpf

Styles