我有一个MVVM应用程序,它有一个滑动条,当用户更改滑动条时,它会更新屏幕上的图形并更新一些图形。这一切都适用于用户更改滑块的位置,我想添加一个“播放”按钮,自动移动滑块和一切更新。我尝试了以下代码来做到这一点,当我尝试它时,屏幕上没有任何变化。我已经确认它确实正在运行代码并更改'SliderPos'变量。我错过了什么?
private void VSMPlayer()
{
SliderPos = 0;
const int speed = 1;
while (SliderPos < SliderLength)
{
Thread.Sleep(100 / speed);
SliderPos = SliderPos + 20;
}
// todo finish this function
}
为清楚起见,这里是SliderPos属性
公共双SliderPos { 得到 { return this.sliderPos; }
set
{
this.sliderPos = value;
SetCursorLocation();
SetParameters();
this.RaisePropertyChanged("SliderPos");
}
}
答案 0 :(得分:1)
拥有SliderPos
的班级需要实施INotifyPropertyChanged
。 (如果您的Slider.Value
绑定了该属性)
编辑:仅此一项无效,因为正确注意到UI-Thread正在休眠。
你可以试试这样的东西,它有效:
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: 如果您没有修改任何UI-Thread-Owned控件,您可以使用除UI-Thread之外的任何线程,例如:
SliderPosition = 0;
new Thread(new ThreadStart(delegate
{
while (SliderPosition < 100)
{
Thread.Sleep(100);
SliderPosition += 20;
}
})).Start();
答案 1 :(得分:0)
看看这个类似的解决方案:
视图模型:
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;
}
查看:
<StackPanel>
<TextBlock Text="{Binding ActiveName}"/>
<Slider Value="{Binding SliderPos}" Maximum="{Binding SliderLength}"/>
<Button Content="Play" Command="{Binding Play}"/>
</StackPanel>