Nitin
Nitin

Reputation: 55

How to DataBind WPF Slider's Thumb's DragCompleted event

I want to bind the DragCompleted event to one of my ViewModel's Command. I tried the following using Blend but it doesn't work:

<Slider x:Name="slider" HorizontalAlignment="Left" Margin="41,147,0,0" VerticalAlignment="Top" Width="412">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Thumb.DragCompleted">
            <i:InvokeCommandAction Command="{Binding DragCompletedCommand}"></i:InvokeCommandAction>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Slider>

But this doesn't work. When I use the normal binding of event to code behind, it works:

<Slider x:Name="slider" Thumb.DragCompleted="slider_DragCompleted"  HorizontalAlignment="Left" Margin="41,147,0,0" VerticalAlignment="Top" Width="412"></Slider>

I tried searching but strangely couldn't find answer to this.

Upvotes: 3

Views: 2236

Answers (2)

Mihai Gisca
Mihai Gisca

Reputation: 1

I ended up using the code behind to access the ViewModel.

In xaml:

<Slider Thumb.DragCompleted="OnThumbDragCompleted"/>

In code-behind (considering that the DataContext of the view is ViewModel):

private void OnThumbDragCompleted(object sender, DragCompletedEventArgs e)
{
    ((ViewModel)this.DataContext).DragCompleted();
}

In ViewModel:

public void DragCompleted()
{
    // event processing
}

Hope this helps!

Upvotes: -1

Tomtom
Tomtom

Reputation: 9394

You can write an attached property for this which can look like:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace MyTestApplication
{
    internal class SliderExtension
    {
        public static readonly DependencyProperty DragCompletedCommandProperty = DependencyProperty.RegisterAttached(
            "DragCompletedCommand",
            typeof(ICommand),
            typeof(SliderExtension),
            new PropertyMetadata(default(ICommand), OnDragCompletedCommandChanged));

        private static void OnDragCompletedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Slider slider = d as Slider;
            if (slider == null)
            {
                return;
            }

            if (e.NewValue is ICommand)
            {
                slider.Loaded += SliderOnLoaded;
            }
        }

        private static void SliderOnLoaded(object sender, RoutedEventArgs e)
        {
            Slider slider = sender as Slider;
            if (slider == null)
            {
                return;
            }
            slider.Loaded -= SliderOnLoaded;

            Track track = slider.Template.FindName("PART_Track", slider) as Track;
            if (track == null)
            {
                return;
            }
            track.Thumb.DragCompleted += (dragCompletedSender, dragCompletedArgs) =>
            {
                ICommand command = GetDragCompletedCommand(slider);
                command.Execute(null);
            };
        }

        public static void SetDragCompletedCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(DragCompletedCommandProperty, value);
        }

        public static ICommand GetDragCompletedCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(DragCompletedCommandProperty);
        }
    }
}

And your Slider-Definition then looks like:

<Slider x:Name="slider" HorizontalAlignment="Left" Margin="41,147,0,0" VerticalAlignment="Top" Width="412" 
        extensions:SliderExtension.DragCompletedCommand="{Binding SlideCompletedCommand}"/>

extensions is the namespace where your attached property is located.

And in your ViewModel you have an ICommand-Property called SlideCompletedCommand, which can look like:

private ICommand slideCompletedCommand;
public ICommand SlideCompletedCommand
{
    get { return slideCompletedCommand ?? (slideCompletedCommand = new RelayCommand(p => SlideCompleted())); }
}

private void SlideCompleted()
{
    // Your slide-completed-code here
}

Upvotes: 3

Related Questions