using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Threading;
namespace ExtendedGrid.Classes
{
///
/// Displays a ToolTip next to the ScrollBar thumb while it is being dragged.
///
public static class ScrollingPreviewService
{
public static DataTemplate GetVerticalScrollingPreviewTemplate(DependencyObject obj)
{
return (DataTemplate) obj.GetValue(VerticalScrollingPreviewTemplateProperty);
}
public static void SetVerticalScrollingPreviewTemplate(DependencyObject obj, DataTemplate value)
{
obj.SetValue(VerticalScrollingPreviewTemplateProperty, value);
}
///
/// Allows for specifying a ContentTemplate for a ToolTip that will appear next to the
/// vertical ScrollBar while dragging the thumb.
///
public static readonly DependencyProperty VerticalScrollingPreviewTemplateProperty =
DependencyProperty.RegisterAttached("VerticalScrollingPreviewTemplate", typeof (DataTemplate),
typeof (ScrollingPreviewService),
new FrameworkPropertyMetadata(null,
OnVerticalScrollingPreviewTemplateChanged));
private static void OnVerticalScrollingPreviewTemplateChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
if ((e.OldValue == null) && (e.NewValue != null))
{
PostAttachToEvents(obj, (DataTemplate) e.NewValue, true);
}
else
{
throw new NotSupportedException("Cannot change the template once it has been set.");
}
}
public static void OnVerticalScrollingPreviewTemplateChanged(ScrollViewer obj,
DataTemplate datatemplate)
{
obj.Dispatcher.BeginInvoke((NoParamCallback)(() => AttachToEvents(obj, datatemplate, true)),
DispatcherPriority.Loaded);
}
public static DataTemplate GetHorizontalScrollingPreviewTemplate(DependencyObject obj)
{
return (DataTemplate) obj.GetValue(HorizontalScrollingPreviewTemplateProperty);
}
public static void SetHorizontalScrollingPreviewTemplate(DependencyObject obj, DataTemplate value)
{
obj.SetValue(HorizontalScrollingPreviewTemplateProperty, value);
}
///
/// Allows for specifying a ContentTemplate for a ToolTip that will appear next to the
/// horizontal ScrollBar while dragging the thumb.
///
public static readonly DependencyProperty HorizontalScrollingPreviewTemplateProperty =
DependencyProperty.RegisterAttached("HorizontalScrollingPreviewTemplate", typeof (DataTemplate),
typeof (ScrollingPreviewService),
new FrameworkPropertyMetadata(null,
OnHorizontalScrollingPreviewTemplateChanged));
private static void OnHorizontalScrollingPreviewTemplateChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
if ((e.OldValue == null) && (e.NewValue != null))
{
PostAttachToEvents(obj, (DataTemplate) e.NewValue, false);
}
}
#region Event Handling
private static void PostAttachToEvents(DependencyObject obj, DataTemplate dataTemplate, bool vertical)
{
// Most likely, the control hasn't expanded its template, wait until
// Loaded priority is reached before looking for elements.
obj.Dispatcher.BeginInvoke((NoParamCallback) (() => AttachToEvents(obj, dataTemplate, vertical)),
DispatcherPriority.Loaded);
}
private delegate void NoParamCallback();
private const double Epsilon = 0;
private static void AttachToEvents(DependencyObject obj, DataTemplate dataTemplate, bool vertical)
{
DependencyObject source = obj;
var scrollViewer = FindElementOfType(obj as FrameworkElement);
if (scrollViewer != null)
{
string scrollBarPartName = vertical ? "PART_VerticalScrollBar" : "PART_HorizontalScrollBar";
var scrollBar = FindName(scrollBarPartName, scrollViewer);
if (scrollBar != null)
{
var track = FindName