It seems that CaptureMouse is behaving differently in WPF and Silverlight, in that in the former one it immediately calls OnLostMouseCapture at a Visual, whereas in Silverlight it doesn’t get called if the element didn’t have the mouse capture already (btw, in Silverlight that method is at a UIElement – there is no Visual ancestor as in WPF).
#region --- Events ---
private void OnMouseLeftButtonDown(object source, MouseButtonEventArgs e)
{
if (IsMoveToPointEnabled)
{
MoveThumbToPoint(e.GetPosition(this));
CaptureMouse(); //must do before setting dragging=true, since WPF seems
//to be always calling OnLostMouseCapture on all
//controls, even if they didn't have the mouse capture
dragging = true; //always set, we might not make it to capture the mouse
}
}
private void OnMouseLeftButtonUp(object source, MouseButtonEventArgs e)
{
ReleaseMouseCapture();
dragging = false; //always clear, in case we never had the mouse capture
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (dragging && IsMoveToPointEnabled)
MoveThumbToPoint(e.GetPosition(this));
}
protected override void OnLostMouseCapture(MouseEventArgs e)
{
base.OnLostMouseCapture(e);
dragging = false; //set dragging to false whatever the value of
//IsMoveToPointEnabled (may have changed while dragging)
}
#endregion
The rest of the code of the SliderExt class that I’ve just added to ClipFlair codebase is below, where … is where the code region that was quoted above goes. This class is a descendent of Slider and implements IsMoveToPointEnabled property for Silverlight (in WPF that property exists), plus in WPF it fixes the behavior of the control so that when that property is set, it not only supports moving the slider thumb to the point on its track where mouse button was held down (instead of stepping up/down as is usually done in scrollbars), but also supports dragging from any point in the slider track which WPF’s implementation of IsMouseToPointEnabled didn’t do (it only allowed to drag from the thumb).
//Project: ClipFlair (http://ClipFlair.codeplex.com)
//Filename: SliderExt.cs
//Version: 20140313
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace SliderExtLib
{
public class SliderExt : Slider
{
public SliderExt()
{
//peek into mouse button events (even handled ones)
AddHandler(MouseLeftButtonDownEvent,
new MouseButtonEventHandler(OnMouseLeftButtonDown), true);
AddHandler(MouseLeftButtonUpEvent,
new MouseButtonEventHandler(OnMouseLeftButtonUp), true);
}
#region --- Fields ---
protected bool dragging;
#endregion
#region --- Properties ---
public bool IsMoveToPointEnabled //WPF has this prop (hiding it), doesn't
//implement move to point if you click and drag on the track instead of thumb
{
get { return (bool)GetValue(IsMoveToPointEnabledProperty); }
set { SetValue(IsMoveToPointEnabledProperty, value); }
}
public static readonly DependencyProperty IsMoveToPointEnabledProperty =
DependencyProperty.RegisterAttached("IsMoveToPointEnabled",
typeof(bool), typeof(SliderExt),
new PropertyMetadata(false));
#endregion
#region --- Methods ---
private void MoveThumbToPoint(Point p)
{
if (Orientation == Orientation.Horizontal)
Value = p.X / ActualWidth * Maximum;
else //if (Orientation == Orientation.Vertical)
Value = p.Y / ActualHeight * Maximum;
}
#endregion
...
}
}
The incentive of making such a slider was for using it at the ColorPicker control I’ve just added to the ClipFlair codebase.
Like this:
Like Loading...