Reputation: 585
I have an very, very huge application in WPF with a Ribbon in it. The ribbon contain a bunch of RibbonControls, each binded to a different command. On every control, we put a ToolTip. We overrided these ToolTip templates to use a control of our own, which gives more information. We could call il a superToolTip.
The override of the tooltip templates is working just fine. Now we want to unify the way the tooltips are showing. What I mean is we want the same initialShowDelay, ShowDuration, etc., for every single tooltips in the application (there are tooltips elsewhere than in the ribbon, which use the same home made control that the ones of the ribbon). So, I binded the ToolTipService.InitialShowDelay, ToolTipService.BetweenShowDelay, ToolTipService.ShowDuration properties to global constants in the application.
InitialShowDelay : The property InitialShowDelay is working just fine for almost every control in the application... The only one not working is RibbonSplitButton, which keep the default value of 400...
BetweenShowDelay : The property BetweenShowDelay is working just fine when the tooltip is on a ListBoxItem... but not working in the Ribbon nor in a complex control of our own (a Property Grid).
These properties are set in the control on which the tooltip is set, and not on the tooltip themselves.
I honestly have absolutely no idead why it is behaving this way... Anyone has any idea on what could cause this or how to solve it?
If you need more information, do not hesitate to ask, i really am desperate about this.
Thank you very much!
Upvotes: 0
Views: 2070
Reputation: 54
Also, for the splitbutton problem it was that the tooltipservice werent set for the child of the splitbutton ( the two parts) wich are named PART_HeaderButton and PART_ToggleButton. So even if you create your own style it will be override by the style of the ribbonsplit button ( see this link for the splitbutton.xaml file :
So to bypass this overriding problem ( because we don't have access to the part directly we have to go via code. Im my case, I overrided the RibbonSplitButton class and the OnLoadTemplate method. That way with getchild we can access the property of the part and change them.
public partial class DuniaRibbonSplitButton : RibbonSplitButton
{
public DuniaRibbonSplitButton()
{
InitializeComponent();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var HeaderButton = base.GetTemplateChild("PART_HeaderButton");
var ToggleButton = base.GetTemplateChild("PART_ToggleButton");
OverrideAttributes(HeaderButton as Control);
OverrideAttributes(ToggleButton as Control);
}
private void OverrideAttributes(Control control)
{
control.ToolTip = "Dummy";
ToolTipService.SetInitialShowDelay(control, ToolTipViewModel.ToolTipInitialDelay);
ToolTipService.SetShowDuration(control, ToolTipViewModel.ToolTipShowDuration);
ToolTipService.SetBetweenShowDelay(control, ToolTipViewModel.ToolTipBetweenShowDelay);
}
}
Upvotes: 1
Reputation: 54
The problem was that the condition for BetweenShowDelay wasn't respected, you need to have a value set for the property "ToolTip", in this case you were using a template, so the value was at null. You can resolve it this way :
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Utils:ToolTipControl DataContext="{Binding ToolTipInfo}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and then place the dummy in the specified button :
<!-- RibbonButton -->
<Style TargetType="{x:Type ribbon:RibbonButton}" BasedOn="{StaticResource RibbonControlStyle}" >
<Style.Triggers>
<DataTrigger Value="true" >
<DataTrigger.Binding>
<Binding Converter="{StaticResource IsBoundConverter}" />
</DataTrigger.Binding>
<Setter Property="Command" Value="{Binding}" />
<Setter Property="ribbon:RibbonControlService.Label" Value="{Binding Name}" />
<Setter Property="ribbon:RibbonControlService.SmallImageSource" Value="{Binding Icon}" />
<Setter Property="ribbon:RibbonControlService.LargeImageSource" Value="{Binding LargeIcon}" />
<Setter Property="Visibility" Value="{Binding Visibility}" />
<Setter Property="ToolTip" Value="dummy"/> <!-- Use dummy value to force tooltip to show and to Bind the tooltip-->
</DataTrigger>
<DataTrigger Value="false" >
<DataTrigger.Binding>
<Binding Converter="{StaticResource IsBoundConverter}" />
</DataTrigger.Binding>
<Setter Property="Background" Value="#FF900000" />
</DataTrigger>
</Style.Triggers>
</Style>
That way the dummy value will be override.
:D
Upvotes: 2
Reputation: 585
Here is some code showing how I implemented my ToolTips
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
...>
...
<!-- Ribbon Tooltips Style -->
<Style TargetType="ribbon:RibbonToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Utils:ToolTipControl DataContext="{Binding ToolTipInfo}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
<!-- RibbonControl -->
<Style x:Key="RibbonControlStyle">
<Setter Property="ribbon:RibbonControlService.ToolTipTitle" Value="dummy" /><!-- Use dummy value to force tooltip to show -->
<Setter Property="ToolTipService.InitialShowDelay" Value="{x:Static Utils:ToolTipViewModel.ToolTipInitialDelay}"/>
<Setter Property="ToolTipService.ShowDuration" Value="{x:Static Utils:ToolTipViewModel.ToolTipShowDuration}"/>
<Setter Property="ToolTipService.BetweenShowDelay" Value="{x:Static Utils:ToolTipViewModel.ToolTipBetweenShowDelay}"/>
<!-- This style is used to select the "Editors" tab when opening Editor without a world, and to select the "Home" tab otherwise -->
<Style.Triggers>
<DataTrigger Binding="{Binding IsWorldLoaded, Source={x:Static ViewModels:ViewportSettingsViewModel.Instance}}" Value="false">
<Setter Property="ribbon:Ribbon.SelectedIndex" Value="2"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsWorldLoaded, Source={x:Static ViewModels:ViewportSettingsViewModel.Instance}}" Value="true">
<Setter Property="ribbon:Ribbon.SelectedIndex" Value="0"/>
</DataTrigger>
</Style.Triggers>
</Style>
Upvotes: 1