iPhone как красный значок уведомления в проекте WPF? - PullRequest
8 голосов
/ 11 января 2010

У меня есть проект C # WPF, который автоматически генерирует ежедневные и еженедельные отчеты. Я хочу информировать пользователя о появлении новых отчетов, поэтому я подумал о значке, похожем на iPhone, где количество новых сообщений отображается в маленьком красном круге: alt text

Я подумал о трех изображениях: два изображения с полукругами слева и справа, если число для отображения небольшое. И третье изображение для середины для случая, когда число большое (123) и не помещается в круг. alt text

Я хочу глянцевый эффект, поэтому я подумал о картинках. У кого-нибудь есть хорошая идея, как сделать это без картинок, но программно?

Ответы [ 5 ]

17 голосов
/ 11 января 2010

Используйте элемент Border и поместите в него текст. Вы можете установить свойство CornerRadius для Границы соответствующим образом, чтобы оно выглядело как круг (или прямоугольник с закругленными углами, если число больше).

Вот первый разрез, который использует тот факт, что CornerRadius будет зажат до половины высоты или ширины в Y и X соответственно:

 <Border Background="Red" CornerRadius="999" Padding="4">
    <TextBlock Foreground="White" FontWeight="Bold" FontSize="12">125</TextBlock>
 </Border>
7 голосов
/ 03 сентября 2010

У меня недавно было то же самое требование, и я быстро собрал этот UserControl. Он использует короткую анимацию, чтобы привлечь внимание пользователя к значку.

Загляните в блог «Большого Ника», чтобы увидеть элегантный код для применения этого пользовательского элемента управления к другому элементу UIE в качестве Adorner (именно таков «значок»!) http://blog.bignickolson.com/2009/10/15/overlaying-controls-in-wpf-with-adorners/

(Спасибо, Ник!)

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>
2 голосов
/ 19 апреля 2010

Это основано на ответе Chris1, но оно будет правильно растягиваться, когда текст внутри значка длиннее одной цифры, я также установил шрифт, чтобы сделать его более согласованным в версиях Windows, немного изменил размер, чтобы компенсировать и добавил контур вокруг значка.

Я также заменил DropShadowEffect на Rectangle, потому что я не могу использовать DropShadowEffect в моем конкретном приложении, DropShadowEffect выглядит лучше, но моя тень Rectangle достаточно хороша, вы можете удалить прямоугольник с тенью и использовать DropShadowEffect, если хотите ,

<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>
0 голосов
/ 19 апреля 2010

Вот мой пример, он не идеален, но выглядит достаточно хорошо.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <DropShadowEffect x:Key="ShadowEffect" Direction="270" BlurRadius="5" ShadowDepth="3"/>
        <Style TargetType="Label" x:Key="CircularLabel">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="FontSize" Value="12" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Label">
                        <Grid>
                            <Rectangle HorizontalAlignment="Center" VerticalAlignment="Center" Width="20" Height="20" Fill="#FFC90000" RadiusX="10" RadiusY="10" Stroke="White" StrokeThickness="2" Effect="{StaticResource ShadowEffect}" />
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
                            <Rectangle x:Name="TopShine" RadiusX="10" RadiusY="10" Width="20" Height="20" StrokeThickness="2">
                                <Rectangle.Fill>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" Opacity="0.8">
                                        <GradientStop Color="White" Offset="0" />
                                        <GradientStop Color="Transparent" Offset="0.6" />
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
  </Page.Resources>
  <Grid>  
    <Label Style="{StaticResource CircularLabel}">1</Label>
  </Grid>
</Page>
0 голосов
/ 11 января 2010

Для глянцевых кнопок существует множество обучающих программ по WPF. По сути, создайте обычную кнопку и используйте комбинацию эффектов и градиентов, чтобы изменить шаблон элемента управления кнопки, чтобы он выглядел как кнопка iPhone. Это пример, но вы можете сделать гораздо больше: http://craig.palenshus.com/silverlight/silverlight-and-the-content-presenter-in-an-iphone-like-button/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...