Initial Commit
This commit is contained in:
51
Charts/LiveTooltips/LiveTooltip.cs
Normal file
51
Charts/LiveTooltips/LiveTooltip.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Input;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.Charts
|
||||
{
|
||||
public class LiveToolTip : ContentControl
|
||||
{
|
||||
static int nameCounter = 0;
|
||||
static LiveToolTip()
|
||||
{
|
||||
var thisType = typeof(LiveToolTip);
|
||||
|
||||
DefaultStyleKeyProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(thisType));
|
||||
FocusableProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(false));
|
||||
IsHitTestVisibleProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(false));
|
||||
BackgroundProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(Brushes.White));
|
||||
OpacityProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(1.0));
|
||||
BorderBrushProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(Brushes.DarkGray));
|
||||
BorderThicknessProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata(new Thickness(1.0)));
|
||||
}
|
||||
|
||||
public LiveToolTip()
|
||||
{
|
||||
Name = "Microsoft_Research_Dynamic_Data_Display_Charts_LiveToolTip_" + nameCounter;
|
||||
nameCounter++;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public FrameworkElement Owner
|
||||
{
|
||||
get { return (FrameworkElement)GetValue(OwnerProperty); }
|
||||
set { SetValue(OwnerProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty OwnerProperty = DependencyProperty.Register(
|
||||
"Owner",
|
||||
typeof(FrameworkElement),
|
||||
typeof(LiveToolTip),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
#endregion // end of Properties
|
||||
}
|
||||
}
|
||||
126
Charts/LiveTooltips/LiveTooltipAdorner.cs
Normal file
126
Charts/LiveTooltips/LiveTooltipAdorner.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.Charts
|
||||
{
|
||||
public class LiveToolTipAdorner : Adorner
|
||||
{
|
||||
private Canvas canvas = new Canvas { IsHitTestVisible = false };
|
||||
private readonly VisualCollection visualChildren;
|
||||
public LiveToolTipAdorner(UIElement adornedElement, LiveToolTip tooltip)
|
||||
: base(adornedElement)
|
||||
{
|
||||
visualChildren = new VisualCollection(this);
|
||||
|
||||
adornedElement.MouseLeave += adornedElement_MouseLeave;
|
||||
adornedElement.MouseEnter += adornedElement_MouseEnter;
|
||||
adornedElement.PreviewMouseMove += adornedElement_MouseMove;
|
||||
//FrameworkElement frAdornedElement = (FrameworkElement)adornedElement;
|
||||
//frAdornedElement.SizeChanged += frAdornedElement_SizeChanged;
|
||||
|
||||
this.liveTooltip = tooltip;
|
||||
|
||||
tooltip.Visibility = Visibility.Hidden;
|
||||
|
||||
canvas.Children.Add(liveTooltip);
|
||||
AddLogicalChild(canvas);
|
||||
visualChildren.Add(canvas);
|
||||
|
||||
Unloaded += LiveTooltipAdorner_Unloaded;
|
||||
}
|
||||
|
||||
//void frAdornedElement_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
//{
|
||||
// grid.Width = e.NewSize.Width;
|
||||
// grid.Height = e.NewSize.Height;
|
||||
|
||||
// InvalidateMeasure();
|
||||
//}
|
||||
|
||||
void LiveTooltipAdorner_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
canvas.Children.Remove(liveTooltip);
|
||||
}
|
||||
|
||||
void adornedElement_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
liveTooltip.Visibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
void adornedElement_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
liveTooltip.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
Point mousePosition;
|
||||
private void adornedElement_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
liveTooltip.Visibility = Visibility.Visible;
|
||||
mousePosition = e.GetPosition(AdornedElement);
|
||||
InvalidateMeasure();
|
||||
}
|
||||
|
||||
private void ArrangeTooltip()
|
||||
{
|
||||
Size tooltipSize = liveTooltip.DesiredSize;
|
||||
|
||||
Point location = mousePosition;
|
||||
location.Offset(-tooltipSize.Width / 2, -tooltipSize.Height - 1);
|
||||
|
||||
liveTooltip.Arrange(new Rect(location, tooltipSize));
|
||||
}
|
||||
|
||||
LiveToolTip liveTooltip;
|
||||
public LiveToolTip LiveTooltip
|
||||
{
|
||||
get { return liveTooltip; }
|
||||
}
|
||||
|
||||
#region Overrides
|
||||
|
||||
protected override Visual GetVisualChild(int index)
|
||||
{
|
||||
return visualChildren[index];
|
||||
}
|
||||
|
||||
protected override int VisualChildrenCount
|
||||
{
|
||||
get { return visualChildren.Count; }
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
{
|
||||
foreach (UIElement item in visualChildren)
|
||||
{
|
||||
item.Measure(constraint);
|
||||
}
|
||||
|
||||
liveTooltip.Measure(constraint);
|
||||
|
||||
return base.MeasureOverride(constraint);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
foreach (UIElement item in visualChildren)
|
||||
{
|
||||
item.Arrange(new Rect(item.DesiredSize));
|
||||
}
|
||||
|
||||
ArrangeTooltip();
|
||||
|
||||
return finalSize;
|
||||
}
|
||||
|
||||
#endregion // end of overrides
|
||||
}
|
||||
}
|
||||
217
Charts/LiveTooltips/LiveTooltipService.cs
Normal file
217
Charts/LiveTooltips/LiveTooltipService.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user