Bu da bu gece beni deli ediyordu. ToolTip
Sorunu çözmek için bir alt sınıf oluşturdum . Benim için .NET 4.0'da, ToolTip.StaysOpen
özellik "gerçekten" değil, açık kalıyor.
Aşağıdaki sınıfta yeni mülkü kullanın ToolTipEx.IsReallyOpen
yerine kullanın ToolTip.IsOpen
. İstediğiniz kontrolü alacaksınız. Via Debug.Print()
çağrı, birçok kez sadece nasıl ayıklayıcı Çıktı penceresinde izleyebilirsiniz this.IsOpen = false
denir! Çok mu StaysOpen
, yoksa söylemeliyim "StaysOpen"
? Zevk almak.
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);
}
}
}
Küçük rant: Microsoft neden DependencyProperty
özellikleri (alıcılar / ayarlayıcılar) sanal yapmadı, böylece alt sınıflardaki değişiklikleri kabul edebilir / reddedebilir / ayarlayabiliriz? Veya virtual OnXYZPropertyChanged
her biri için bir tane DependencyProperty
mi hazırlıyorsunuz ? Ugh.
---Düzenle---
Yukarıdaki çözümüm XAML düzenleyicide garip görünüyor - araç ipucu her zaman gösteriliyor, Visual Studio'daki bazı metinleri engelliyor!
İşte bu sorunu çözmenin daha iyi bir yolu:
Bazı 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>
Bazı kodlar:
// 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);
}
}
Sonuç: Sınıflar hakkında farklı bir şey var ToolTip
ve ContextMenu
. Her ikisinin de belirli özellikleri yöneten ToolTipService
ve gibi "hizmet" sınıfları vardır ContextMenuService
ve her ikisi de Popup
görüntüleme sırasında "gizli" üst denetim olarak kullanılır. Son olarak, Web'deki TÜM XAML ToolTip örneklerinin ToolTip
doğrudan sınıfı kullanmadığını fark ettim . Bunun yerine, a StackPanel
ile TextBlock
s yerleştirirler . Size şunu söyleten şeyler: "hmmm ..."
ShowDuration
mülkiyet, bu gibi bir şey olduğunu düşünüyorum30,000
. Bundan daha büyük herhangi bir şey ve varsayılan olarak geri dönecektir5000
.