MVVM WPF应用程序中的简单动画

时间:2011-04-14 12:44:45

标签: wpf mvvm mvvm-light

我有一个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");
        }
    }

2 个答案:

答案 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>