我有一个非常相似的问题,并且能够使用以下自定义控件解决它。这是一个 CommandSlider,它还允许您在滑动完成后发送按钮之类的命令(不是您需要的),但 ScrollViewer 操作代码也在那里。看看这是否对您的情况有所帮助。它允许您按照您的要求在完整的 XAML 中完成所有工作。
注意:滑块必须有ManipulationMode="TranslateX" or "TranslateY",这也取决于方向。
public sealed class CommandSlider : Slider
{
public CommandSlider()
{
IsThumbToolTipEnabled = false;
PointerCaptureLost += (s, e) => (Command?.CanExecute(CommandParameter)).GetValueOrDefault().Switch(() => Command?.Execute(CommandParameter));
Loaded += (s, e) => ParentScrollViewer = this.GetParent<ScrollViewer>();
}
private ScrollViewer ParentScrollViewer { get; set; }
protected override void OnManipulationDelta(ManipulationDeltaRoutedEventArgs e)
{
base.OnManipulationDelta(e);
if (ParentScrollViewer != null)
{
var scrollX = Orientation == Orientation.Vertical
? e.Position.X * -1 + ParentScrollViewer.HorizontalOffset
: ParentScrollViewer.HorizontalOffset;
var scrollY = Orientation == Orientation.Horizontal
? e.Position.Y * -1 + ParentScrollViewer.VerticalOffset
: ParentScrollViewer.VerticalOffset;
var zoom = ParentScrollViewer.ZoomFactor;
ParentScrollViewer.ChangeView(scrollX, scrollY, zoom);
}
}
public object CommandParameter
{
get => GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register(nameof(CommandParameter), typeof(object), typeof(CommandSlider), new PropertyMetadata(null));
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(CommandSlider), new PropertyMetadata(null));
public double SourceValue
{
get => (double)GetValue(SourceValueProperty);
set => SetValue(SourceValueProperty, value);
}
public static readonly DependencyProperty SourceValueProperty =
DependencyProperty.Register(nameof(SourceValue), typeof(double), typeof(CommandSlider), new PropertyMetadata(0d,
(s, e) => (s as CommandSlider).Value = (double)e.NewValue));
}
自定义扩展方法
public static class XAMLExtensions
{
public static T GetParent<T>(this DependencyObject dependencyObject) where T : DependencyObject
{
var parentDependencyObject = VisualTreeHelper.GetParent(dependencyObject);
switch (parentDependencyObject)
{
case null:
return null;
case T parent:
return parent;
default:
return GetParent<T>(parentDependencyObject);
}
}
}