5

I have a PlayerV.xaml View with a Slider inside:

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

and have a button:

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

Button works correct. Button's playNext command is contained in PlayerVM.cs

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

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

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

====Additional Explanation====

I know I can write:

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

And in PlayerV.xaml.cs there will be

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:

private void OnStartup(object sender, StartupEventArgs e)
{
    MainWindow _mainWindow = new MainWindow();
    PlayerVM playerVM = new PlayerVM();
    _mainWindow.DataContext = playerVM;
    _mainWindow.Show();
 }
bart
  • 304
  • 1
  • 3
  • 13
  • As you bound value of slider to CurrentProgress prop of your VM, than each time you slide using your slider it changes too. So you just have call the methode of command yuou need from the setter of CurrentProgress prop. Make sure you have TwoWay binding mode – Den Aug 05 '14 at 12:36
  • I think I am doing something wrong. In PlayerVM I have a thread (timer tick) which sets CurrentProgress value according to mediaPlayer.Position. But I wanted to when the user changes the position of the slider -> the position of the player should be passed in accordance. How do I know that SLiders value was changed by user, not by timer_ticks function? – bart Aug 05 '14 at 13:00
  • the most trivial way - your ticker has fixed intrval that changes progress, in your setter just compare old and new value, and depending on the result make a choice – Den Aug 05 '14 at 14:36
  • I had an idea to use that trivial way. But, as it turned out, my previous formula was incorrect and I thought that it is not a solution. Now I improved formula and it works! THanks, @Den. – bart Aug 05 '14 at 21:27

2 Answers2

17

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 ValueChanged event handler, you can simply call your view model method when ever the value is changed:

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 not the case at all and for purely UI matters such as this, it's a good place for it.

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

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

One further option involves handling the ValueChanged event 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 Binding questions for explanations and code examples of this method.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
3

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.Interactivity Namespace and include a MVVM Light (there might be other MVVM libraries that have that feature but i use MVVM Light).

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

Community
  • 1
  • 1
Ponraja
  • 570
  • 2
  • 6
  • 17