ScrollViewer中的XAML滑块
对于Windows 10 UWP应用程序,我有这样的XAML结构:ScrollViewer中的XAML滑块,xaml,slider,uwp,scrollviewer,Xaml,Slider,Uwp,Scrollviewer,对于Windows 10 UWP应用程序,我有这样的XAML结构: <ScrollViewer> <StackPanel> <Slider /> <Slider /> ... </StackPanel> </ScrollViewer> ... 我想创造这样的用户体验: 当用户开始水平滑动手势时,触摸下的滑块应接收输入并开始更改其值,而垂直滚动被完全禁用(即
<ScrollViewer>
<StackPanel>
<Slider />
<Slider />
...
</StackPanel>
</ScrollViewer>
...
我想创造这样的用户体验:
是否可以在纯XAML中实现此行为?我想我已经尝试了与滚动相关的所有可能的属性组合。。。不走运。有人知道吗?在操作系统版本为10586的移动仿真器上测试后,我发现当垂直滚动
ScrollViewer
时,即使我画圆圈,它也不会影响滑块的内部,并且当滑块
水平滑动时,只有当其值达到最大值时,如果我画圆圈,ScrollViewer
的垂直滚动将生效
是否可以在纯XAML中实现此行为
是的,这是可能的
当用户开始水平滑动手势时,触摸下的滑块应接收输入并开始更改其值,而垂直滚动被完全禁用(即使用户继续绘制圆运动)
您可以在项目中安装该软件包,然后使用其DataTriggerBehavior
例如:
<ScrollViewer x:Name="scrollViewer" HorizontalScrollMode="Disabled" VerticalScrollMode="Auto">
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding ElementName=slider1,Path=FocusState}" ComparisonCondition="NotEqual" Value="Unfocused">
<Core:ChangePropertyAction PropertyName="VerticalScrollMode" Value="Disabled" />
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding ElementName=slider1,Path=FocusState}" ComparisonCondition="Equal" Value="Unfocused">
<Core:ChangePropertyAction PropertyName="VerticalScrollMode" Value="Auto" />
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding ElementName=slider2,Path=FocusState}" ComparisonCondition="NotEqual" Value="Unfocused">
<Core:ChangePropertyAction PropertyName="VerticalScrollMode" Value="Disabled" />
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding ElementName=slider2,Path=FocusState}" ComparisonCondition="Equal" Value="Unfocused">
<Core:ChangePropertyAction PropertyName="VerticalScrollMode" Value="Auto" />
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<StackPanel Height="1300">
<Slider Margin="0,200" x:Name="slider1" />
<Slider x:Name="slider2" />
</StackPanel>
</ScrollViewer>
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Media="using:Microsoft.Xaml.Interactions.Media"
正如您在我的代码中看到的,我比较了滑块的聚焦状态
属性,如果其值为未聚焦
,则启用了滚动查看器的垂直滚动模式。因此,当用户与此布局交互时,在<代码>滑块< /代码>上单击后,他需要单击空白部分以使<代码>滑块首先失去焦点,然后启用垂直滚动模式。p>
当用户开始垂直滑动手势时,scrollviewer应接收输入并开始垂直滚动,而触摸下的滑块应保持完整(即使用户继续绘制圆圈运动)
根据我的测试,我认为这个手势在默认情况下是可以保证的,所以我没有为此编写代码。如果它不在您身边,请留下评论,并提供您的设备类型和操作系统版本,以便我可以进行测试 我有一个非常类似的问题,并且能够通过以下自定义控件解决它。这是一个CommandSlider,它还允许您在滑动完成(不是您需要的)后发送命令,如按钮,但ScrollViewer操作代码也在其中。看看这是否有助于你的处境。它允许您按照要求在完整的XAML中完成所有工作
注意:滑块必须具有operationmode=“TranslateX”或“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));
}
公共密封类命令滑块:滑块
{
公共命令滑块()
{
IsThumbToolTipeEnabled=false;
PointerCaptureLost+=(s,e)=>(命令?.CanExecute(CommandParameter)).GetValueOrDefault().Switch(()=>命令?.Execute(CommandParameter));
Loaded+=(s,e)=>ParentScrollViewer=this.GetParent();
}
私有ScrollViewer父ScrollViewer{get;set;}
ManipulationDelta上的受保护覆盖无效(ManipulationDeltaRoutedEventArgs e)
{
基于操作delta(e);
if(ParentScrollViewer!=null)
{
var scrollX=方向==方向.垂直
?e.Position.X*-1+ParentScrollViewer.HorizontalOffset
:ParentScrollViewer.HorizontalOffset;
变量scrollY=方向==方向.水平
?e.Position.Y*-1+ParentScrollViewer.VerticalOffset
:ParentScrollViewer.VerticalOffset;
var zoom=ParentScrollViewer.ZoomFactor;
ParentScrollViewer.ChangeView(scrollX、scrollY、zoom);
}
}
公共对象命令参数
{
get=>GetValue(CommandParameterProperty);
set=>SetValue(CommandParameterProperty,value);
}
public static readonly dependencProperty命令参数解释属性=
Register(nameof(CommandParameter)、typeof(object)、typeof(CommandSlider)、newpropertyMetadata(null));
公共ICommand命令
{
get=>(ICommand)GetValue(CommandProperty);
set=>SetValue(CommandProperty,value);
}
公共静态只读DependencyProperty CommandProperty=
Register(nameof(Command)、typeof(ICommand)、typeof(CommandSlider)、newpropertyMetadata(null));
公共双源值
{
get=>(双精度)GetValue(SourceValueProperty);
set=>SetValue(SourceValueProperty,value);
}
公共静态只读DependencyProperty SourceValueProperty=
DependencyProperty.Register(nameof(SourceValue)、typeof(double)、typeof(CommandSlider)、new PropertyMetadata(0d、,
(s,e)=>(s作为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);
}
}
}
公共静态类XAMLExtensions
{
公共静态T GetParent(此DependencyObject DependencyObject),其中T:DependencyObject
{
var parentDependencyObject=VisualTreeHelper.GetParent(dependencyObject);
开关(parentDependencyObject)
{
大小写为空:
返回null;
案例T父母:
返回父母;
违约:
返回GetParent(parentDependencyObject);
}
}
}
很有意思,但为什么用户在只有X交互的情况下会做圆周绘制运动呢