WPF Sliderf 跟随光标

WPF Sliderf follow cursor

我有滑块 :

<Slider x:Name="DesktopAudioSlider"
                        HorizontalAlignment="Stretch"
                        Margin="0,0,5,0">

我需要像 UWP Slider 中那样的行为,当它单击时跟随光标。我不能使用事件,因为使用 MVVM,试图将 sender 和 eventargs 转换为元组并传递给命令,但是没有办法将 MouseEventargs 传递给转换器。

转换器:

class SliderArgsToTupleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(parameter is MouseEventArgs)
            {
                return new Tuple<object, MouseEventArgs>(value, parameter as MouseEventArgs);
            }
            else
            {
                throw new ArgumentException();
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

命令:

this.SlideMouseMoveCommand = new RelayCommand<Tuple<object, MouseEventArgs>>(SlideMouseMoveExecute);

触发器:

<i:EventTrigger EventName="MouseMove">
                            <i:InvokeCommandAction Command="{Binding MixerViewModel.SlideMouseMoveCommand, Source={StaticResource Locator}}"
                                                   CommandParameter="{Binding ElementName=DesktopAudioSlider , ConverterParameter={}}"
                        </i:EventTrigger>

无法在命令中传递两个参数,我找到了一个解决方案 - 添加行为。

public class SliderMoveBehavior : Behavior<Slider>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.MouseMove += SliderMouseMove;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.MouseMove -= SliderMouseMove;
        }

        private void SliderMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point position = e.GetPosition(AssociatedObject);
                double d = 1.0d / AssociatedObject.ActualWidth * position.X;
                var p = AssociatedObject.Maximum * d;
                AssociatedObject.Value = (int)p;
            }
        }
    }

在XAML中:

<Slider x:Name="PlaybackSpeedSlider">
     <i:Interaction.Behaviors>
         <behaviors:SliderMoveBehavior/>
     </i:Interaction.Behaviors>
</Slider>