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>
我有滑块 :
<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>