Я пытаюсь создать плавающий слайдер. Поскольку анимации являются незамерзающими, кроме того, как только вы перетаскиваете ползунок, его значение изменяется, а большой палец переместится в позицию, было бы сложно одушевить реальный большой палец.Как сделать плавающий слайдер?
Так что я сделал, чтобы анимировать поддельный большой палец вместо этого (я называю это крючком большого пальца) и сделать фактический большой палец прозрачным. это было довольно круто, но проблем мало.
, как вы видите, в следующем формате 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>