【问题标题】:Add unread notification to wpf microsoft ribbonbutton image将未读通知添加到 wpf microsoftribbonbutton 图像
【发布时间】:2014-09-02 12:42:03
【问题描述】:

我想问与Coxy 相同的问题:我想在 RibbonButton 的图像上显示未读项目的数量。

例子:

我可以在不修改整个模板的副本的情况下做到这一点吗?我再次问同样问题的原因是我使用的是 Microsoft Ribbon 控件,Coxy question 给出的解决方案只能应用于 Telerik 的 Ribbon 控件。

【问题讨论】:

  • 您是否考虑过使用装饰器? djfr.wordpress.com/2012/03/30/…
  • 我想问和Coxy一样的问题...为什么?我们不喜欢这个网站上的重复问题......是什么让这个不同的问题足以不作为重复而关闭?我看不出你有什么理由不能听从另一个问题的答案。
  • Coxy 正在使用来自 telerik 的功能区,您无法将相同的解决方案应用于 Microsoft 功能区。谢里登下次尽量礼貌一点。
  • Martin,为什么你认为这只适用于 Teleric Ribbon Button?您只需编辑 WPF 功能区按钮的 ControlTemplate

标签: wpf ribbon-control


【解决方案1】:

我在答案中添加了这个,因为它太长了,无法发表评论。

我访问了 Microsoft 下载站点并从 here 下载了功能区控件的源代码。包含所有触发器的完整模板都在其中。我不会在此处粘贴任何内容,因为它受版权保护,但任何人都可以下载并安装它。我想。

安装程序会在 C:\Program Files (x86)\MicrosoftRibbonForWPF 文件夹中安装源代码的 zip 文件。我将 zip 文件解压缩到 VS 项目文件夹中。

我正在查看的模板位于 v4.0\Themes\Generic.xaml 文件中。

那些错误的触发器确实引用了相同的属性。它是SystemParameters2.Current 静态对象的HighContrast 属性。

您可以为您的应用程序组合一个自定义模板,甚至不使用这些触发器。至少,我会这样做。

【讨论】:

    【解决方案2】:

    Martin Andersen 是对的:目前无法在 XAML 中创建功能区按钮,在“文档大纲”窗口中右键单击它,选择编辑模板并创建它的副本。 VS会显示如下错误信息并且没有生成模板:

    如果您在 Blend 中执行相同操作,则会出现相同的错误消息,但实际上会生成功能区按钮的控件模板。不幸的是,这个模板是错误的。它包含几个触发器,其绑定绑定到(0)。以下是此类错误触发器的示例。

    <DataTrigger Binding="{Binding (0)}" Value="True">
        <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/>
        <Setter Property="Background" TargetName="OuterBorder" Value="Transparent"/>
        <Setter Property="BorderBrush" TargetName="OuterBorder" Value="Transparent"/>
        <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
    </DataTrigger>
    

    此问题也已报告给 Microsoft:https://connect.microsoft.com/VisualStudio/feedback/details/794891/problems-styling-wpf-4-5-ribbon-control 他们提供了默认控件模板作为此问题的附件,但不幸的是我无法下载它们。生成的文件始终为空(零 KB)。有人可以下载吗?

    建议的解决方案

    我目前的建议是将按钮封装在另一个自定义控件中,该控件派生自 ContentControl 并处理所有通知气泡。然后,您可以将按钮设置为这个新控件的内容。我目前正在研究一个示例 - 当我发现有用的东西时,我会更新这篇文章。

    错误的控制模板

    这里是RibbonButton的完整错误控制模板:

    <ControlTemplate x:Key="RibbonButtonWithNotificationStyle" TargetType="{x:Type RibbonButton}">
        <Border x:Name="OuterBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}" SnapsToDevicePixels="True">
            <Border x:Name="InnerBorder" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" Padding="{TemplateBinding Padding}">
                <StackPanel x:Name="StackPanel">
                    <Image x:Name="PART_Image" RenderOptions.BitmapScalingMode="NearestNeighbor" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Height="32" Margin="{DynamicResource {ComponentResourceKey ResourceId=LargeImageMargin, TypeInTargetAssembly={x:Type Ribbon}}}" Source="{TemplateBinding LargeImageSource}" VerticalAlignment="Center" Width="32"/>
                    <Grid x:Name="Grid" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <RibbonTwoLineText x:Name="TwoLineText" HorizontalAlignment="Center" LineStackingStrategy="BlockLineHeight" LineHeight="13" Margin="1,1,1,0" TextAlignment="Center" Text="{TemplateBinding Label}" VerticalAlignment="Top"/>
                    </Grid>
                </StackPanel>
            </Border>
        </Border>
        <ControlTemplate.Triggers>
            <DataTrigger Binding="{Binding ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Self}}" Value="Large">
                <Setter Property="MinWidth" Value="44"/>
                <Setter Property="Height" Value="66"/>
                <Setter Property="MinHeight" TargetName="Grid" Value="26"/>
                <Setter Property="RibbonTwoLineText.HasTwoLines" TargetName="TwoLineText" Value="True"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Self}}" Value="Small">
                <Setter Property="Height" Value="22"/>
                <Setter Property="Margin" TargetName="PART_Image" Value="1,0"/>
                <Setter Property="Source" TargetName="PART_Image" Value="{Binding SmallImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="Width" TargetName="PART_Image" Value="16"/>
                <Setter Property="Height" TargetName="PART_Image" Value="16"/>
                <Setter Property="HorizontalAlignment" TargetName="TwoLineText" Value="Left"/>
                <Setter Property="Margin" TargetName="TwoLineText" Value="1"/>
                <Setter Property="Orientation" TargetName="StackPanel" Value="Horizontal"/>
            </DataTrigger>
    
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Self}}" Value="Small"/>
                    <Condition Binding="{Binding IsInQuickAccessToolBar, RelativeSource={RelativeSource Self}}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Height" Value="Auto"/>
            </MultiDataTrigger>
            <DataTrigger Binding="{Binding ControlSizeDefinition.IsLabelVisible, RelativeSource={RelativeSource Self}}" Value="False">
                <Setter Property="Visibility" TargetName="TwoLineText" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Self}}" Value="Collapsed">
                <Setter Property="Visibility" TargetName="PART_Image" Value="Collapsed"/>
            </DataTrigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" TargetName="OuterBorder" Value="{Binding MouseOverBackground, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{Binding MouseOverBorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="InnerBorder" Value="#80FFFFFF"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocused" Value="True">
                <Setter Property="Background" TargetName="OuterBorder" Value="{Binding FocusedBackground, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{Binding FocusedBorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="InnerBorder" Value="#80FFFFFF"/>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter Property="Background" TargetName="OuterBorder" Value="{Binding PressedBackground, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{Binding PressedBorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderBrush" TargetName="InnerBorder" Value="Transparent"/>
            </Trigger>
            <Trigger Property="IsInControlGroup" Value="True">
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{Binding Ribbon.BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="BorderThickness" TargetName="OuterBorder" Value="0,0,1,0"/>
                <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
                <Setter Property="CornerRadius" TargetName="InnerBorder" Value="0"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Opacity" TargetName="PART_Image" Value="0.5"/>
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="#FF9E9E9E"/>
            </Trigger>
            <DataTrigger Binding="{Binding (0)}" Value="True">
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/>
                <Setter Property="Background" TargetName="OuterBorder" Value="Transparent"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="Transparent"/>
                <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
            </DataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
                    <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="False"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsDropDownOpen, FallbackValue=false, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
                    <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="False"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
                <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
                <Setter Property="BorderBrush" TargetName="InnerBorder" Value="Transparent"/>
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsKeyboardFocused, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
                <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
                <Setter Property="BorderBrush" TargetName="InnerBorder" Value="Transparent"/>
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                <Setter Property="CornerRadius" TargetName="OuterBorder" Value="0"/>
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsInControlGroup, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="False"/>
                    <Condition Binding="{Binding (0)}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="TextElement.Foreground" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
            </MultiDataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    【讨论】:

    • 是否有可能弄清楚坏绑定应该绑定到哪些属性?也就是说,代码中是否有足够的线索可以提示您它们应该绑定到什么?
    • 我不能,但我没有仔细看。我用错误的模板更新了帖子。
    • 没有真正的方法可以知道,但我有一种直觉,所有的 {Binding (0)} 条件都在同一个属性上。似乎其他所有属性都很好。它可能是控件的某些属性,指示下拉菜单是否可见或是否在控件中。不过,我对这个类的了解还不够,不知道该属性可能是什么。
    • 难道这些是内部属性?这可以解释为什么无法正确解析控制模板。
    • 我想它们可能是内部属性。这些属性必须对 WPF DLL 中的代码可见。我检查了文档,功能区控件都在一个单独的 DLL 中,所以我的直觉说它们不是内部属性,但我不确定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    相关资源
    最近更新 更多