How to detect when a ribbon button's instance is in the Quick Access Toolbar

Ribbon for WPF Forum

Posted 6 months ago by John Brown
Version: 18.1.0675
Avatar

Hi,

I have a ribbon button in a WPF Desktop program that displays an 'unread messages' indicator in the top right corner, like what you get on a smartphone, but when that button is added to the Quick Access Toolbar, the indicator is shown as well and overwrites the whole icon because it's using the small icon.

I want to disable the indicator when the button is in the QAT but show it when the button is in the ribbon, but have been unable to work out how to do it and was hoping you could provide some guidance.

Here is the xaml for this button.  The OverlayBadgeBehavior is a 'Behavior' class used to draw the badge with a number in a circle.  The badge can be hidden by setting its IsEnabled property to false, which I do when there are no unprocessed notifications.  I also use a different icon (different color) when there are unprocessed notifications.

      <ribbon:Button x:Uid="_notificationsButton"
                     x:Name="_notificationsButton"
                     Command="{Binding Path=ViewNotificationsCommand}"
                     Label="Notifications"
                     ScreenTipDescription="View notifications." 
                     commonBehaviors:OverlayBadgeBehavior.Value="{Binding Path=UnprocessedNotificationCount}"
                     commonBehaviors:OverlayBadgeBehavior.IsEnabled="{Binding Path=HasUnprocessedNotifications}">
         <ribbon:Button.Style>
            <Style x:Uid="_notificationsButtonStyle" 
                   TargetType="ribbon:Button">
               <Style.Triggers>
                  <DataTrigger x:Uid="_dataTrigger_1" Binding="{Binding Path=HasUnprocessedNotifications}" Value="False">
                     <Setter x:Uid="_setter_11"
                             Property="ImageSourceLarge"
                             Value="{DynamicResource icoNotifications32Image}" />
                     <Setter x:Uid="_setter_12"
                             Property="ImageSourceSmall"
                             Value="{DynamicResource icoNotifications16Image}" />
                  </DataTrigger>
                  <DataTrigger x:Uid="_dataTrigger_2" Binding="{Binding Path=HasUnprocessedNotifications}" Value="True">
                     <Setter x:Uid="_setter_21"
                          Property="ImageSourceLarge"
                          Value="{DynamicResource icoNotificationsUnread32Image}" />
                     <Setter x:Uid="_setter_22"
                          Property="ImageSourceSmall"
                          Value="{DynamicResource icoNotificationsUnread16Image}" />
                  </DataTrigger>
                  <Trigger x:Uid="_dataTrigger_3" Property="Context" Value="QuickAccessToolBarItem">
                     <Setter x:Uid="_setter_23"
                             Property="commonBehaviors:OverlayBadgeBehavior.IsEnabled"
                             Value="False" />
                  </Trigger>
               </Style.Triggers>
            </Style>
         </ribbon:Button.Style>
      </ribbon:Button>

As you can see, I have tried to set OverlayBadgeBehavior.IsEnabled to false when the button's Context property is set to "QuickAccessToolBarItem", but it doesn't work.

I have also tried using the button's VariantSize property is set to "Small", but that also doesn't work.

I have also tried using a DataTrigger instead of a regular Trigger, with both of these properties (one at a time, of course), but that doesn't work either.

Note that the OverlayBadgeBehavior class is written as a general-use behavior that can applied to any control, and does not "know" about RibbonButtons or any other specific control, so I would be reluctant to introduce control-specific logic by checking non-standard properties like VariantSize or Context.

Ideally, I would prefer a xaml-only solution, but I'm happy to implement it in whatever manner is necessary (code-behind, etc.).

Thanks in advance.

Comments (1)

Answer - Posted 6 months ago by John Brown
Avatar

Don't worry about this.  I have solved the problem  :-)

Just after I posted the question, I had another idea about what might be happening, so I tried it and it fixed the problem.

For the benefit of future searchers, I fixed it by moving the behavior's IsEnabled setting into each of the DataTriggers, rather than in the button's main list of properties.  Like this:

      <ribbon:Button x:Uid="_notificationsButton"
                     x:Name="_notificationsButton"
                     Command="{Binding Path=ViewNotificationsCommand}"
                     Label="Notifications"
                     ScreenTipDescription="View notifications." 
                     commonBehaviors:OverlayBadgeBehavior.Value="{Binding Path=UnprocessedNotificationCount}">
         <ribbon:Button.Style>
            <Style x:Uid="_notificationsButtonStyle" 
                   TargetType="ribbon:Button">
               <Style.Triggers>
                  <DataTrigger x:Uid="_dataTrigger_1" Binding="{Binding Path=HasUnprocessedNotifications}" Value="False">
                     <Setter x:Uid="_setter_11"
                             Property="ImageSourceLarge"
                             Value="{DynamicResource icoNotifications32Image}" />
                     <Setter x:Uid="_setter_12"
                             Property="ImageSourceSmall"
                             Value="{DynamicResource icoNotifications16Image}" />
                     <Setter x:Uid="_setter_13"
                             Property="commonBehaviors:OverlayBadgeBehavior.IsEnabled"
                             Value="False" />
                  </DataTrigger>
                  <DataTrigger x:Uid="_dataTrigger_2" Binding="{Binding Path=HasUnprocessedNotifications}" Value="True">
                     <Setter x:Uid="_setter_21"
                          Property="ImageSourceLarge"
                          Value="{DynamicResource icoNotificationsUnread32Image}" />
                     <Setter x:Uid="_setter_22"
                          Property="ImageSourceSmall"
                          Value="{DynamicResource icoNotificationsUnread16Image}" />
                     <Setter x:Uid="_setter_23"
                             Property="commonBehaviors:OverlayBadgeBehavior.IsEnabled"
                             Value="True" />
                  </DataTrigger>
                  <Trigger x:Uid="_dataTrigger_3" Property="Context" Value="QuickAccessToolBarItem">
                     <Setter x:Uid="_setter_33"
                             Property="commonBehaviors:OverlayBadgeBehavior.IsEnabled"
                             Value="False" />
                  </Trigger>
               </Style.Triggers>
            </Style>
         </ribbon:Button.Style>
      </ribbon:Button>

What I think was happening in the code in my original question is that the Trigger for the Context property was setting IsEnabled=false, but the behavior's IsEnabled property in the main list of properties must have been evaluated after the Trigger was done, and was setting IsEnabled=true again.

Thanks.

The latest build of this product (v2019.1 build 0683) was released 12 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.