1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using Windows.UI.Xaml;
5: using Windows.UI.Xaml.Controls;
6: using Windows.UI.Xaml.Controls.Primitives;
7: using Windows.UI.Xaml.Shapes;
8: using Windows.UI.Xaml.Data;
9: using Windows.UI.Xaml.Documents;
10: using Windows.UI.Xaml.Input;
11: using Windows.UI.Xaml.Media;
12:
13: // The Templated Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234235
14:
15:
16: namespace SimpleSliderDemo.Controls
17: {
18: [TemplatePart(Name = ThumbPartName, Type = typeof(Thumb))]
19: [TemplatePart(Name = TrackPartName, Type = typeof(Rectangle))]
20: public sealed class SimpleSlider : Control
21: {
22:
23: #region Fields
24:
25: private const string ThumbPartName = "PART_Thumb";
26: private const string TrackPartName = "PART_Track";
27:
28: private Thumb thumb;
29: private Rectangle rectangle;
30:
31: #endregion //Fields
32:
33: #region Constructor
34: public SimpleSlider()
35: {
36: this.DefaultStyleKey = typeof(SimpleSlider);
37: }
38: #endregion //Constructor
39:
40: #region Properties
41:
42: #region MinimumValue
43:
44: // Using a DependencyProperty as the backing store for MinimumValue. This enables animation, styling, binding, etc...
45: public static readonly DependencyProperty MinimumValueProperty =
46: DependencyProperty.Register("MinimumValue", typeof(object), typeof(SimpleSlider), new PropertyMetadata(0.0));
47:
48: ///
49: /// Gets or sets the minimum.
50: ///
51: public double MinimumValue
52: {
53: get { return (double)GetValue(MinimumValueProperty); }
54: set { SetValue(MinimumValueProperty, value); }
55: }
56:
57: #endregion //MinimumValue
58:
59: #region MaximumValue
60:
61: // Using a DependencyProperty as the backing store for MaximumValue. This enables animation, styling, binding, etc...
62: public static readonly DependencyProperty MaximumValueProperty =
63: DependencyProperty.Register("MaximumValue", typeof(object), typeof(SimpleSlider), new PropertyMetadata(0.0));
64:
65: ///
66: /// Gets or sets the maximum.
67: ///
68: public double MaximumValue
69: {
70: get { return (double)GetValue(MaximumValueProperty); }
71: set { SetValue(MaximumValueProperty, value); }
72: }
73:
74: #endregion //MaximumValue
75:
76: #region Value
77:
78: // Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
79: public static readonly DependencyProperty ValueProperty =
80: DependencyProperty.Register("Value", typeof(object), typeof(SimpleSlider), new PropertyMetadata(0.0, OnValueChanged));
81:
82: ///
83: /// Gets or sets the value.
84: ///
85: public double Value
86: {
87: get { return (double)GetValue(ValueProperty); }
88: set
89: {
90: SetValue(ValueProperty, value);
91: }
92: }
93: #endregion //Value
94:
95: #endregion //Properties
96:
97: #region Methods
98:
99: #region OnApplyTemplate
100: ///
101: /// When overridden in a derived class, is invoked whenever application code or internal processes call .
102: ///
103: protected override void OnApplyTemplate() // OnApplyTemplateCore()
104: {
105: //base.OnApplyTemplateCore();
106:
107: base.OnApplyTemplate();
108:
109: this.thumb = this.GetTemplateChild(ThumbPartName) as Thumb;
110: if (this.thumb != null)
111: {
112: this.thumb.DragDelta += this.Thumb_DragDelta;
113: }
114:
115: this.rectangle = this.GetTemplateChild(TrackPartName) as Rectangle;
116:
117: this.SizeChanged += new SizeChangedEventHandler(SimpleSlider_SizeChanged);
118: }
119: #endregion //OnApplyTemplate
120:
121: #region SimpleSlider_SizeChanged
122: ///
123: /// Called when size changed.
124: ///
125: private void SimpleSlider_SizeChanged(object sender, SizeChangedEventArgs e)
126: {
127: if (e.NewSize.Width != e.PreviousSize.Width)
128: {
129: this.UpdateControlParts();
130: }
131: }
132: #endregion //SimpleSlider_SizeChanged
133:
134: #region OnValueChanged
135: ///
136: /// Called when value changed.
137: ///
138: private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
139: {
140: var customSlider = (SimpleSlider)dependencyObject;
141: customSlider.UpdateControlParts();
142: }
143: #endregion //OnValueChanged
144:
145: #region Thumb_DragDelta
146: ///
147: /// Handles the DragDelta event of the Thumb control.
148: ///
149: private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
150: {
151: var pixelDiff = e.HorizontalChange;
152: var currentLeft = Canvas.GetLeft(this.thumb);
153:
154: // trying to drag too far left
155: if ((currentLeft + pixelDiff) < 0)
156: {
157: this.Value = 0;
158: }
159: // trying to drag too far right
160: else if ((currentLeft + pixelDiff + this.thumb.ActualWidth) > this.ActualWidth)
161: {
162: this.Value = this.MaximumValue;
163: }
164: else
165: {
166: var totalSize = this.ActualWidth;
167: var ratioDiff = pixelDiff / totalSize;
168: var rangeSize = this.MaximumValue - this.MinimumValue;
169: var rangeDiff = rangeSize * ratioDiff;
170: this.Value += rangeDiff;
171: }
172: }
173: #endregion //Thumb_DragDelta
174:
175: #region UpdateControlParts
176: ///
177: /// Updates the control parts.
178: ///
179: private void UpdateControlParts()
180: {
181: double halfTheThumbWith = 0;
182:
183: if (this.thumb != null)
184: {
185: halfTheThumbWith = this.thumb.ActualWidth / 2;
186: }
187:
188: double totalSize = this.ActualWidth - halfTheThumbWith * 2;
189:
190: double ratio = totalSize / (this.MaximumValue - this.MinimumValue);
191:
192: if (this.thumb != null)
193: {
194: Canvas.SetLeft(this.thumb, ratio * this.Value);
195: }
196:
197: if (this.rectangle != null)
198: {
199: this.rectangle.Width = ratio * this.Value + halfTheThumbWith;
200: }
201: }
202: #endregion //UpdateControlParts
203:
204: #endregion //Methods
205: }
206: }