wpf 如何处理视图模型中的 Slider.ValueChanged 事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25138695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:17:14  来源:igfitidea点击:

How to handle the Slider.ValueChanged event in a view model?

c#wpfxamlmvvm

提问by bart

I have a PlayerV.xamlView with a Slider inside:

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

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

and have a button:

并有一个按钮:

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

Button works correct. Button's playNextcommand is contained in PlayerVM.cs

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

I want slider's ValueChanged to call a function which is stored in PlayerVM.cs:

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

[1]:<Slider Value="{Binding CurrentProgress}" ValueChanged="{Binding playNext}"/>

[1]:<Slider Value="{Binding CurrentProgress}" ValueChanged="{Binding playNext}"/>

I know [1] has an incorrect syntax, I used it for sake of clarity of explanation.

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

====Additional Explanation====

====附加说明====

I know I can write:

我知道我可以写:

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

And in PlayerV.xaml.csthere will be

PlayerV.xaml.cs 中会有

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

But I don't want any logic in there. I want it to be in PlayerVM.cs(like button's command handler functions). How to do that? Also in my App.xaml.cs startup function is:

但我不想在那里有任何逻辑。我希望它在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();
 }

回答by Sheridan

You have two options. First, despite what you said about not wanting to use code behind, one solution is for you to do just that. In the ValueChangedevent handler, you can simply call your view model method when ever the value is changed:

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

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

I've offered this solution because I suspect that you're new to MVVM and still think that you're not allowed to use the code behind. In fact, that is notthe case at all and for purely UI matters such as this, it's a good place for it.

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

Another option is just to data bind a property directly to the Slider.Value. As the Slidervalue is changed, so will the property be. Therefore, you can simply call your method from the data bound property setter:

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

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

One further option involves handling the ValueChangedevent in a custom Attached Property. There is a bit more to this solution than the others, so I'd prefer to direct you to some answers that I have already written for other questions, rather than re-writing it all again. Please see my answers to the How to set Focus to a WPF Control using MVVM?and WPF C# - navigate WebBrowser on mouseclick through Bindingquestions for explanations and code examples of this method.

另一种选择涉及ValueChanged在自定义附加属性中处理事件。此解决方案比其他解决方案要多一些,因此我更愿意将您引向我已经为其他问题编写的一些答案,而不是重新全部重写。请参阅我对如何使用 MVVM 将焦点设置为 WPF 控件的回答WPF C# - 通过绑定问题在鼠标单击时导航 WebBrowser,以获取此方法的解释和代码示例。

回答by Ponraja

By using the event to commend logic you can bind events to your view model, but you need help. You need to use functions from the System.Windows.InteractivityNamespace and include a MVVM Light(there might be other MVVM libraries that have that feature but i use MVVM Light).

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

refer this: Is it possible to bind a WPF Event to MVVM ViewModel command?

请参阅:是否可以将 WPF 事件绑定到 MVVM ViewModel 命令?