นี่ยังทำให้ฉันบ้าในคืนนี้ ฉันสร้าง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);
}
}
}
พูดจาโผงผางเล็กน้อย: เหตุใด Microsoft จึงไม่สร้างDependencyProperty
คุณสมบัติ (getters / setters) เสมือนเพื่อให้เราสามารถยอมรับ / ปฏิเสธ / ปรับเปลี่ยนการเปลี่ยนแปลงในคลาสย่อยได้ หรือทำvirtual OnXYZPropertyChanged
สำหรับแต่ละคนDependencyProperty
? ฮึ.
--- แก้ไข ---
วิธีแก้ปัญหาของฉันข้างต้นดูแปลก ๆ ในตัวแก้ไข 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
ในฐานะที่เป็น "ความลับ" การควบคุมผู้ปกครองระหว่างการแสดง สุดท้ายผมสังเกตเห็นทั้งหมดตัวอย่าง XAML คำแนะนำเครื่องมือบนเว็บไม่ได้ใช้ระดับToolTip
โดยตรง แต่จะฝัง a StackPanel
ด้วยTextBlock
s สิ่งที่ทำให้คุณพูด: "อืม ... "
ShowDuration
30,000
อะไรที่มากกว่านั้นและค่าเริ่มต้นจะกลับไป5000
เป็น