Simple animation in MVVM WPF application
I have a MVVM application that has a slider bar and when the user changes the slider bar it updates a graphic on the screen and updates some plots. This all works when the user changes the position of the slider, I would like to add a 'Play' button that automatically moves the slider and everything updates. I have tried the following code to do that and when I try it nothing changes on the 开发者_开发技巧screen. I have confirmed that it is indeed running the code and changing the 'SliderPos' variable. What am I missing?
private void VSMPlayer()
{
SliderPos = 0;
const int speed = 1;
while (SliderPos < SliderLength)
{
Thread.Sleep(100 / speed);
SliderPos = SliderPos + 20;
}
// todo finish this function
}
For clarity's sake here is the SliderPos property
public double SliderPos { get { return this.sliderPos; }
set
{
this.sliderPos = value;
SetCursorLocation();
SetParameters();
this.RaisePropertyChanged("SliderPos");
}
}
The class owning SliderPos
needs to implement INotifyPropertyChanged
. (If your Slider.Value
is bound to that property)
Edit: This alone does not work, as Will correctly noted the UI-Thread is sleeping.
You could try something like this, it works:
SliderPosition = 0;
DispatcherTimer timer = null;
timer = new DispatcherTimer(TimeSpan.FromSeconds(0.1), DispatcherPriority.Render, delegate
{
SliderPosition += 20;
if (SliderPosition > 100) timer.Stop();
},
Dispatcher.CurrentDispatcher);
timer.Start();
Edit2: If you are not modifying any UI-Thread-Owned controls you can just use any thread apart from the UI-Thread, e.g.:
SliderPosition = 0;
new Thread(new ThreadStart(delegate
{
while (SliderPosition < 100)
{
Thread.Sleep(100);
SliderPosition += 20;
}
})).Start();
Look at this similar solution:
ViewModel:
public class MainVM : INotifyPropertyChanged
{
public int SliderLength
{
get
{
return Names.Count - 1;
}
}
private void VSMPlayer()
{
SliderPos = 0;
const int speed = 1;
while (SliderPos < SliderLength)
{
Thread.Sleep(100 / speed);
SliderPos = SliderPos + 1;
}
// todo finish this function
}
private bool CanVSMPlayer()
{
return Names.Count > 0;
}
public ICommand Play
{
get
{
return new RelayCommand(() =>
{
IAsyncResult result = new Action(VSMPlayer).BeginInvoke((c =>
{
//operation completed
}), null);
}, CanVSMPlayer);
}
}
public ObservableCollection<string> Names
{
get
{
return new ObservableCollection<string>() { "a", "b", "c", "d", "e", "f", "g", "h", "i" };
}
}
int _sliderPos = 0;
public int SliderPos
{
get { return _sliderPos; }
set
{
_sliderPos = value;
RaisePropertyChanged("SliderPos");
RaisePropertyChanged("ActiveName");
}
}
public string ActiveName
{
get
{
if (SliderPos < Names.Count)
{
return Names[SliderPos];
}
else
{
return Names[0];
}
}
}
void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
View:
<StackPanel>
<TextBlock Text="{Binding ActiveName}"/>
<Slider Value="{Binding SliderPos}" Maximum="{Binding SliderLength}"/>
<Button Content="Play" Command="{Binding Play}"/>
</StackPanel>
精彩评论