Ini juga membuatku gila malam ini. Saya membuat ToolTipsubclass untuk menangani masalah tersebut. Bagi saya, di .NET 4.0,ToolTip.StaysOpen properti tidak "benar-benar" tetap buka.
Di kelas di bawah ini, gunakan properti baru ToolTipEx.IsReallyOpen, bukan properti ToolTip.IsOpen. Anda akan mendapatkan kendali yang Anda inginkan. Melalui Debug.Print()panggilan, Anda dapat melihat di jendela Output debugger berapa kali this.IsOpen = falsedipanggil! Begitu banyak StaysOpen, atau haruskah saya katakan "StaysOpen"? Nikmati.
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);
}
}
}
Kata-kata kasar kecil: Mengapa Microsoft tidak membuat DependencyPropertyproperti (getter / setter) virtual sehingga kami dapat menerima / menolak / menyesuaikan perubahan dalam subclass? Atau buat virtual OnXYZPropertyChangeduntuk setiap DependencyProperty? Ugh.
--- Edit ---
Solusi saya di atas terlihat aneh di editor XAML - tooltip selalu ditampilkan, memblokir beberapa teks di Visual Studio!
Berikut cara yang lebih baik untuk mengatasi masalah ini:
Beberapa 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>
Beberapa kode:
// 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);
}
}
Kesimpulan: Ada sesuatu yang berbeda tentang kelas ToolTipdan ContextMenu. Keduanya memiliki kelas "layanan", seperti ToolTipServicedan ContextMenuService, yang mengelola properti tertentu, dan keduanya digunakan Popupsebagai kontrol induk "rahasia" selama tampilan. Akhirnya, saya perhatikan SEMUA contoh XAML ToolTip di Web tidak menggunakan class ToolTipsecara langsung. Sebaliknya, mereka menyematkan a StackPaneldengan TextBlocks. Hal yang membuatmu berkata: "hmmm ..."
ShowDurationproperti, anggaplah itu seperti itu30,000. Apa pun yang lebih besar dari itu dan akan default kembali ke5000.