绑定滑块控件的事件

时间:2011-03-16 11:46:20

标签: wpf xaml mvvm binding

在视图(AudioView.xaml)中,我编写了以下代码

<Slider
    Name="AudioSlider"
    Width="200"
    Height="23"
    Grid.Column="0"
    IsSelectionRangeEnabled="True"
    IsSnapToTickEnabled="True"
    Maximum="{Binding Path=TotalAudioPlayingSeconds, Mode=OneTime}"
    Minimum="0"
    Style="{StaticResource CustomStyleForSlider}"
    Thumb.DragCompleted="{Binding AudioSliderChangedCommand}"
    TickFrequency="1"
    Value="{Binding Path=AudioPosition}"/>

注意:还有文件AudioView.xaml.cs

在视图模型类(AudioViewModel.cs)中,我定义了以下属性

public event DragCompletedEventHandler AudioSliderChangedCommand;

并在视图模型类的构造函数中( AudioViewModel.cs

this.AudioSliderChangedCommand = new DragCompletedEventHandler(OnAudioSliderChanged);

在编译期间,我收到以下错误

  

错误8 DragCompleted =“{Binding AudioSliderChangedCommand}”不是   有效。 {Binding AudioSliderChangedCommand}不是有效事件   处理程序方法名称只生成或生成实例方法   代码隐藏类是有效的。

1 个答案:

答案 0 :(得分:6)

问题不在你的代码隐藏中,而是在你的XAML中。在某处你这样做:

DragCompleted="{Binding AudioSliderChangedCommand}"

这指示XAML反序列化器将AudioSliderChangedCommand处理程序附加到DragCompleted事件。但是,AudioSliderChangedCommand 不是具有相应签名的方法(可以作为处理程序附加),并且在View类中不是。最后,您不能将Binding用于事件处理程序。

要解决此问题,最简单的解决方案是在View

中执行此操作
private void DragCompletedEventHandler(object sender, DragCompletedEventArgs e)
{
    var viewModel = (YourViewModelType)this.DataContext;
    viewModel.OnAudioSliderChanged(this, e);
}

并且还要改变

DragCompleted="{Binding AudioSliderChangedCommand}"

DragCompleted="DragCompletedEventHandler"

在您的XAML中。

以上是这样的:

  1. 在您的视图中,当引发DragCompleted时,将调用方法View.DragCompletedEventHandler
  2. 此方法将从ViewModel获取AudioSliderChangedCommand事件(请参阅下面的注释)并提升它,传递原始事件args
  3. 重要提示

    您似乎对事件,事件处理程序和命令感到困惑。您现有的代码具有误导性。 AudioSliderChangedCommandevent,但名称表明它是ICommand。相应的名称为AudioSliderChanged

    此外,适当的MVVM方式是使用DelegateCommand的一些风格(所有体面的MVVM框架都有一个;我在Prism中使用类名进行实现)。然后,假设AudioSliderChangedCommand确实是一个命令,View中的代码隐藏将是:

    private void DragCompletedEventHandler(object sender, DragCompletedEventArgs e)
    {
        var viewModel = (YourViewModelType)this.DataContext;
        viewModel.AudioSliderChangedCommand.Execute();
    }
    

    通过使用某种“事件来命令”附加行为,也可以完全没有任何代码隐藏。