解决方法:参照ToolTip控件实现一个功能更为强大的ToolTip(命名为RichToolTip)

1、目标:仿照Word2007的悬停工具栏,如下图实现上下文工具栏。

2、虽然ToolTip的控件模板可以定义为包含可交互操作的控件(如Button,TextBox等),然而却无法接受焦点(鼠标移到ToolTip上内容立即就消失),所以无法用此办法实现;

3、使用方法与ToolTipService类似,参见如下代码:

<TextBox x:Name="_txtWords" BorderThickness="1" BorderBrush="Black" Margin="5"><controls:RichToolTip.PopupContent><controls:RichToolTipPlacementTarget="{Binding RelativeSource={RelativeSource Self}, Path=RelatedObject}"Placement="MousePoint" HorizontalOffset="0"VerticalOffset="0"><Border BorderBrush="Black" BorderThickness="1" Margin="5" Background="DarkKhaki"><utils:HoverOverToolBarView /></Border></controls:RichToolTip></controls:RichToolTip.PopupContent>
</TextBox>

4、应用效果如下所见:

5、代码实现:

RichToolTip Control's Code

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Windows;
  5 using System.Windows.Controls;
  6 using System.Windows.Controls.Primitives;
  7 using System.Windows.Data;
  8 using System.Windows.Documents;
  9 using System.Windows.Input;
 10 using System.Windows.Media;
 11 using System.Windows.Media.Imaging;
 12 using System.Windows.Shapes;
 13 using System.Windows.Threading;
 14 using System.Runtime.InteropServices;
 15 using System.Windows.Interop;
 16 using System.Reflection;
 17 using System.Diagnostics;
 18 using System.Security;
 19 using System.Security.Permissions;
 20 using System.Windows.Navigation;
 21 using System.Windows.Media.Animation;
 22
 23 namespace JetSun.Presentation.Controls
 24 {
 25     /// <summary>
 26     /// A kind-of Tooltip implementation that stays open once element is hovered and the content inside is responsive
 27     ///
 28     /// It corresponds to most of the TooltipService attached properties so use them as you wish
 29     /// Known Issues:
 30     /// 1 - I didn't have the time nor the strength to care about repositioning. I simply hide the popup whenever it would need repositioning. (Window movement, etc..) But it's ok since it's the default behavior of popup overall.
 31     /// 2 - XBap mode sets transparency through a hack! supported only in full trust.
 32     /// 3 - In XBap mode, moving the mouse slowly towards the popup will cause it to hide
 33     /// 4 - In XBap mode, moving the mouse over the element shows the tooltip even when the browser isn't the active window
 34     /// </summary>
 35     ///
 36     public partial class RichToolTip : ContentControl
 37     {
 38         #region Fields
 39         const int _animationDurationInMs = 200;
 40         const int _showDeferredMilliseconds = 500;
 41         const bool _animationEnabledDefault = true;
 42
 43         delegate void Action();
 44         Popup _parentPopup;
 45
 46         static RichToolTip _lastShownPopup = null;
 47         #endregion
 48
 49         #region Properties
 50         UIElement _relatedObject;
 51         /// <summary>
 52         /// 关联控件
 53         /// </summary>
 54         public UIElement RelatedObject
 55         {
 56             get { return _relatedObject; }
 57         }
 58
 59         private bool _enableAnimation = _animationEnabledDefault;
 60         /// <summary>
 61         /// 是否显示动画
 62         /// </summary>
 63         public bool EnableAnimation
 64         {
 65             get { return _enableAnimation; }
 66             set { _enableAnimation = value; }
 67         }
 68         #endregion
 69
 70         #region Instancing
 71         static RichToolTip()
 72         {
 73             EventManager.RegisterClassHandler(typeof(UIElement), UIElement.MouseDownEvent, new MouseButtonEventHandler(OnElementMouseDown), true);
 74             EventManager.RegisterClassHandler(typeof(RichToolTip), ButtonBase.ClickEvent, new RoutedEventHandler(OnButtonBaseClick), false);
 75             EventManager.RegisterClassHandler(typeof(Selector), Selector.SelectionChangedEvent, new SelectionChangedEventHandler(selector_SelectionChangedEvent), true);
 76
 77             if (BrowserInteropHelper.IsBrowserHosted)
 78             {
 79                 EventManager.RegisterClassHandler(typeof(NavigationWindow), UIElement.MouseLeaveEvent, new RoutedEventHandler(OnNavigationWindowMouseLeaveEvent), true);
 80             }
 81             else
 82             {
 83                 EventManager.RegisterClassHandler(typeof(Window), Window.SizeChangedEvent, new RoutedEventHandler(OnWindowSizeChanged), true);
 84             }
 85
 86             CommandManager.RegisterClassCommandBinding(typeof(RichToolTip), new CommandBinding(CloseCommand, ExecuteCloseCommand));
 87             InitStoryboards();
 88         }
 89         /// <summary>
 90         ///
 91         /// </summary>
 92         public RichToolTip()
 93         {
 94             Loaded += new RoutedEventHandler(ContentTooltip_Loaded);
 95             Unloaded += new RoutedEventHandler(ContentTooltip_Unloaded);
 96         }
 97         /// <summary>
 98         ///
 99         /// </summary>
100         /// <param name="relatedObject"></param>
101         public RichToolTip(UIElement relatedObject)
102             : this()
103         {
104             Load(relatedObject);
105         }
106         #endregion
107
108         #region Loading
109         void Load(UIElement relatedObject)
110         {
111             _relatedObject = relatedObject;
112
113             FrameworkElement fe = relatedObject as FrameworkElement;
114
115             if (fe == null)
116             {
117                 throw new InvalidOperationException("The element is not supported");
118             }
119
120             _relatedObject.MouseEnter += element_MouseEnter;
121             _relatedObject.MouseLeave += element_MouseLeave;
122
123             fe.Unloaded += new RoutedEventHandler(RelatedObject_Unloaded);
124
125             BindRootVisual();
126
127             this.MouseLeave += new MouseEventHandler(RichToolTip_MouseLeave);
128         }
129
130         void RichToolTip_MouseLeave(object sender, MouseEventArgs e)
131         {
132             if (IsShown() && this == _lastShownPopup)
133             {
134                 Hide(true);
135             }
136         }
137
138         void RelatedObject_Unloaded(object sender, RoutedEventArgs e)
139         {
140             _relatedObject.MouseEnter -= element_MouseEnter;
141             _relatedObject.MouseLeave -= element_MouseLeave;
142         }
143
144         void ContentTooltip_Unloaded(object sender, RoutedEventArgs e)
145         {
146             UnbindRootVisual();
147         }
148
149         void ContentTooltip_Loaded(object sender, RoutedEventArgs e)
150         {
151             BindRootVisual();
152         }
153         #endregion
154
155         #region Popup Creation
156         private static readonly Type PopupType = typeof(Popup);
157         private static readonly Type PopupSecurityHelperType = PopupType.GetNestedType("PopupSecurityHelper", BindingFlags.Public | BindingFlags.NonPublic);
158
159         private static readonly FieldInfo Popup_secHelper = PopupType.GetField("_secHelper", BindingFlags.Instance | BindingFlags.NonPublic);
160         private static readonly FieldInfo PopupSecurityHelper_isChildPopupInitialized = PopupSecurityHelperType.GetField("_isChildPopupInitialized", BindingFlags.Instance | BindingFlags.NonPublic);
161         private static readonly FieldInfo PopupSecurityHelper_isChildPopup = PopupSecurityHelperType.GetField("_isChildPopup", BindingFlags.Instance | BindingFlags.NonPublic);
162
163         void HookupParentPopup()
164         {
165             _parentPopup = new Popup();
166
167             if (BrowserInteropHelper.IsBrowserHosted)
168             {
169                 try
170                 {
171                     new ReflectionPermission(PermissionState.Unrestricted).Demand();
172
173                     DoPopupHacks();
174                 }
175                 catch (SecurityException) { }
176             }
177
178             _parentPopup.AllowsTransparency = true;
179             Popup.CreateRootPopup(_parentPopup, this);
180         }
181
182         void DoPopupHacks()
183         {
184             object secHelper = Popup_secHelper.GetValue(_parentPopup);
185             PopupSecurityHelper_isChildPopupInitialized.SetValue(secHelper, true);
186             PopupSecurityHelper_isChildPopup.SetValue(secHelper, false);
187         }
188         #endregion
189
190         #region Commands
191         /// <summary>
192         ///
193         /// </summary>
194         public static RoutedCommand CloseCommand = new RoutedCommand("Close", typeof(RichToolTip));
195         static void ExecuteCloseCommand(object sender, ExecutedRoutedEventArgs e)
196         {
197             HideLastShown(true);
198         }
199         #endregion
200
201         #region Dependency Properties
202         /// <summary>
203         ///
204         /// </summary>
205         public static readonly DependencyProperty PlacementProperty = ToolTipService.PlacementProperty.AddOwner(typeof(RichToolTip));
206         /// <summary>
207         ///
208         /// </summary>
209         public PlacementMode Placement
210         {
211             get { return (PlacementMode)GetValue(PlacementProperty); }
212             set { SetValue(PlacementProperty, value); }
213         }
214         /// <summary>
215         ///
216         /// </summary>
217         /// <param name="obj"></param>
218         /// <returns></returns>
219         public static PlacementMode GetPlacement(DependencyObject obj)
220         {
221             return (PlacementMode)obj.GetValue(PlacementProperty);
222         }
223         /// <summary>
224         ///
225         /// </summary>
226         /// <param name="obj"></param>
227         /// <param name="value"></param>
228         public static void SetPlacement(DependencyObject obj, PlacementMode value)
229         {
230             obj.SetValue(PlacementProperty, value);
231         }
232         /// <summary>
233         ///
234         /// </summary>
235         public static readonly DependencyProperty PlacementTargetProperty = ToolTipService.PlacementTargetProperty.AddOwner(typeof(RichToolTip));
236         /// <summary>
237         ///
238         /// </summary>
239         public UIElement PlacementTarget
240         {
241             get { return (UIElement)GetValue(PlacementTargetProperty); }
242             set { SetValue(PlacementTargetProperty, value); }
243         }
244         /// <summary>
245         ///
246         /// </summary>
247         /// <param name="obj"></param>
248         /// <returns></returns>
249         public static UIElement GetPlacementTarget(DependencyObject obj)
250         {
251             return (UIElement)obj.GetValue(PlacementTargetProperty);
252         }
253         /// <summary>
254         ///
255         /// </summary>
256         /// <param name="obj"></param>
257         /// <param name="value"></param>
258         public static void SetPlacementTarget(DependencyObject obj, UIElement value)
259         {
260             obj.SetValue(PlacementTargetProperty, value);
261         }
262         /// <summary>
263         ///
264         /// </summary>
265         public static readonly DependencyProperty PlacementRectangleProperty = ToolTipService.PlacementRectangleProperty.AddOwner(typeof(RichToolTip));
266         /// <summary>
267         ///
268         /// </summary>
269         public Rect PlacementRectangle
270         {
271             get { return (Rect)GetValue(PlacementRectangleProperty); }
272             set { SetValue(PlacementRectangleProperty, value); }
273         }
274         /// <summary>
275         ///
276         /// </summary>
277         /// <param name="obj"></param>
278         /// <returns></returns>
279         public static Rect GetPlacementRectangle(DependencyObject obj)
280         {
281             return (Rect)obj.GetValue(PlacementRectangleProperty);
282         }
283         /// <summary>
284         ///
285         /// </summary>
286         /// <param name="obj"></param>
287         /// <param name="value"></param>
288         public static void SetPlacementRectangle(DependencyObject obj, Rect value)
289         {
290             obj.SetValue(PlacementRectangleProperty, value);
291         }
292         /// <summary>
293         ///
294         /// </summary>
295         public static readonly DependencyProperty HorizontalOffsetProperty = ToolTipService.HorizontalOffsetProperty.AddOwner(typeof(RichToolTip));
296         /// <summary>
297         ///
298         /// </summary>
299         public double HorizontalOffset
300         {
301             get { return (double)GetValue(HorizontalOffsetProperty); }
302             set { SetValue(HorizontalOffsetProperty, value); }
303         }
304         /// <summary>
305         ///
306         /// </summary>
307         /// <param name="obj"></param>
308         /// <returns></returns>
309         public static double GetHorizontalOffset(DependencyObject obj)
310         {
311             return (double)obj.GetValue(HorizontalOffsetProperty);
312         }
313         /// <summary>
314         ///
315         /// </summary>
316         /// <param name="obj"></param>
317         /// <param name="value"></param>
318         public static void SetHorizontalOffset(DependencyObject obj, double value)
319         {
320             obj.SetValue(HorizontalOffsetProperty, value);
321         }
322         /// <summary>
323         ///
324         /// </summary>
325         public static readonly DependencyProperty VerticalOffsetProperty = ToolTipService.VerticalOffsetProperty.AddOwner(typeof(RichToolTip));
326         /// <summary>
327         ///
328         /// </summary>
329         public double VerticalOffset
330         {
331             get { return (double)GetValue(VerticalOffsetProperty); }
332             set { SetValue(VerticalOffsetProperty, value); }
333         }
334         /// <summary>
335         ///
336         /// </summary>
337         /// <param name="obj"></param>
338         /// <returns></returns>
339         public static double GetVerticalOffset(DependencyObject obj)
340         {
341             return (double)obj.GetValue(VerticalOffsetProperty);
342         }
343         /// <summary>
344         ///
345         /// </summary>
346         /// <param name="obj"></param>
347         /// <param name="value"></param>
348         public static void SetVerticalOffset(DependencyObject obj, double value)
349         {
350             obj.SetValue(VerticalOffsetProperty, value);
351         }
352         /// <summary>
353         ///
354         /// </summary>
355         public static readonly DependencyProperty IsOpenProperty =
356                 Popup.IsOpenProperty.AddOwner(typeof(RichToolTip), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnIsOpenChanged)));
357         /// <summary>
358         ///
359         /// </summary>
360         public bool IsOpen
361         {
362             get { return (bool)GetValue(IsOpenProperty); }
363             set { SetValue(IsOpenProperty, value); }
364         }
365
366         private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
367         {
368             RichToolTip ctrl = (RichToolTip)d;
369
370             if ((bool)e.NewValue)
371             {
372                 if (ctrl._parentPopup == null)
373                 {
374                     ctrl.HookupParentPopup();
375                 }
376             }
377         }
378
379         #endregion
380
381         #region Attached Properties
382
383         #region HideOnClick
384         /// <summary>
385         ///
386         /// </summary>
387         /// <param name="obj"></param>
388         /// <returns></returns>
389         public static bool GetHideOnClick(DependencyObject obj)
390         {
391             return (bool)obj.GetValue(HideOnClickProperty);
392         }
393         /// <summary>
394         ///
395         /// </summary>
396         /// <param name="obj"></param>
397         /// <param name="value"></param>
398         public static void SetHideOnClick(DependencyObject obj, bool value)
399         {
400             obj.SetValue(HideOnClickProperty, value);
401         }
402         /// <summary>
403         ///
404         /// </summary>
405         public static readonly DependencyProperty HideOnClickProperty =
406             DependencyProperty.RegisterAttached("HideOnClick", typeof(bool), typeof(RichToolTip), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
407         #endregion
408
409         #region PopupContent
410         /// <summary>
411         ///
412         /// </summary>
413         /// <param name="obj"></param>
414         /// <returns></returns>
415         public static object GetPopupContent(DependencyObject obj)
416         {
417             return obj.GetValue(PopupContentProperty);
418         }
419         /// <summary>
420         ///
421         /// </summary>
422         /// <param name="obj"></param>
423         /// <param name="value"></param>
424         public static void SetPopupContent(DependencyObject obj, object value)
425         {
426             obj.SetValue(PopupContentProperty, value);
427         }
428         /// <summary>
429         ///
430         /// </summary>
431         public static readonly DependencyProperty PopupContentProperty =
432             DependencyProperty.RegisterAttached("PopupContent", typeof(object), typeof(RichToolTip), new FrameworkPropertyMetadata(OnPopupContentChanged));
433
434         private static void OnPopupContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
435         {
436             UIElement element = o as UIElement;
437             if (element == null)
438             {
439                 throw new InvalidOperationException("Can't hook to events other than UI Element");
440             }
441
442             if (e.NewValue != null)
443             {
444                 RichToolTip popup = e.NewValue as RichToolTip;
445
446                 if (popup != null)
447                 {
448                     popup.Load(element);
449                 }
450                 else
451                 {
452                     popup = new RichToolTip(element);
453
454                     Binding binding = new Binding
455                     {
456                         Path = new PropertyPath(PopupContentProperty),
457                         Mode = BindingMode.OneWay,
458                         Source = o,
459                     };
460                     popup.SetBinding(ContentProperty, binding);
461                 }
462
463                 SetContentTooltipWrapper(o, popup);
464             }
465         }
466         #endregion
467
468         #region ContentTooltipWrapper
469         internal static RichToolTip GetContentTooltipWrapper(DependencyObject obj)
470         {
471             return (RichToolTip)obj.GetValue(ContentTooltipWrapperProperty);
472         }
473
474         internal static void SetContentTooltipWrapper(DependencyObject obj, RichToolTip value)
475         {
476             obj.SetValue(ContentTooltipWrapperProperty, value);
477         }
478
479         internal static readonly DependencyProperty ContentTooltipWrapperProperty =
480             DependencyProperty.RegisterAttached("ContentTooltipWrapper", typeof(RichToolTip), typeof(RichToolTip));
481         #endregion
482
483         #endregion
484
485         #region Root Visual Binding
486         bool _boundToRoot = false;
487         bool _hasParentWindow = false;
488         Window _parentWindow = null;
489
490         void BindRootVisual()
491         {
492             if (!_boundToRoot)
493             {
494                 if (!BrowserInteropHelper.IsBrowserHosted)
495                 {
496                     _parentWindow = UIHelpers.FindLogicalAncestorByType<Window>(_relatedObject)
497                         ?? UIHelpers.FindVisualAncestorByType<Window>(_relatedObject);
498
499                     if (_parentWindow != null)
500                     {
501                         _hasParentWindow = true;
502
503                         _parentWindow.Deactivated += window_Deactivated;
504                         _parentWindow.LocationChanged += window_LocationChanged;
505                     }
506                 }
507
508                 _boundToRoot = true;
509             }
510         }
511
512         void UnbindRootVisual()
513         {
514             if (_boundToRoot)
515             {
516                 if (_parentWindow != null)
517                 {
518                     _parentWindow.Deactivated -= window_Deactivated;
519                     _parentWindow.LocationChanged -= window_LocationChanged;
520                 }
521
522                 _boundToRoot = false;
523             }
524         }
525         #endregion
526
527         #region Animations & Intervals
528         static DispatcherTimer _timer;
529         static Storyboard _showStoryboard;
530         static Storyboard _hideStoryboard;
531         bool setRenderTransform;
532
533         static void InitStoryboards()
534         {
535             _showStoryboard = new Storyboard();
536             _hideStoryboard = new Storyboard();
537
538             TimeSpan duration = TimeSpan.FromMilliseconds(_animationDurationInMs);
539
540             DoubleAnimation animation = new DoubleAnimation(1, duration, FillBehavior.Stop);
541             Storyboard.SetTargetProperty(animation, new PropertyPath(UIElement.OpacityProperty));
542             _showStoryboard.Children.Add(animation);
543
544             animation = new DoubleAnimation(0.1, 1, duration, FillBehavior.Stop);
545             Storyboard.SetTargetProperty(animation, new PropertyPath("(0).(1)", FrameworkElement.RenderTransformProperty, ScaleTransform.ScaleXProperty));
546             _showStoryboard.Children.Add(animation);
547
548             animation = new DoubleAnimation(0.1, 1, duration, FillBehavior.Stop);
549             Storyboard.SetTargetProperty(animation, new PropertyPath("(0).(1)", FrameworkElement.RenderTransformProperty, ScaleTransform.ScaleYProperty));
550             _showStoryboard.Children.Add(animation);
551
552             animation = new DoubleAnimation(0, duration, FillBehavior.Stop);
553             Storyboard.SetTargetProperty(animation, new PropertyPath(UIElement.OpacityProperty));
554             _hideStoryboard.Children.Add(animation);
555
556             _hideStoryboard.Completed += delegate { OnAnimationCompleted(); };
557         }
558
559         static void InitTimer()560         {
561             _timer = new DispatcherTimer();
562             _timer.Interval = TimeSpan.FromMilliseconds(_showDeferredMilliseconds);
563         }
564
565         static void ResetTimer(RichToolTip tooltip)
566         {
567             if (_timer != null)
568             {
569                 _timer.Tick -= tooltip.ShowDeferred;
570                 _timer.Stop();
571             }
572         }
573
574         void Animate(bool show)
575         {
576             if (show)
577             {
578                 if (!setRenderTransform)
579                 {
580                     RenderTransform = new ScaleTransform();
581
582                     setRenderTransform = true;
583                 }
584
585                 _showStoryboard.Begin(this);
586             }
587             else
588             {
589                 _hideStoryboard.Begin(this);
590             }
591         }
592
593         static void OnAnimationCompleted()
594         {
595             HideLastShown(false);
596         }
597         #endregion
598
599         #region Event Invocations
600         void element_MouseEnter(object sender, MouseEventArgs e)
601         {
602             if (!IsShown() && this != _lastShownPopup)
603             {
604                 if (!_hasParentWindow || _parentWindow.IsActive)
605                 {
606                     Show(true);
607                 }
608             }
609         }
610
611         void element_MouseLeave(object sender, MouseEventArgs e)
612         {
613             ResetTimer(this);
614
615             if (IsShown() && this == _lastShownPopup)
616             {
617                 Hide(true);
618             }
619         }
620
621         static void OnNavigationWindowMouseLeaveEvent(object sender, RoutedEventArgs e)
622         {
623             Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
624             new Action(() =>
625             {
626                 if (_lastShownPopup != null && !_lastShownPopup.IsMouseOver)
627                 {
628                     HideLastShown(false);
629                 }
630             }));
631         }
632
633         void window_LocationChanged(object sender, EventArgs e)
634         {
635             if (IsShown())
636             {
637                 HideLastShown(false);
638             }
639         }
640
641         void window_Deactivated(object sender, EventArgs e)
642         {
643             if (IsShown())
644             {
645                 HideLastShown(false);
646             }
647         }
648
649         static void OnWindowSizeChanged(object sender, RoutedEventArgs e)
650         {
651             HideLastShown();
652         }
653
654         static void OnElementMouseDown(object sender, MouseButtonEventArgs e)
655         {
656             if (_lastShownPopup != null && _lastShownPopup.IsShown())
657             {
658                 RichToolTip popup;
659
660                 DependencyObject o = e.OriginalSource as DependencyObject;
661                 if (!TryFindPopupParent(e.OriginalSource, out popup))
662                 {
663                     HideLastShown(true);
664                 }
665             }
666         }
667
668         static void OnButtonBaseClick(object sender, RoutedEventArgs e)
669         {
670             if (_lastShownPopup != null && _lastShownPopup.IsShown())
671             {
672                 DependencyObject o = e.OriginalSource as DependencyObject;
673
674                 bool hide = GetHideOnClick(o);
675                 if (hide)
676                 {
677                     HideLastShown(true);
678
679                     e.Handled = true;
680                 }
681             }
682         }
683
684         static void selector_SelectionChangedEvent(object sender, SelectionChangedEventArgs e)
685         {
686             HideLastShown();
687         }
688
689         static bool TryFindPopupParent(object source, out RichToolTip popup)
690         {
691             popup = null;
692             UIElement element = source as UIElement;
693
694             if (element != null)
695             {
696                 popup = UIHelpers.FindVisualAncestorByType<RichToolTip>(element);
697
698                 if (popup == null)
699                 {
700                     popup = UIHelpers.FindLogicalAncestorByType<RichToolTip>(element);
701                 }
702
703                 return popup != null;
704             }
705
706             return false;
707         }
708         #endregion
709
710         #region Show / Hide
711         bool _showAnimate = _animationEnabledDefault;
712
713         bool IsShown()
714         {
715             return IsOpen;
716         }
717
718         public void Show(bool animate)
719         {
720             _showAnimate = animate;
721
722             if (_timer == null)
723             {
724                 InitTimer();
725             }
726
727             _timer.Tick += ShowDeferred;
728
729             if (!_timer.IsEnabled)
730             {
731                 _timer.Start();
732             }
733         }
734
735         private void ShowDeferred(object sender, EventArgs e)
736         {
737             ResetTimer(this);
738
739             HideLastShown(false);
740
741             ShowInternal();
742
743             if (_showAnimate && EnableAnimation)
744             {
745                 Animate(true);
746             }
747             else
748             {
749                 this.Opacity = 1;
750             }
751
752             _lastShownPopup = this;
753         }
754
755         private void ShowInternal()
756         {
757             Visibility = Visibility.Visible;
758
759             IsOpen = true;
760         }
761
762         static void HideLastShown()
763         {
764             HideLastShown(false);
765         }
766
767         static void HideLastShown(bool animate)
768         {
769             if (_lastShownPopup != null)
770             {
771                 _lastShownPopup.Hide(animate);
772             }
773         }
774
775         /// <summary>
776         ///
777         /// </summary>
778         /// <param name="animate"></param>
779         public void Hide(bool animate)
780         {
781             Point pt = Mouse.GetPosition(this);
782             if (pt.X >= 0 && pt.Y >= 0 && pt.X <= this.ActualWidth && pt.Y <= this.ActualHeight) return;
783
784             if (animate && EnableAnimation)
785             {
786                 Animate(false);
787             }
788             else
789             {
790                 HideInternal();
791             }
792         }
793
794         private void HideInternal()
795         {
796             this.Visibility = Visibility.Collapsed;
797             this.IsOpen = false;
798
799             _lastShownPopup = null;
800         }
801
802         #endregion
803     }
804 }

转载于:https://www.cnblogs.com/chriskwok/archive/2012/08/04/2623161.html

WPF的悬停工具栏实现方案相关推荐

  1. WPF多国语言实现方案

    MVVM模式就不必多讲了直接上代码 配置静态资源在App.xaml中 <Application.Resources><s:ApplicationLoader><sys:I ...

  2. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(8月13日-8月19日)

    Silverlight/Windows8/WPF/WP7/HTML5周学习导读(8月13日-8月19日) 本周Silverlight学习资源更新 Silverlight中如何实现上下标的显示 Lice ...

  3. WPF使用X:Static做多语言支持

    原文:WPF使用X:Static做多语言支持 让程序支持多语言,一般把需要显示的字符串保存在一个资源类的static属性中. <!--[if !supportLists]--> <! ...

  4. 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(4月2日-4月8日)

    分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(4月2日-4月8日) 本周Silverlight学习资源更新 Microsoft Silverlight 4从入 ...

  5. 关于WPF的资源引用问题

    WPF的资源引用大致有下面几个点需要讨论,下面我们逐个讨论. 目录 Pack Uri方案 资源文件Pack Uri 本地程序集资源 引用程序集资源 内容文件 Pack Uri 源站点 Pack Uri ...

  6. 微软官方的.NET Framework API 参考网址

    微软官方的.NET Framework API 参考网址,值得收藏和查阅~~~ https://docs.microsoft.com/zh-cn/dotnet/api/?view=netframewo ...

  7. [UWP]本地化入门

    [UWP]本地化入门 原文:[UWP]本地化入门 1. 前言 上一篇文章介绍了各种WPF本地化的入门知识,这篇文章介绍UWP本地化的入门知识. 2. 使用resw资源文件实现本地化 在以前的XAML平 ...

  8. VCL已死,RAD已死(插播)

    VCL已死,RAD已死 --SD2C中未能尽言的话题<<<-- 上一节 这个插播,是Shaofei Cheng在MSN跟我的一段聊天记录.关于这个话题,我在会后休息的时 候,与很多朋 ...

  9. eplan连接定义点不显示_EPLAN操作命令之线色设置

    EPLAN操作命令之线色设置 今天我们利用操作命令建立一个快速改变线色的小工具栏,希望以此来扣开EPLAN操作命令的大门.EPLAN中连线默认的颜色是红色的,改变它的颜色需要在连接定义点中连接图形的颜 ...

最新文章

  1. C语言经典例67-数组最大值与最小值与数组元素交换
  2. 上海大学计算机工程与科学学院官网,上海大学计算机工程与科学学院.PDF
  3. java 日期 运算
  4. C语言基础语言总结(二)
  5. oracle实现分段,用Oracle分段空间管理功能改进数据库性能
  6. Raect Router 4 的使用 (1)
  7. 如何选择高速存储、查询数据库
  8. BTA 2018 区块链核心技术专场:12 位专家全方位剖析区块链核心技术原理与业务实践
  9. 高校表白App-团队冲刺第十天
  10. myeclipse导入项目
  11. atitit.为什么 java开发要比php开发速度慢??
  12. 百度地图小区边界爬取
  13. 第十二周项目四----利用遍历思想求解图问题之7最远顶点
  14. 高尔顿钉板实验是二项分布吗?
  15. qq linux for android,腾讯QQ for android 糊弄还是敷衍?
  16. 实现vue页面下载成word文档
  17. Android_listview_video安卓列表视频直接播放
  18. EDK II之USB主控制器(EHCI)驱动的实现框架
  19. React 基础----1
  20. 大二物竞金牌转北大计算机,2011年第28届全国中学生物理竞赛决赛金牌选手去向表...

热门文章

  1. linux mysql怎么建数据库用户,Linux MySQL新建用户
  2. 使用左 右 全 内连接及使用where条件语句的区别
  3. 10款常用Java测试工具
  4. 使用Windows版Redis
  5. 14.图像透视——介绍,坐标系统(Coordinate System),建模投影(Modelling Projection)_1
  6. 17.立体匹配——介绍,匹配,寻找最佳匹配 Matlab实战_1
  7. python读取数据库绘图_获取博客积分排名,存入数据库,读取数据进行绘图(python,selenium,matplotlib)...
  8. 【英语学习】【Level 07】U05 Best Destination L5 Top choice
  9. OpenGL坐标系及基本变换
  10. jq判断是否为整数_五种js判断是否为整数(转)