【问题标题】:How to handle the Slider.ValueChanged event in a view model?如何处理视图模型中的 Slider.ValueChanged 事件?
【发布时间】:2014-08-05 12:20:00
【问题描述】:

我有一个 PlayerV.xaml 视图,里面有一个 Slider:

<Slider Value="{Binding CurrentProgress}"/>

还有一个按钮:

<Button Content="next song" Command="{Binding playNext}"/>

按钮工作正常。 Button 的 playNext 命令包含在 PlayerVM.cs

中

我希望滑块的 ValueChanged 调用存储在 PlayerVM.cs 中的函数:

[1]:&lt;Slider Value="{Binding CurrentProgress}" ValueChanged="{Binding playNext}"/&gt;

我知道 [1] 的语法不正确,我使用它是为了解释清楚。

====补充说明====

我知道我会写:

<Slider ValueChanged="Slider_ValueChanged" Value="{Binding CurrentProgress}" />

而在PlayerV.xaml.cs中会有

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        //some logic (actions) 
    }    
}

但我不想要任何逻辑。我希望它位于 PlayerVM.cs 中(如按钮的命令处理函数)。 怎么做? 另外在我的 App.xaml.cs 启动功能是:

private void OnStartup(object sender, StartupEventArgs e)
{
    MainWindow _mainWindow = new MainWindow();
    PlayerVM playerVM = new PlayerVM();
    _mainWindow.DataContext = playerVM;
    _mainWindow.Show();
 }

【问题讨论】:

  • 当您将滑块的值绑定到 VM 的 CurrentProgress 属性时,每次使用滑块滑动时,它也会发生变化。因此,您只需从 CurrentProgress 属性的设置器中调用您需要的命令方法。确保您有 TwoWay 绑定模式
  • 我认为我做错了什么。在 PlayerVM 中,我有一个线程(计时器滴答),它根据 mediaPlayer.Position 设置 CurrentProgress 值。但是我想当用户更改滑块的位置时->播放器的位置应该按照传递。我怎么知道 SLiders 的值是由用户更改的,而不是由 timer_ticks 函数更改的?
  • 最简单的方法 - 你的股票有固定的 intrval 改变进度,在你的 setter 中只是比较旧值和新值,并根据结果做出选择
  • 我想到了使用这种简单的方法。但是,事实证明,我之前的公式是不正确的,我认为这不是一个解决方案。现在我改进了配方,它起作用了!谢谢,@Den。

标签: c# wpf xaml mvvm


【解决方案1】:

你有两个选择。首先,尽管您说过不想在后面使用代码,但一种解决方案是让您这样做。在ValueChanged 事件处理程序中,您可以在值更改时简单地调用您的视图模型方法:

private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    Slider slider = sender as Slider;
    PlayerVM viewModel = (PlayerVM)DataContext;
    viewModel.YourMethod(slider.Value);
} 

我提供此解决方案是因为我怀疑您是 MVVM 的新手,并且仍然认为您不允许使用后面的代码。事实上,根本不是这种情况,对于像这样的纯 UI 问题,这是一个很好的地方。

另一种选择是将属性直接数据绑定到Slider.Value。随着Slider 值的改变,属性也会改变。因此,您可以简单地从数据绑定属性设置器中调用您的方法:

public double CurrentProgress
{
    get { return currentProgress; }
    set
    {
        currentProgress = value;
        NotifyPropertyChanged("CurrentProgress");
        YourMethod(value);
    }
}

另一个选项涉及在自定义附加属性中处理ValueChanged 事件。这个解决方案比其他解决方案要多一些,所以我更愿意将您引向一些我已经为其他问题写过的答案,而不是重新写一遍。请参阅我对How to set Focus to a WPF Control using MVVM? 和WPF C# - navigate WebBrowser on mouseclick through Binding 问题的回答,了解此方法的说明和代码示例。

【讨论】:

    【解决方案2】:

    通过使用事件来推荐逻辑,您可以将事件绑定到您的视图模型,但您需要帮助。您需要使用 System.Windows.Interactivity 命名空间中的函数并包含 MVVM Light(可能有其他 MVVM 库具有该功能,但我使用 MVVM Light)。

    参考这个:Is it possible to bind a WPF Event to MVVM ViewModel command?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2015-06-23
      • 1970-01-01
      相关资源
      最近更新 更多