Reputation: 1529
I am trying to create a slider
using silverlight
and i am under a situation that i have to drag the slider with certain frequency and it is achieved in wpf using TickFrequency
but i couldnt find the alternative to do so using silverlight.
Suppose my slider is:
Slider slider = new Slider();
In explain what i want to do is:
If i a slider whose max= 10 and min=1 and my slider frequncy=2 so what i want is
when i drag the slider then it must drag by 0->2>4>6>8>10
. Not like : 0->1>2>3>4>5>6>7>8>9>10
Now ,could someone please help me ?
I tried this:
slider.LostMouseCapture += (o, e) =>
{
double distanceFromFactor = slider.Value % 2;
if (distanceFromFactor > 1)
distanceFromFactor = distanceFromFactor - step; //This step is decided dynamically rather 2/0.5/3 or whatever..
slider.Value -= distanceFromFactor;
txtblUnits.Text = Math.Round(slider.Value).ToString() + " units";
};
But the problem is when it works fine when i have slider.Max=4
, slider.Min=-4
and step=2
. But if i do slider.Max=4
, slider.Min=-4
and max =0.5
it still updates the same result as in the previous txtblUnits
but this time was expecting the updates of slider drag like -4->-3.5->3.....->4
.
How to make solution of this ?
Upvotes: 0
Views: 414
Reputation: 6415
The reason your slider will move right to the end just with one drag is that you are handling the ValueChanged
event, and altering the value of the slider within it, which will raise a ValueChanged
event, which alters the value of the slider, which raises a ValueChanged
event ... repeat until bored.
Instead of that you could use the LostMouseCapture
event to detect when the mouse has been released, and then quantise the value to your desired increments. Something like this:
private void MySlider_OnLostMouseCapture(object sender, MouseEventArgs e)
{
var step = 2;
var halfStep = step/2;
var distanceFromFactorOfStep = MySlider.Value % step;
if (distanceFromFactorOfStep > halfStep)
distanceFromFactorOfStep = distanceFromFactorOfStep - step;
MySlider.Value -= distanceFromFactorOfStep;
}
NOTE: this only changes Value
when mouse is released, so you can't use a real-time binding to display the Value in, say, a TextBox
: it will only have a factor-of-2 value after this method has run.
Also you should set SmallChange
and LargeChange
on your Slider to 2, so that your UI can cope with a user clicking or using cursor keys, and not just rely on them dragging.
EDIT: Logic explanation.
(1) To increase/decrease the value in steps you want to limit the slider.Value
to be a multiple of your step size.
(2) Taking the modulo of the raw slider value gives you a 'distance' from the nearest, lowest, factor of your step size.
E.g. With a step size of 2 and a raw slider value of 2.532,
the modulo will be 0.532 (2.532%2 = 0.532).
With a raw slider value of 13.152 the modulo will be 1.152.
(3) You could just take this modulo value and subtract it from your raw value to give you a new slider value that is a multiple of your step.
e.g.
2.532 - 0.532 = 2.
13.152 - 1.152 = 12
(4) But this rounding down means that a raw slider value of 1.99999 (for example) will be converted to 0, rather than the closest multiple of step - which would be 2, for a step size of 2. So to see whether the raw value is closest to the lower multiple or the higher multiple you should compare the modulo to half of the step size.
(5) From the example above, 13.152 is closer to 14 than to 12. You can see this mathematically by comparing the modulo (1.152) to half of the step size (1). If it is larger than half of the step size then you want to use the higher multiple of step. If it is less than half the step size you want to use the lower.
(6) If modulo > halfstep then subtracting the step size from the modulo will give you a value suitable for subtracting from the raw slider value.
e.g.
1.152 - 2 = -0.848
13.152 - -0.848 = 14
Upvotes: 1
Reputation: 222582
You can do like this, Get your sliderValueChanged event to save the current and then add 2 to every change. or Use LargeChange and SmallChange Properties of the slider.
Slider slid = new Slider();
public MainPage()
{
InitializeComponent();
slid.LargeChange = 2.0;
slid.SmallChange = 0.0;
LayoutRoot.Children.Add(slid);
slid.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sldr_ValueChanged);
}
void sldr_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
slid.Value = Math.Round(e.NewValue * 2) / 2;
txtBox1.Text = slid.Value.ToString();
}
Upvotes: 1