WP7, C#, Increase slider value by holding a button - c#

I have to increase the slider control value while holding a button.
As long as I am holding the button the slider has to keep increasing.
For example, the scenario is typical with volume control.
I have a slider for volume and a button Increase for volume.
Now as long as I keep holding the Increase button, the volume (marker) in the slider should keep increasing continuously till I release the button.
What I have achieved is changing the value of the slider on individual click events on the button.
Kindly give your suggestions on how I can achieve this.

According to the book there should be RepeatButton. In this case it will perfectly suit your needs. Try to avoid Thread sleeps. Freezes are not pretty good thing. It's one of first candidates for refactoring.

public bool Ok = false;
public void Do()
{
while (Ok)
{
this.Text += ".";
System.Threading.Thread.Sleep(100);
Application.DoEvents();
//I added dots to the form text , You do your own mission
}
}
private void btnLouder_MouseDown(object sender, MouseEventArgs e)
{
Ok = true;
Do();
}
private void btnLouder_MouseUp(object sender, MouseEventArgs e)
{
Ok = false;
}
Add a TrackBar control to the form and then
Replace the code in While block with this one, it does exactly what you want :
if(trackBar1.Value < trackBar1.Maximum)
trackBar1.Value += 1;

Related

Check time after a mousebuttondown before the mousebuttonup

I think that must be only a little problem, but I can't get a clear thought on that. Someone an idea?
I have some borders on a canvas (filled with images) and i want to click the border (i do this with the OnMouseLeftButtonDown) where the border gets red (so the user knows for sure which object he had clicked) and then, after 1 or 2 seconds, when the mousebutton is still pushed down, a drag'n'drop should start.
At first I had the borders inside buttons, but the clickevent seems to conflict with the dragevent. So I got rid of the buttons and did everything inside the borders directly, which works well also. But how can I start the drag after the mousebuttondown and stop it when the mousebuttonup happens before the time runs out.
Someone an idea for a clean solution?
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_source = sender as Border;
Mouse.Capture(_source);
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_source = null;
Mouse.Capture(null);
}
and in event OnMouseMove you can modify border margins depends on mouse position but after checking if _source is type of Border.
var position = e.GetPosition(Canvas);
EDIT:
For that time you can add property Stopwatch _watch, and inside OnMouseLeftButtonDown event handler you can do it:
_watch = Stopwatch.StartNew();
in OnMouseLeftButtonUp:
_watch.Stop();
and in OnMouseMove before your code:
while (_watch.ElapsedMilliseconds < 2000 && _watch.IsRunning)
{
Thread.Sleep(100);
}

Update mediaElement based on slider value

I have a mediaElement and a slider.
The slider's maximum value is video's duration in seconds (for example if the video is 2 minutes, the slider's value is 120).
I want to update the mediaElement.Position based on the slider's value but the problems is that I dont want to update the position until the user FINISHED manipulating the value.
so what I did is 2 functions:
private void DurationSlider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
SeekToMediaPosition();
}
this function applys if the user stopped manipulating the slider.
private void DurationSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
SeekToMediaPosition();
}
this function applys if the user clicked on different value in the slider.
The problem is that they clash.
Manipulating the slider cause the value to be changed...
so What I did is added this function:
bool manipulating = false;
private void DurationSlider_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
manipulating = true;
}
and in the ValueChanged function I checked whether manipulating = true or not
It solved half of the problem - it does not change the video position while manipulating (until I finish) but if I click on different position on the slider (without releasing the mouse) and continue manipulating the slider's value - it changes the video position to where I clicked on the slider and then changes again to where I ended the manipulation.
So whats wrong?
I want to change the video position ONLY when the user released the mouse.
I cant find event that fires what I want...
You could use PointerCaptureLost Event to determine the position after the user finished dragging the control.
<Slider PointerCaptureLost=="Slider_PointerCaptureLost"
Height="27" Margin="132,162,0,0" VerticalAlignment="Top" Width="303"/>
Then in code behind.
private void Slider_PointerCaptureLost(object sender, DragCompletedEventArgs e)
{
Slider s = sender as Slider;
// Your code
MessageBox.Show(s.Value.ToString());
}

Track Bar Only fire event on final value not ever time value changes

I am working on a pretty basic C# visual studio forms application but am having some issue getting the track bar to act as I want it to so hoping someone in the community might have a solution for this.
What I have is a pretty basic application with the main part being a track bar with a value of 0 to 100. The user sets the value of the track to represent "the amount of work to perform" at which point the program reaches out to some devices and tells them to do "x" amount of work (x being the value of the trackbar). So what I do is use the track bars scroll event to catch when the track bars value has changed and inside the handler call out to the devices and tells them how much work to do.
My issue is that my event handler is called for each value between where the track bar currently resides and where ever it ends. So if it is slid from 10 to 30, my event handler is called 20 times which means I am reaching out to my devices and telling them to run at values I don't even want them to run at. Is there someway only to event when scroll has stopped happening so you can check the final value?
Just check a variable, if the user clicked the track bar. If so, delay the output.
bool clicked = false;
trackBar1.Scroll += (s,
e) =>
{
if (clicked)
return;
Console.WriteLine(trackBar1.Value);
};
trackBar1.MouseDown += (s,
e) =>
{
clicked = true;
};
trackBar1.MouseUp += (s,
e) =>
{
if (!clicked)
return;
clicked = false;
Console.WriteLine(trackBar1.Value);
};
For the problem #roken mentioned, you can set LargeChange and SmallChange to 0.
Try the MouseCaptureChanged event - that is the best for this task
A user could also move the track bar multiple times in a short period of time, or click on the track multiple times to increment the thumb over instead of dragging the thumb. All being additional cases where the value that registers at the end of a "thumb move" is not really the final value your user desires.
Sounds like you need a button to confirm the change, which would then capture the current value of the trackbar and send it off to your devices.
Try this with the trackbar_valuechanged event handler:
trackbar_valuechanged(s,e) {
if(trackbar.value == 10){
//Do whatever you want
} else{
//Do nothing or something else
}
}
I found a fairly reliable way to do this is to use a timer hooked up in the trackbar.Scroll event:
private Timer _scrollingTimer = null;
private void trackbar_Scroll(object sender, EventArgs e)
{
if (_scrollingTimer == null)
{
// Will tick every 500ms (change as required)
_scrollingTimer = new Timer()
{
Enabled = false,
Interval = 500,
Tag = (sender as TrackBar).Value
};
_scrollingTimer.Tick += (s, ea) =>
{
// check to see if the value has changed since we last ticked
if (trackBar.Value == (int)_scrollingTimer.Tag)
{
// scrolling has stopped so we are good to go ahead and do stuff
_scrollingTimer.Stop();
// Do Stuff Here . . .
_scrollingTimer.Dispose();
_scrollingTimer = null;
}
else
{
// record the last value seen
_scrollingTimer.Tag = trackBar.Value;
}
};
_scrollingTimer.Start();
}
}
I had this problem just now as I'm implementing a built in video player and would like the user to be able to change the position of the video but I didn't want to overload the video playback API by sending it SetPosition calls for every tick the user passed on the way to his/her final destination.
This is my solution:
First, the arrow keys are a problem. You can try your best to handle the arrow keys via a timer or some other mechanism but I found it more pain than it is worth. So set the property SmallChange and LargeChange to 0 as #Matthias mentioned.
For mouse input, the user is going to have to click down, move it, and let go so handle the MouseDown, MouseUp, and the Scroll events of the trackbar like so:
private bool trackbarMouseDown = false;
private bool trackbarScrolling = false;
private void trackbarCurrentPosition_Scroll(object sender, EventArgs e)
{
trackbarScrolling = true;
}
private void trackbarCurrentPosition_MouseUp(object sender, MouseEventArgs e)
{
if (trackbarMouseDown == true && trackbarScrolling == true)
Playback.SetPosition(trackbarCurrentPosition.Value);
trackbarMouseDown = false;
trackbarScrolling = false;
}
private void trackbarCurrentPosition_MouseDown(object sender, MouseEventArgs e)
{
trackbarMouseDown = true;
}
I had a similar problem, only with a range TrackBar Control. Same idea applies to this also, only it's easier for this case.
I handled the MouseUp Event on the TrackBar to launch the procedures I needed, only after you would let go of the mouse button. This works if you drag the bar to your desired position or just click it.
private void rangeTrackBarControl1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
YourProcedureHere();
}
i solved the problem for my application with two events:
catch the Trackbar-ValueChange-Event
whithin the value-change event disable the valuechange event and enable the MouseUp-Event
public MainWindow()
{
//Event for new Trackbar-Value
trackbar.ValueChanged += new System.EventHandler(trackbar_ValueChanged);
}
private void trackbar_ValueChanged(object sender, EventArgs e)
{
//enable Trackbar Mouse-ButtonUp-Event
trackbar.MouseUp += ch1_slider_MouseUp;
//disable Trackbar-ValueChange-Event
trackbar.ValueChanged -= ch1_slider_ValueChanged;
}
private void trackbar_MouseUp(object sender, EventArgs e)
{
//enable Trackbar-ValueChange-Event again
trackbar.ValueChanged += new System.EventHandler(trackbar_ValueChanged);
//disable Mouse-ButtonUp-Event
trackbar.MouseUp -= trackbar_MouseUp;
//This is the final trackbar-value
textBox.AppendText(trackbar.Value);
}
ATTENTION: this works if the trackbar is moved by mose. It is also possible to move the trackbar by keyboard. Then futher code must be implemented to handle this event.

C# Fade-in and fade-out transparency when form is being moved

I have the code to make the form partially transparent when is being moved, but I want to know if it's possible to add fade-in and fade-out effects when I start moving and stop moving the form.
EDIT
The code I am using to add transparency to the form is:
bool canMove = false;
private void Form1_Load(object sender, EventArgs e)
{
canMove = true;
}
private void Form1_Move(object sender, EventArgs e)
{
if (canMove)
{
this.Opacity = 0.7;
}
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
this.Opacity = 1;
}
You should use a Timer control, set the opacity in timer's tick event. until the form stops moving (define a variable like isMoving and set it to true/false based on form's status).
You can find an example of setting opacity in timer's tick event in my article about a fading label. Use Google translator to read it.
Hope this helps.
You could take a Timer control, you could then start the timer when form starts moving and set the transparency of the form to some value, and on each tick of the Timer, make the transparency to decrease and on some value make it to increase. If you want to have the fadein fadeout effect when form stops moving, you can do the same when the form has moved.

trying to add a "fast forward" like function to a button in c#

so i have a button, i'm trying to add a function that uses System.Diagnostics.Stopwatch to a button similar to a fast forward or rewind. when i hold down the button for a second i want it to do something stupid, like so:
private void button_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var stopWatch = Stopwatch.StartNew();
if (stopWatch.ElapsedTicks < 1000)
{
lbl1.Content = "Quickpress";
}
else if (stopWatch.ElapsedTicks >1000)
{
HAVE SOME ACTION HAPPEN HERE EVERY .5 SECONDS (how do i do it)
}
}
now, this is much simpler than what i want to do, but if the user presses the button for a long time, i want an action to happen every .5 seconds, how do i do it?
the mousedown event fires, it just always selects the short press, even if i hold the button down.
The RepeatButton is probably what you are looking for, it would encapsulate the periodic behavior but i don't know if there is a way to tell a short click from a holding click.
Edit: It seems to me you still need a field (well, you could use the Tag) to account for the state, e.g.
<RepeatButton
Click="RepeatButton_Click"
PreviewMouseLeftButtonUp="RepeatButton_MouseLeftButtonUp"
Interval="500" Delay="1000" Content="Buton" />
int _clickCount = 0;
private void RepeatButton_Click(object sender, RoutedEventArgs e)
{
if (_clickCount > 0)
{
// Repeated hold action
}
_clickCount++;
}
private void RepeatButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_clickCount == 1)
{
// Short click action
}
_clickCount = 0;
}
(Note that the above code is far from clean, there are click logic issues for example as the reset should occur on mouse up but the short click action should only be performed if the mouse is still over the button, as the code is now the action will always happen (if the if condition is met of course))
You need to reuse the existing Stopwatch instance by storing it in a field in your class.

Categories