zoukankan      html  css  js  c++  java
  • WPF的悬停工具栏实现方案

    解决方法:参照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:RichToolTip
                    PlacementTarget="{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 }
  • 相关阅读:
    Ubuntu(Debian)的aptitude与aptget的区别和联系
    安装lxml相关
    解决Ubuntu 12.04更新后 ”系统的网络服务与此版本的网络管理器不兼容“问题
    Windows下配置Nginx代理Django
    scons入门笔记
    git仓库合并(向原有git仓库中加入新仓库)
    asterisk源码分析(main函数)
    live555源码编译(win7+vs2010)
    asterisk源码目录结构
    小试一题
  • 原文地址:https://www.cnblogs.com/chriskwok/p/2623161.html
Copyright © 2011-2022 走看看