218 lines
5.5 KiB
C#
218 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Data;
|
|
using System.ComponentModel;
|
|
|
|
namespace Microsoft.Research.DynamicDataDisplay.Charts
|
|
{
|
|
public static class LiveToolTipService
|
|
{
|
|
|
|
# region Properties
|
|
|
|
public static object GetToolTip(DependencyObject obj)
|
|
{
|
|
return (object)obj.GetValue(ToolTipProperty);
|
|
}
|
|
|
|
public static void SetToolTip(DependencyObject obj, object value)
|
|
{
|
|
obj.SetValue(ToolTipProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty ToolTipProperty = DependencyProperty.RegisterAttached(
|
|
"ToolTip",
|
|
typeof(object),
|
|
typeof(LiveToolTipService),
|
|
new FrameworkPropertyMetadata(null, OnToolTipChanged));
|
|
|
|
private static LiveToolTip GetLiveToolTip(DependencyObject obj)
|
|
{
|
|
return (LiveToolTip)obj.GetValue(LiveToolTipProperty);
|
|
}
|
|
|
|
private static void SetLiveToolTip(DependencyObject obj, LiveToolTip value)
|
|
{
|
|
obj.SetValue(LiveToolTipProperty, value);
|
|
}
|
|
|
|
private static readonly DependencyProperty LiveToolTipProperty = DependencyProperty.RegisterAttached(
|
|
"LiveToolTip",
|
|
typeof(LiveToolTip),
|
|
typeof(LiveToolTipService),
|
|
new FrameworkPropertyMetadata(null));
|
|
|
|
#region Opacity
|
|
|
|
public static double GetTooltipOpacity(DependencyObject obj)
|
|
{
|
|
return (double)obj.GetValue(TooltipOpacityProperty);
|
|
}
|
|
|
|
public static void SetTooltipOpacity(DependencyObject obj, double value)
|
|
{
|
|
obj.SetValue(TooltipOpacityProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty TooltipOpacityProperty = DependencyProperty.RegisterAttached(
|
|
"TooltipOpacity",
|
|
typeof(double),
|
|
typeof(LiveToolTipService),
|
|
new FrameworkPropertyMetadata(1.0, OnTooltipOpacityChanged));
|
|
|
|
private static void OnTooltipOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
LiveToolTip liveTooltip = GetLiveToolTip(d);
|
|
if (liveTooltip != null)
|
|
{
|
|
liveTooltip.Opacity = (double)e.NewValue;
|
|
}
|
|
}
|
|
|
|
#endregion // end of Opacity
|
|
|
|
#region IsPropertyProxy property
|
|
|
|
public static bool GetIsPropertyProxy(DependencyObject obj)
|
|
{
|
|
return (bool)obj.GetValue(IsPropertyProxyProperty);
|
|
}
|
|
|
|
public static void SetIsPropertyProxy(DependencyObject obj, bool value)
|
|
{
|
|
obj.SetValue(IsPropertyProxyProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty IsPropertyProxyProperty = DependencyProperty.RegisterAttached(
|
|
"IsPropertyProxy",
|
|
typeof(bool),
|
|
typeof(LiveToolTipService),
|
|
new FrameworkPropertyMetadata(false));
|
|
|
|
#endregion // end of IsPropertyProxy property
|
|
|
|
#endregion
|
|
|
|
private static void OnToolTipChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
FrameworkElement source = (FrameworkElement)d;
|
|
|
|
if (e.NewValue == null)
|
|
{
|
|
source.Loaded -= source_Loaded;
|
|
source.ClearValue(LiveToolTipProperty);
|
|
}
|
|
|
|
if (GetIsPropertyProxy(source)) return;
|
|
|
|
var content = e.NewValue;
|
|
|
|
DataTemplate template = content as DataTemplate;
|
|
if (template != null)
|
|
{
|
|
content = template.LoadContent();
|
|
}
|
|
|
|
LiveToolTip tooltip = null;
|
|
if (e.NewValue is LiveToolTip)
|
|
{
|
|
tooltip = e.NewValue as LiveToolTip;
|
|
}
|
|
else
|
|
{
|
|
tooltip = new LiveToolTip { Content = content };
|
|
}
|
|
|
|
if (tooltip == null && e.OldValue == null)
|
|
{
|
|
tooltip = new LiveToolTip { Content = content };
|
|
}
|
|
|
|
if (tooltip != null)
|
|
{
|
|
SetLiveToolTip(source, tooltip);
|
|
if (!source.IsLoaded)
|
|
{
|
|
source.Loaded += source_Loaded;
|
|
}
|
|
else
|
|
{
|
|
AddTooltip(source);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void AddTooltipForElement(FrameworkElement source, LiveToolTip tooltip)
|
|
{
|
|
AdornerLayer layer = AdornerLayer.GetAdornerLayer(source);
|
|
|
|
LiveToolTipAdorner adorner = new LiveToolTipAdorner(source, tooltip);
|
|
layer.Add(adorner);
|
|
}
|
|
|
|
private static void source_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
FrameworkElement source = (FrameworkElement)sender;
|
|
|
|
if (source.IsLoaded)
|
|
{
|
|
AddTooltip(source);
|
|
}
|
|
}
|
|
|
|
private static void AddTooltip(FrameworkElement source)
|
|
{
|
|
if (DesignerProperties.GetIsInDesignMode(source)) return;
|
|
|
|
LiveToolTip tooltip = GetLiveToolTip(source);
|
|
|
|
Window window = Window.GetWindow(source);
|
|
FrameworkElement child = source;
|
|
FrameworkElement parent = null;
|
|
if (window != null)
|
|
{
|
|
while (parent != window)
|
|
{
|
|
parent = (FrameworkElement)VisualTreeHelper.GetParent(child);
|
|
child = parent;
|
|
var nameScope = NameScope.GetNameScope(parent);
|
|
if (nameScope != null)
|
|
{
|
|
string nameScopeName = nameScope.ToString();
|
|
if (nameScopeName != "System.Windows.TemplateNameScope")
|
|
{
|
|
NameScope.SetNameScope(tooltip, nameScope);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var binding = BindingOperations.GetBinding(tooltip, LiveToolTip.ContentProperty);
|
|
if (binding != null)
|
|
{
|
|
BindingOperations.ClearBinding(tooltip, LiveToolTip.ContentProperty);
|
|
BindingOperations.SetBinding(tooltip, LiveToolTip.ContentProperty, binding);
|
|
}
|
|
|
|
Binding dataContextBinding = new Binding { Path = new PropertyPath("DataContext"), Source = source };
|
|
tooltip.SetBinding(LiveToolTip.DataContextProperty, dataContextBinding);
|
|
|
|
tooltip.Owner = source;
|
|
if (GetTooltipOpacity(source) != (double)LiveToolTipService.TooltipOpacityProperty.DefaultMetadata.DefaultValue)
|
|
{
|
|
tooltip.Opacity = LiveToolTipService.GetTooltipOpacity(source);
|
|
}
|
|
|
|
AddTooltipForElement(source, tooltip);
|
|
}
|
|
}
|
|
}
|