Wpf滑动内部包含滑动,内部触控滑动时无法滑动操作
最近修复遇到的一个问题:滑动内部包含滑动,具体情况是ScrollViewer子元素放置Slider,触控Slider滑动时,只能在点击的时候操作一次,不能继续滑动操作。
针对上述问题:分析之后的原因时,在Slider滑动时,由于ScrollViewer会捕捉触控设备,导致内部的Slider失去触控设备,导致在Slider元素上无法继续滑动。
得到问题的根源之后那就好处理了,有两种方式
方式一
关闭ScrollViewer的触控操作 ,简单能够解决内部Slider无法滑动问题,但是当外部ScrollViewer出现滑动操作时,就不合适了。应采用方式二
PanningMode = “None”
方式二
第一步 重写Thumb,目的是在触控Slider滑动时防止丢失捕捉设备,而导致无法继续滑动操作
public class CustomThumb : Thumb { private TouchDevice _currentDevice = null; protected override void OnPreviewTouchDown(TouchEventArgs e) { ReleaseCurrentDevice(); CaptureCurrentDevice(e); } protected override void OnPreviewTouchUp(TouchEventArgs e) { ReleaseCurrentDevice(); } /// <summary> /// 处理TouchDevice被捕捉,无法接收任何PreviewTouchMove或TouchMove事件 /// </summary> /// <param name="e"></param> protected override void OnLostTouchCapture(TouchEventArgs e) { if (_currentDevice != null) { CaptureCurrentDevice(e); } } /// <summary> /// 释放触摸设备 /// </summary> private void ReleaseCurrentDevice() { if (_currentDevice != null) { var temp = _currentDevice; _currentDevice = null; ReleaseTouchCapture(temp); } } /// <summary> /// 捕捉触摸设备 /// </summary> /// <param name="e"></param> private void CaptureCurrentDevice(TouchEventArgs e) { bool gotTouch = CaptureTouch(e.TouchDevice); if (gotTouch) { _currentDevice = e.TouchDevice; } } } }
第二步 自定义Slider的样式:CustomSlider.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="Style.Slider.DecreaseRepeatButton" TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Background="{TemplateBinding Background}" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Style.Slider.IncreaseRepeatButton" TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Background="{TemplateBinding Background}" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Style.Slider.ProgressRepeatButton" TargetType="{x:Type RepeatButton}"> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Border Background="Transparent"> <Border Margin="{TemplateBinding Padding}" Background="{TemplateBinding Background}" CornerRadius="2" Height="6"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Style.Slider.Thumb" TargetType="Thumb"> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Thumb"> <Grid> <Border x:Name="ThumbBorder" Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" CornerRadius="3"> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Style.ZoomSlider" TargetType="Slider"> <Setter Property="Focusable" Value="false" /> <Setter Property="IsMoveToPointEnabled" Value="True"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Slider"> <Grid > <Track Grid.Column="1" Name="PART_Track" Height="80"> <Track.DecreaseRepeatButton> <RepeatButton Style="{StaticResource Style.Slider.ProgressRepeatButton}" Command="Slider.DecreaseLarge" > </RepeatButton> </Track.DecreaseRepeatButton> <Track.Thumb> <controls:CustomThumb Width="28" Height="6" Background="{StaticResource Brush.Background.Slider.Thumb}" Style="{StaticResource Style.Slider.Thumb}"/> </Track.Thumb> <Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource Style.Slider.ProgressRepeatButton}" Command="Slider.IncreaseLarge"> </RepeatButton> </Track.IncreaseRepeatButton> </Track> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
第三步 : 使用Slider样式
<Slider Style="{StaticResource Style.ZoomSlider}" Height="80" BorderThickness="1" Orientation="Vertical" />