I've created a button which is linked to the following function:
private void btnSetVal_Click_1(object sender, RoutedEventArgs e)
{
//VolumeMeter.Value = Convert.ToInt32(txtValue.Text);
int l_iMilSecs = 1000;
VolumeMeter.fSetVal(20);
Thread.Sleep(l_iMilSecs);
VolumeMeter.Value = 30;
Thread.Sleep(l_iMilSecs);
VolumeMeter.Value = 40;
Thread.Sleep(l_iMilSecs);
VolumeMeter.Value = 50;
Thread.Sleep(l_iMilSecs);
VolumeMeter.Value = 60;
}
The function fSetVal - updates a user control visibility. In run time the btnSetVal_Click_1 put the thread to sleep(as many times I call sleep) but only perform the last call to fSetVal.. I've tried to add the keyword volatile to the function but it doesn't even compile so it's probably not the right way to go.. Any thought how to prevent it?
fSetVal :
public void fSetVal(int p_iNewVal)
{
//Amit: Set the first X(p_iNewVal ) rectangles visible.
int l_iLastVisibleIndex = m_iNumOfRectangles - p_iNewVal -1;
for (int i = m_iNumOfRectangles - 1; i > l_iLastVisibleIndex; --i)
{
unifGridVolumeMeter.Children[i].Visibility = Visibility.Visible;
}
//Amit: Set the rest of the rectangles to invisible:
for (int i = 0; i <= l_iLastVisibleIndex; i++)
{
unifGridVolumeMeter.Children[i].Visibility = Visibility.Hidden;
}
}
The problem is that you're sleeping on the UI thread, which means the UI can't update.
Instead, you should use a timer, e.g. a DispatcherTimer
to call a method repeatedly (until it's finished).
Alternatively, make your method async
and use Task.Delay
instead of Thread.Sleep
:
private async void btnSetVal_Click_1(object sender, RoutedEventArgs e)
{
// TODO: Use a loop instead of this repeated code...
int l_iMilSecs = 1000;
VolumeMeter.fSetVal(20);
await Task.Delay(l_iMilSecs);
VolumeMeter.Value = 30;
await Task.Delay(l_iMilSecs);
VolumeMeter.Value = 40;
await Task.Delay(l_iMilSecs);
VolumeMeter.Value = 50;
await Task.Delay(l_iMilSecs);
VolumeMeter.Value = 60;
}
Another alternative is to make use of the extensive animation support within WPF...
See more on this question at Stackoverflow