/Main/src/DynamicDataDisplay/Charts/LiveTooltips/LiveTooltipService.cs
C# | 221 lines | 180 code | 41 blank | 0 comment | 31 complexity | b42fba95a6e56b44015485ac3f4d20a5 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Windows; 6using System.Windows.Input; 7using System.Windows.Documents; 8using System.Windows.Controls; 9using System.Windows.Media; 10using System.Windows.Data; 11using System.ComponentModel; 12 13namespace Microsoft.Research.DynamicDataDisplay.Charts 14{ 15 public static class LiveToolTipService 16 { 17 18 # region Properties 19 20 public static object GetToolTip(DependencyObject obj) 21 { 22 return (object)obj.GetValue(ToolTipProperty); 23 } 24 25 public static void SetToolTip(DependencyObject obj, object value) 26 { 27 obj.SetValue(ToolTipProperty, value); 28 } 29 30 public static readonly DependencyProperty ToolTipProperty = DependencyProperty.RegisterAttached( 31 "ToolTip", 32 typeof(object), 33 typeof(LiveToolTipService), 34 new FrameworkPropertyMetadata(null, OnToolTipChanged)); 35 36 private static LiveToolTip GetLiveToolTip(DependencyObject obj) 37 { 38 return (LiveToolTip)obj.GetValue(LiveToolTipProperty); 39 } 40 41 private static void SetLiveToolTip(DependencyObject obj, LiveToolTip value) 42 { 43 obj.SetValue(LiveToolTipProperty, value); 44 } 45 46 private static readonly DependencyProperty LiveToolTipProperty = DependencyProperty.RegisterAttached( 47 "LiveToolTip", 48 typeof(LiveToolTip), 49 typeof(LiveToolTipService), 50 new FrameworkPropertyMetadata(null)); 51 52 #region Opacity 53 54 public static double GetTooltipOpacity(DependencyObject obj) 55 { 56 return (double)obj.GetValue(TooltipOpacityProperty); 57 } 58 59 public static void SetTooltipOpacity(DependencyObject obj, double value) 60 { 61 obj.SetValue(TooltipOpacityProperty, value); 62 } 63 64 public static readonly DependencyProperty TooltipOpacityProperty = DependencyProperty.RegisterAttached( 65 "TooltipOpacity", 66 typeof(double), 67 typeof(LiveToolTipService), 68 new FrameworkPropertyMetadata(1.0, OnTooltipOpacityChanged)); 69 70 private static void OnTooltipOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 71 { 72 LiveToolTip liveTooltip = GetLiveToolTip(d); 73 if (liveTooltip != null) 74 { 75 liveTooltip.Opacity = (double)e.NewValue; 76 } 77 } 78 79 #endregion // end of Opacity 80 81 #region IsPropertyProxy property 82 83 public static bool GetIsPropertyProxy(DependencyObject obj) 84 { 85 return (bool)obj.GetValue(IsPropertyProxyProperty); 86 } 87 88 public static void SetIsPropertyProxy(DependencyObject obj, bool value) 89 { 90 obj.SetValue(IsPropertyProxyProperty, value); 91 } 92 93 public static readonly DependencyProperty IsPropertyProxyProperty = DependencyProperty.RegisterAttached( 94 "IsPropertyProxy", 95 typeof(bool), 96 typeof(LiveToolTipService), 97 new FrameworkPropertyMetadata(false)); 98 99 #endregion // end of IsPropertyProxy property 100 101 #endregion 102 103 private static void OnToolTipChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 104 { 105 FrameworkElement source = (FrameworkElement)d; 106 107 if (e.NewValue == null) 108 { 109 source.Loaded -= source_Loaded; 110 source.ClearValue(LiveToolTipProperty); 111 } 112 113 if (GetIsPropertyProxy(source)) return; 114 115 var content = e.NewValue; 116 117 DataTemplate template = content as DataTemplate; 118 if (template != null) 119 { 120 content = template.LoadContent(); 121 } 122 123 LiveToolTip tooltip = null; 124 if (e.NewValue is LiveToolTip) 125 { 126 tooltip = e.NewValue as LiveToolTip; 127 } 128 else 129 { 130 tooltip = new LiveToolTip { Content = content }; 131 } 132 133 if (tooltip == null && e.OldValue == null) 134 { 135 tooltip = new LiveToolTip { Content = content }; 136 } 137 138 if (tooltip != null) 139 { 140 SetLiveToolTip(source, tooltip); 141 if (!source.IsLoaded) 142 { 143 source.Loaded += source_Loaded; 144 } 145 else 146 { 147 AddTooltip(source); 148 } 149 } 150 } 151 152 private static void AddTooltipForElement(FrameworkElement source, LiveToolTip tooltip) 153 { 154 AdornerLayer layer = AdornerLayer.GetAdornerLayer(source); 155 156 LiveToolTipAdorner adorner = new LiveToolTipAdorner(source, tooltip); 157 layer.Add(adorner); 158 } 159 160 private static void source_Loaded(object sender, RoutedEventArgs e) 161 { 162 FrameworkElement source = (FrameworkElement)sender; 163 164 if (source.IsLoaded) 165 { 166 AddTooltip(source); 167 } 168 } 169 170 private static void AddTooltip(FrameworkElement source) 171 { 172 if (DesignerProperties.GetIsInDesignMode(source)) return; 173 174 LiveToolTip tooltip = GetLiveToolTip(source); 175 176 Window window = Window.GetWindow(source); 177 FrameworkElement child = source; 178 FrameworkElement parent = null; 179 if (window != null) 180 { 181 while (parent != window) 182 { 183 parent = (FrameworkElement)VisualTreeHelper.GetParent(child); 184 child = parent; 185 186 if (parent == null) 187 return; 188 189 var nameScope = NameScope.GetNameScope(parent); 190 if (nameScope != null) 191 { 192 string nameScopeName = nameScope.ToString(); 193 if (nameScopeName != "System.Windows.TemplateNameScope") 194 { 195 NameScope.SetNameScope(tooltip, nameScope); 196 break; 197 } 198 } 199 } 200 } 201 202 var binding = BindingOperations.GetBinding(tooltip, LiveToolTip.ContentProperty); 203 if (binding != null) 204 { 205 BindingOperations.ClearBinding(tooltip, LiveToolTip.ContentProperty); 206 BindingOperations.SetBinding(tooltip, LiveToolTip.ContentProperty, binding); 207 } 208 209 Binding dataContextBinding = new Binding { Path = new PropertyPath("DataContext"), Source = source }; 210 tooltip.SetBinding(LiveToolTip.DataContextProperty, dataContextBinding); 211 212 tooltip.Owner = source; 213 if (GetTooltipOpacity(source) != (double)LiveToolTipService.TooltipOpacityProperty.DefaultMetadata.DefaultValue) 214 { 215 tooltip.Opacity = LiveToolTipService.GetTooltipOpacity(source); 216 } 217 218 AddTooltipForElement(source, tooltip); 219 } 220 } 221}