2

我的 silverlight 应用程序中有一个功能区栏,我希望在其中一个图标上有一个徽章图标,显示图标激活的视图中的项目数。
想象一下 OS X 中的 Mail 图标,显示未读消息的数量或 IOS 应用程序图标上的通知计数器。

我对 xaml 样式了解不多,但在我看来,我可以复制功能区栏按钮的默认样式,然后添加某种红色圆圈和一个白色文本,该文本从一个新的功能区栏按钮上的属性,所以我可以绑定到它。

有没有人有这样的例子我可以开始?


感谢肖恩的回答。这就是我最终要做的:
在 xaml 中:

<telerikRibbonBar:RadRibbonRadioButton
    Text="Expired Active   Call Factors"
    Size="Large"
    LargeImage="/CallFactorDatabase.UI;component/Images/Ribbon/Large/ExpiredActiveView.png"
    Command="{Binding ActivateViewCommand}"
    CommandParameter="ExpiredActiveView">
    <Grid>
        <Grid.Resources>
            <converters:BooleanToVisibilityConverter x:Key="visibleWhenTrueConverter" VisibilityWhenTrue="Visible" VisibilityWhenFalse="Collapsed" />
        </Grid.Resources>
        <Grid Width="27" Height="27" Visibility="{Binding ExpiredActiveCallFactors, Converter={StaticResource visibleWhenTrueConverter}}" Margin="50,-40,0,0">
            <Ellipse Fill="Black" Width="27" Height="27"/>
            <Ellipse Width="25" Height="25" VerticalAlignment="Center" HorizontalAlignment="Center">
                <Ellipse.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="Coral" Offset="0.0" />
                        <GradientStop Color="Red" Offset="1.0" />
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Viewbox Width="25" Height="25" VerticalAlignment="Center" HorizontalAlignment="Center" >
                <TextBlock Text="{Binding ExpiredActiveCallFactorsCount}" Foreground="White"/>
            </Viewbox>
        </Grid>
    </Grid>
</telerikRibbonBar:RadRibbonRadioButton>

它的外观:
在此处输入图像描述

没有运气把它放在功能区按钮前面,但是哦,好吧。

4

2 回答 2

4

这可以通过一些绑定和一个可选的值转换器来完成。此示例假定您绑定到具有 Items 属性的模型,并且该属性的类型为 ObservableCollection,以便在添加/删除项目时,集合的 Count 属性将触发属性更改。

<Grid>
    <Grid.Resources>
        <local:CountToVisbilityConverter x:Key="CountToVis"/>
    </Grid.Resources>
    ....
    <Grid Width="25" Height="25" Visibility="{Binding Items.Count, Converter=CountToVis}">
        <Ellipse Fill="Red" Width="25" Height="25"/>
        <ViewBox Width="25" Height="25">
            <TextBlock Text="{Binding Itmes.Count}" Foreground="White"/>
        </Viewbox>
    </Grid>
</Grid>

和价值转换器:

public class CountToVisibilityConverter : IValueConverter
{

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value == null) return Visibility.Collapsed;

        int count = System.Convert.ToInt32(value);
        return count == 0 ? Visibility.Collapsed : Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

我看到可选”转换器的原因是因为您也可以像这样使用交互数据触发器

    <Grid x:Name="UnreadNotification" Width="25" Height="25">
        <Ellipse Fill="Red" Width="25" Height="25"/>
        <ViewBox Width="25" Height="25">
            <TextBlock Text="{Binding Itmes.Count}" Foreground="White"/>
        </Viewbox>
    </Grid>
    <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding Items.Count, Comparison="Equal"
                    Value="0">
            <ei:ChangePropertyAction PropertyName="IsEnabled"
                                 Value="True"
                                 TargetName="UnreadNotification" />
        </ei:DataTrigger>
    </i:Interaction.Triggers>
于 2012-04-27T05:12:43.990 回答
3

这是我的解决方案。默认情况下,徽章将显示在右上角。您可以通过设置“BadgeMarginOffset”属性来更改此设置。我附上了几张图片来展示它的外观。一,它显示了包装 Telerik RadRibbonButton 的徽章。您还可以更改徽章的背景和前景颜色(BadgeBackground、BadgeForeground)。默认值如下所示。

使用 BadgeMarginOffset

没有 BadgeMarginOffset

Telerik RadRibbonButton

UserControl 的 XAML

<UserControl x:Class="Foundation.Common.Controls.Wpf.Badge"
         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"
         xmlns:converters="clr-namespace:Foundation.Common.Controls.Wpf.Converters"
         Background="Transparent" x:Name="UserControl"
         mc:Ignorable="d" >
<UserControl.Resources>
    <converters:GreaterThanZeroBooleanConverter x:Key="GreaterThanZeroBooleanConverter" />
    <converters:GreaterThanZeroVisibilityConverter x:Key="GreaterThanZeroVisibilityConverter"/>
</UserControl.Resources>
<UserControl.Template>
    <ControlTemplate>
        <Grid HorizontalAlignment="Stretch" >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Border CornerRadius="10"  
                    UseLayoutRounding="True"
                    x:Name="BadgeBorder"
                    Grid.ZIndex="99"
                    VerticalAlignment="Top"
                    HorizontalAlignment="Right"
                    Visibility="{Binding ElementName=UserControl, Path=Count, Mode=TwoWay, Converter={StaticResource GreaterThanZeroVisibilityConverter}}"
                    Grid.Row="0"
                    Margin="{Binding ElementName=UserControl, Path=BadgeMarginOffset}"
                    Height="22"
                    Padding="6.7,2,7,3" 
                    Background="{Binding ElementName=UserControl, Path=BadgeBackground}">
                <Border.Style>
                    <Style TargetType="Border">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=UserControl, Path=Count, Mode=TwoWay, Converter={StaticResource GreaterThanZeroBooleanConverter}}" Value="True">
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation From="0.0"
                                                             To="1.0"
                                                             Duration="0:0:0.7"
                                                             Storyboard.TargetProperty="Opacity"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.EnterActions>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding ElementName=UserControl, Path=ShowDropShadow}" Value="True">
                                <Setter Property="Effect">
                                    <Setter.Value>
                                        <DropShadowEffect BlurRadius="6" ShadowDepth="4" Color="#949494"/>
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <TextBlock Text="{Binding ElementName=UserControl, Path=Count}"
                           Foreground="{Binding ElementName=UserControl, Path=BadgeForeground}"
                           FontWeight="Bold"
                           FontSize="12">
                </TextBlock>
            </Border>
            <ContentPresenter Grid.Row="0" 
                              Grid.RowSpan="2"
                              DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"
                              Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
        </Grid>
    </ControlTemplate>
</UserControl.Template>

UserControl背后的代码

public partial class Badge : UserControl
{
    #region Dependency Properties

    public static readonly DependencyProperty CountProperty =
        DependencyProperty.Register("Count", typeof(int), typeof(Badge));

    public static readonly DependencyProperty ShowDropShadowProperty =
        DependencyProperty.Register("ShowDropShadow", typeof(bool), typeof(Badge), new PropertyMetadata(true));

    public static readonly DependencyProperty BadgeMarginOffsetProperty =
        DependencyProperty.Register("BadgeMarginOffset", typeof(Thickness), typeof(Badge));

    public static readonly DependencyProperty BadgeBackgroundProperty =
        DependencyProperty.Register("BadgeBackground", typeof(Brush), typeof(Badge), new PropertyMetadata(Brushes.Red));

    public static readonly DependencyProperty BadgeForegroundProperty =
        DependencyProperty.Register("BadgeForeground", typeof(Brush), typeof(Badge), new PropertyMetadata(Brushes.White));

    #endregion Dependency Properties

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="Badge"/> class.
    /// </summary>
    public Badge()
    {
        this.InitializeComponent();
    }

    #endregion Constructor

    #region Properties

    /// <summary>
    /// Gets or sets a value indicating whether [show drop shadow].
    /// </summary>
    /// <value>
    ///   <c>true</c> if [show drop shadow]; otherwise, <c>false</c>.
    /// </value>
    public bool ShowDropShadow
    {
        get => (bool)this.GetValue(ShowDropShadowProperty);
        set => this.SetValue(ShowDropShadowProperty, value);
    }

    /// <summary>
    /// Gets or sets the badge margin offset.
    /// </summary>
    /// <value>
    /// The badge margin offset.
    /// </value>
    public Thickness BadgeMarginOffset
    {
        get => (Thickness)this.GetValue(BadgeMarginOffsetProperty);
        set => this.SetValue(BadgeMarginOffsetProperty, value);
    }

    /// <summary>
    /// Gets or sets the badge background.
    /// </summary>
    /// <value>
    /// The badge background.
    /// </value>
    public Brush BadgeBackground
    {
        get => (Brush)this.GetValue(BadgeBackgroundProperty);
        set => this.SetValue(BadgeBackgroundProperty, value);
    }

    /// <summary>
    /// Gets or sets the badge foreground.
    /// </summary>
    /// <value>
    /// The badge foreground.
    /// </value>
    public Brush BadgeForeground
    {
        get => (Brush)this.GetValue(BadgeForegroundProperty);
        set => this.SetValue(BadgeBackgroundProperty, value);
    }

    /// <summary>
    /// Gets or sets the count.
    /// </summary>
    /// <value>
    /// The count.
    /// </value>
    public int Count
    {
        get => (int)this.GetValue(CountProperty);
        set => this.SetValue(CountProperty, value);
    }

    #endregion Properties
}

前两张图片的示例代码

<wpf:Badge Count="108" Margin="20" HorizontalAlignment="Left" BadgeMarginOffset="0,-5,-5,0">
    <Button Height="100" Width="100">
        <Button.Content>
            <Image Source="Resources/about.png" />
        </Button.Content>
    </Button>
</wpf:Badge>
于 2018-05-03T13:40:37.430 回答