我想创建一个浮动滑块。由于动画是可冻结的,除此之外,只要您拖动滑块,其值将更改并且拇指跳转到该位置,则对实际拇指进行动画处理会非常棘手。如何制作浮动滑块?
所以我所做的就是让一个假的拇指变成动画(我把它叫做挂钩的拇指),并使实际的拇指透明。这很酷,但几乎没有问题。
,你在下面的gif看,勾拇指的保证金不响应轨道的宽度:(左边距从代码隐藏动画)
我怎样才能让保证金的回应? (我不想解决代码背后的这个问题)
这部分是滑块样式的模板。
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Track x:Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="PART_SelectionRange"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
Style="{StaticResource PlaybackScrollRepeatButtonStyle}"
Command="{x:Static Slider.DecreaseLarge}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
Style="{StaticResource PlaybackScrollRepeatButtonStyle}"
Command="{x:Static Slider.IncreaseLarge}"/>
</Track.IncreaseRepeatButton>
<!-- Transparent thumb with width of 1px and auto height. -->
<Track.Thumb>
<Thumb x:Name="Thumb"
Style="{StaticResource PlaybackSliderHiddenThumbStyle}"/>
</Track.Thumb>
</Track>
<!-- This is the fake thumb. its margin is animated in codebehind. -->
<ContentControl x:Name="HookedThumb" HorizontalAlignment="Left"
Style="{StaticResource PlaybackSliderHookedThumbStyle}"
Background="{StaticResource Playback.Slider.Thumb.Brush}"
BorderBrush="{StaticResource Playback.Slider.Thumb.Border}"/>
</Grid>
我知道这是不响应的原因,因为我使用HorizontalAlignment="Left"
作为挂钩的拇指。如果我使用HorizontalAlignment="Stretch"
,它仍然无法响应。这就是你看到的:
(代码隐藏改变,因为保证金以不同的方式计算)
现在,这是靠近拇指,但仍然没有反应。
我打开任何解决方案。不要担心动画。我会处理。我想要的是让大拇指响起来,就像主拇指一样。
我的另一个想法是使附加的拇指边框,只是动画的边界的宽度,但我不能得到正确的风格。任何帮助赞赏。
这里是你想知道在落后的情况下代码(当HorizontalAlignment="Stretch"
)
// following will animate margin of hooked thumb to the location of thumb.
var cc = (ContentControl)PlaybackSlider.Template.FindName("HookedThumb", PlaybackSlider);
var track = (Track)PlaybackSlider.Template.FindName("PART_Track", PlaybackSlider);
var selection = (RepeatButton)PlaybackSlider.Template.FindName("PART_SelectionRange", PlaybackSlider);
var thumb = track.Thumb;
cc.Margin = new Thickness(-track.ActualWidth + cc.Width, 0, 0, 0); // starting margin
var keyframe = new SplineThicknessKeyFrame(); // holds the target keyframe.
var animator = new ThicknessAnimationUsingKeyFrames // this will animate margin
{
KeyFrames = new ThicknessKeyFrameCollection { keyframe },
BeginTime = TimeSpan.Zero,
Duration = TimeSpan.FromMilliseconds(200),
DecelerationRatio = 1
};
var storyboard = new Storyboard // we use storyboard so we can stop and begin animation at any time.
{
Children = new TimelineCollection { animator }
};
// setup storyboard with target property and dependency object.
Storyboard.SetTarget(animator, cc);
Storyboard.SetTargetProperty(animator, new PropertyPath(MarginProperty));
Action beginAnimation =() =>
{
storyboard.Stop(); // stop animation. change target, begin animation again.
var left = -track.ActualWidth + selection.Width*2; // calculate left margin
var correction = left; // set correction to the left margin
// prevent moving thumb out of range
if (correction < -track.ActualWidth + cc.Width) correction = -track.ActualWidth + cc.Width;
if (left + cc.Width > track.ActualWidth)
correction = track.ActualWidth - cc.Width;
// set new target frame
keyframe.Value = new Thickness(correction, 0, 0, 0);
storyboard.Begin();
};
// following are the handlers that begins the animation.
PlaybackSlider.ValueChanged += (o, e) =>
{
if(thumb.IsDragging) return;
beginAnimation();
};
thumb.DragStarted += (o, e) => beginAnimation();
thumb.DragDelta += (o, e) => beginAnimation();
thumb.DragCompleted += (o, e) => beginAnimation();
这里有风格:触发器排除。
<!-- playback repeat button style -->
<Style x:Key="PlaybackScrollRepeatButtonStyle" TargetType="{x:Type RepeatButton}" BasedOn="{StaticResource {x:Type RepeatButton}}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="Transparent">
<Rectangle Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
VerticalAlignment="Center"
StrokeThickness="0.5"
Height="3"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- playback slider thumb-->
<Style x:Key="PlaybackSliderHiddenThumbStyle" TargetType="{x:Type Thumb}" BasedOn="{StaticResource {x:Type Thumb}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Canvas Background="Transparent" Width="1px"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- playback slider thumb decoy-->
<Style x:Key="PlaybackSliderHookedThumbStyle" TargetType="{x:Type ContentControl}" BasedOn="{StaticResource {x:Type ContentControl}}">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Width" Value="17"/>
<Setter Property="Height" Value="17"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Border Background="Transparent">
<Ellipse x:Name="Ellipse"
Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="1.5"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- playback slider style -->
<Style x:Key="PlaybackSliderStyle" TargetType="{x:Type Slider}" BasedOn="{StaticResource {x:Type Slider}}">
<Setter Property="Background" Value="{StaticResource Playback.Slider.Brush}"/>
<Setter Property="BorderBrush" Value="{StaticResource Playback.Slider.Border}"/>
<Setter Property="Foreground" Value="{StaticResource Playback.Slider.SelectionRange}"/>
<Setter Property="SelectionStart" Value="{Binding Minimum, RelativeSource={RelativeSource Self}}"/>
<Setter Property="SelectionEnd" Value="{Binding Value, RelativeSource={RelativeSource Self}}"/>
<Setter Property="IsSelectionRangeEnabled" Value="True"/>
<Setter Property="IsMoveToPointEnabled" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Slider}">
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Track x:Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="PART_SelectionRange"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
Style="{StaticResource PlaybackScrollRepeatButtonStyle}"
Command="{x:Static Slider.DecreaseLarge}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
Style="{StaticResource PlaybackScrollRepeatButtonStyle}"
Command="{x:Static Slider.IncreaseLarge}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb x:Name="Thumb"
Style="{StaticResource PlaybackSliderHiddenThumbStyle}"/>
</Track.Thumb>
</Track>
<ContentControl x:Name="HookedThumb" HorizontalAlignment="Stretch"
Style="{StaticResource PlaybackSliderHookedThumbStyle}"
Background="{StaticResource Playback.Slider.Thumb.Brush}"
BorderBrush="{StaticResource Playback.Slider.Thumb.Border}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>