1: using System;
2: using System.Net;
3: using System.Windows;
4: using System.Windows.Controls;
5: using System.Windows.Documents;
6: using System.Windows.Ink;
7: using System.Windows.Input;
8: using System.Windows.Media;
9: using System.Windows.Media.Animation;
10: using System.Windows.Shapes;
11: using System.Windows.Controls.Primitives;
12: using System.Windows.Threading;
13:
14: namespace VirtualizedSlider
15: {
16: public class CustomSlider : Slider
17: {
18: public Thumb horizontalThumb;
19: private FrameworkElement horizontalLeftTrack;
20: private FrameworkElement horizontalRightTrack;
21: private double oldValue = 0, newValue = 0, prevNewValue = 0;
22: public event RoutedPropertyChangedEventHandler<double> MyValueChanged;
23: public event RoutedPropertyChangedEventHandler<double> MyValueChangedInDrag;
24:
25: private DispatcherTimer dragtimer = new DispatcherTimer();
26: private double dragTimeElapsed = 0;
27: private const short DragWaitThreshold = 200, DragWaitInterval = 100;
28: public Rectangle progressRect = null;
29: private bool dragSeekJustFired = false;
30:
31: public CustomSlider()
32: {
33: this.ValueChanged += new RoutedPropertyChangedEventHandler<double>(CustomSlider_ValueChanged);
34: dragtimer.Interval = new TimeSpan(0, 0, 0, 0, DragWaitInterval);
35: dragtimer.Tick += new EventHandler(dragtimer_Tick);
36:
37: }
38:
39: void dragtimer_Tick(object sender, EventArgs e)
40: {
41: dragTimeElapsed += DragWaitInterval;
42: if (dragTimeElapsed >= DragWaitThreshold)
43: {
44: RoutedPropertyChangedEventHandler<double> handler = MyValueChangedInDrag;
45: if ((handler != null) && (newValue != prevNewValue))
46: {
47: handler(this, new RoutedPropertyChangedEventArgs<double>(oldValue, newValue));
48: dragSeekJustFired = true;
49: prevNewValue = newValue;
50: }
51: dragTimeElapsed = 0;
52: }
53: }
54:
55: void CustomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
56: {
57: oldValue = e.OldValue;
58: newValue = e.NewValue;
59: if (horizontalThumb.IsDragging)
60: {
61: dragTimeElapsed = 0;
62: dragtimer.Stop();
63: dragtimer.Start();
64: dragSeekJustFired = false;
65: }
66: }
67:
68: public override void OnApplyTemplate()
69: {
70: base.OnApplyTemplate();
71:
72: horizontalThumb = GetTemplateChild("HorizontalThumb") as Thumb;
73:
74: horizontalLeftTrack = GetTemplateChild("LeftTrack") as FrameworkElement;
75: horizontalRightTrack = GetTemplateChild("RightTrack") as FrameworkElement;
76: progressRect = GetTemplateChild("progressRect") as Rectangle;
77:
78: if (horizontalLeftTrack != null) horizontalLeftTrack.MouseLeftButtonDown += new MouseButtonEventHandler(OnMoveThumbToMouse);
79: if (horizontalRightTrack != null) horizontalRightTrack.MouseLeftButtonDown += new MouseButtonEventHandler(OnMoveThumbToMouse);
80:
81: horizontalThumb.DragCompleted += new DragCompletedEventHandler(DragCompleted);
82: progressRect.Width = this.Width;
83: }
84:
85: private void OnMoveThumbToMouse(object sender, MouseButtonEventArgs e)
86: {
87: e.Handled = true;
88: Point p = e.GetPosition(this);
89:
90: if (this.Orientation == Orientation.Horizontal)
91: {
92: Value = (p.X - (horizontalThumb.ActualWidth / 2)) / (ActualWidth - horizontalThumb.ActualWidth) * Maximum;
93: }
94: RoutedPropertyChangedEventHandler<double> handler = MyValueChanged;
95: if (handler != null)
96: {
97: handler(this, new RoutedPropertyChangedEventArgs<double>(oldValue, Value));
98: }
99: }
100:
101: private void DragCompleted(object sender, DragCompletedEventArgs e)
102: {
103: dragtimer.Stop();
104: dragTimeElapsed = 0;
105: RoutedPropertyChangedEventHandler<double> handler = MyValueChanged;
106: if ((handler != null) && (!dragSeekJustFired))
107: {
108: handler(this, new RoutedPropertyChangedEventArgs<double>(oldValue, this.Value));
109: }
110: }
111: }
112: }