PageRenderTime 41ms CodeModel.GetById 17ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/Main/src/DynamicDataDisplay/Charts/LiveTooltips/LiveTooltipService.cs

#
C# | 221 lines | 180 code | 41 blank | 0 comment | 31 complexity | b42fba95a6e56b44015485ac3f4d20a5 MD5 | raw file
  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}