我有一個標籤工具提示,我希望它保持打開狀態,直到用戶 將鼠標移動到不同的控件。強制WPF工具提示留在屏幕上
我曾嘗試在提示以下屬性:
StaysOpen="True"
和
TooltipService.ShowDuration = "60000"
但在這兩種情況下,工具提示僅顯示了整整5秒。
爲什麼這些值被忽略?
我有一個標籤工具提示,我希望它保持打開狀態,直到用戶 將鼠標移動到不同的控件。強制WPF工具提示留在屏幕上
我曾嘗試在提示以下屬性:
StaysOpen="True"
和
TooltipService.ShowDuration = "60000"
但在這兩種情況下,工具提示僅顯示了整整5秒。
爲什麼這些值被忽略?
把這段代碼放在初始化部分。
ToolTipService.ShowDurationProperty.OverrideMetadata(
typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));
我前幾天只是摔跤WPF Tooltip。似乎不可能阻止它自己出現並消失,所以最終我採取了處理事件的辦法。例如,我想停止打開它,除非它有一些內容,所以我處理的Opened
事件,然後這樣做:
tooltip.IsOpen = (tooltip.Content != null);
這是一個黑客,但它的工作。
假設您可以類似地處理Closed
事件並告訴它再次打開,從而保持它可見。
您可能希望使用Popup而不是Tooltip,因爲Tooltip假定您以預定義的UI標準方式使用它。
我不確定爲什麼StaysOpen不起作用,但ShowDuration的工作方式與MSDN中記錄的一樣 - 它是在顯示工具提示時顯示的時間量。將其設置爲少量(例如500毫秒)以查看差異。
在你的情況下,訣竅是維持「最後一次控制」狀態,但是一旦你有了這個應該是相當簡單的動態更改展示位置目標和內容(手動或通過綁定)使用一個彈出窗口,或隱藏最後一個可見的彈出窗口,如果你使用多個。
對於Window調整大小和移動(Popups不會移動容器),Popups有一些小問題,所以您可能也想在調整行爲時考慮到這一點。有關更多詳細信息,請參閱this link。
HTH。
此外,如果您想將任何其他控件放在您的工具提示中,它將不會被集中,因爲工具提示本身可以獲得焦點。就像micahtan說的那樣,你最好的鏡頭是Popup。
TooltipService.ShowDuration工作,但你必須有工具提示,這樣設置的對象:
<Label ToolTipService.ShowDuration="12000" Name="lblShowTooltip" Content="Shows tooltip">
<Label.ToolTip>
<ToolTip>
<TextBlock>Hello world!</TextBlock>
</ToolTip>
</Label.ToolTip>
</Label>
我會說,之所以選擇這種設計,因爲它允許不同的不同的超時相同的提示控制。
ToolTipService.ShowDurationProperty.OverrideMetadata(
typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));
這是爲我工作。將此行復制到您的類構造函數中。
今晚這也讓我瘋狂。我創建了一個ToolTip
子類來處理這個問題。對我而言,在.NET 4.0上,ToolTip.StaysOpen
屬性並非「真正」保持打開狀態。
在下面的類中,使用新屬性ToolTipEx.IsReallyOpen
而不是屬性ToolTip.IsOpen
。你會得到你想要的控制。通過調用Debug.Print()
,您可以在調試器輸出窗口中看到調用this.IsOpen = false
的次數!這麼多的StaysOpen
,或者我應該說"StaysOpen"
?請享用。
public class ToolTipEx : ToolTip
{
static ToolTipEx()
{
IsReallyOpenProperty =
DependencyProperty.Register(
"IsReallyOpen",
typeof(bool),
typeof(ToolTipEx),
new FrameworkPropertyMetadata(
defaultValue: false,
flags: FrameworkPropertyMetadataOptions.None,
propertyChangedCallback: StaticOnIsReallyOpenedChanged));
}
public static readonly DependencyProperty IsReallyOpenProperty;
protected static void StaticOnIsReallyOpenedChanged(
DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ToolTipEx self = (ToolTipEx)o;
self.OnIsReallyOpenedChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected void OnIsReallyOpenedChanged(bool oldValue, bool newValue)
{
this.IsOpen = newValue;
}
public bool IsReallyOpen
{
get
{
bool b = (bool)this.GetValue(IsReallyOpenProperty);
return b;
}
set { this.SetValue(IsReallyOpenProperty, value); }
}
protected override void OnClosed(RoutedEventArgs e)
{
System.Diagnostics.Debug.Print(String.Format(
"OnClosed: IsReallyOpen: {0}, StaysOpen: {1}", this.IsReallyOpen, this.StaysOpen));
if (this.IsReallyOpen && this.StaysOpen)
{
e.Handled = true;
// We cannot set this.IsOpen directly here. Instead, send an event asynchronously.
// DispatcherPriority.Send is the highest priority possible.
Dispatcher.CurrentDispatcher.BeginInvoke(
(Action)(() => this.IsOpen = true),
DispatcherPriority.Send);
}
else
{
base.OnClosed(e);
}
}
}
小咆哮:爲什麼沒有微軟做DependencyProperty
屬性(getter/setter方法)虛擬的,這樣我們就可以接受/拒絕/調整在子類中的變化?或者爲每個DependencyProperty
製作virtual OnXYZPropertyChanged
?啊。
---編輯---
上面我的解決方案看起來在XAML編輯怪異 - 工具提示總是顯示,堵在Visual Studio中一些文字!
這裏是解決這個問題的一個更好的方法:
一些XAML:
<!-- Need to add this at top of your XAML file:
xmlns:System="clr-namespace:System;assembly=mscorlib"
-->
<ToolTip StaysOpen="True" Placement="Bottom" HorizontalOffset="10"
ToolTipService.InitialShowDelay="0" ToolTipService.BetweenShowDelay="0"
ToolTipService.ShowDuration="{x:Static Member=System:Int32.MaxValue}"
>This is my tooltip text.</ToolTip>
一些代碼:
// Alternatively, you can attach an event listener to FrameworkElement.Loaded
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// Be gentle here: If someone creates a (future) subclass or changes your control template,
// you might not have tooltip anymore.
ToolTip toolTip = this.ToolTip as ToolTip;
if (null != toolTip)
{
// If I don't set this explicitly, placement is strange.
toolTip.PlacementTarget = this;
toolTip.Closed += new RoutedEventHandler(OnToolTipClosed);
}
}
protected void OnToolTipClosed(object sender, RoutedEventArgs e)
{
// You may want to add additional focus-related tests here.
if (this.IsKeyboardFocusWithin)
{
// We cannot set this.IsOpen directly here. Instead, send an event asynchronously.
// DispatcherPriority.Send is the highest priority possible.
Dispatcher.CurrentDispatcher.BeginInvoke(
(Action)delegate
{
// Again: Be gentle when using this.ToolTip.
ToolTip toolTip = this.ToolTip as ToolTip;
if (null != toolTip)
{
toolTip.IsOpen = true;
}
},
DispatcherPriority.Send);
}
}
結論:一些是關於類ToolTip
和ContextMenu
不同。兩者都有「服務」類,如ToolTipService
和ContextMenuService
,它們管理某些屬性,並且在顯示期間都使用Popup
作爲「祕密」父控件。最後,我注意到ALL Web上的XAML ToolTip示例不直接使用類ToolTip
。相反,他們嵌入與TextBlock
s。事情讓你說:「嗯......」只是爲了完整起見
: 在代碼中,它看起來是這樣的:
ToolTipService.SetShowDuration(element, 60000);
如果要指定在Window
只有某些元素有 有效不確定ToolTip
持續時間,您可以在您的Window.Resources
中爲這些元素定義Style
。這裏是一個Style
的Button
有這樣一個ToolTip
:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
...>
...
<Window.Resources>
<Style x:Key="ButtonToolTipIndefinate" TargetType="{x:Type Button}">
<Setter Property="ToolTipService.ShowDuration"
Value="{x:Static Member=sys:Int32.MaxValue}"/>
</Style>
...
</Window.Resources>
...
<Button Style="{DynamicResource ButtonToolTipIndefinate}"
ToolTip="This should stay open"/>
<Button ToolTip="This Should disappear after the default time.">
...
你也可以添加Style.Resources
到Style
改變ToolTip
它顯示的外觀,例如:
<Style x:Key="ButtonToolTipTransparentIndefinate" TargetType="{x:Type Button}">
<Style.Resources>
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="HasDropShadow" Value="False"/>
</Style>
</Style.Resources>
<Setter Property="ToolTipService.ShowDuration"
Value="{x:Static Member=sys:Int32.MaxValue}"/>
</Style>
注意:我這樣做了,我也在Style
中使用了BasedOn
,因此我的自定義控件版本中定義的其他所有內容都將應用於正常的ToolTip
。
對於`ShowDuration`屬性,有一個強制*的某處*的最大值,認爲它類似`30,000`。任何比這更大的東西,它會默認回到`5000`。 – Dennis 2011-09-29 10:43:38
@丹尼斯:我測試了WPF 3.5和`ToolTipService.ShowDuration =「60000」`工作。它沒有默認回到`5000`。 – 2011-12-02 15:28:57
@emddudley:工具提示實際上是否保持開放60000ms?您可以將ToolTipService.ShowDuration屬性設置爲* any * value> = 0(即Int32.MaxValue),但工具提示不會保持打開狀態。 – Dennis 2011-12-02 16:34:38