最近修复遇到的一个问题:滑动内部包含滑动,具体情况是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" />