浮動スライダーを作成しようとしています。アニメーションはフリーズすることができるので、スライダをドラッグするとその値が変化し、サムがその位置にジャンプするとすぐに、実際の親をアニメーション化するのは難しいでしょう。フローティングスライダーの作成方法は?
私がしたことは、代わりに偽の親指を動かすことでした(私は親指と呼んでいます)。そして実際の親指を透明にします。それはかなりクールに行ったが、問題はほとんどない。
次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"
を使用しても、それはまだ応答しません。これは何を参照してくださいされています。今、これは親指に近いが、まだ応答しない
(マージンは異なる方法で計算されているため、分離コードが変更された)
。
私はすべてのソリューションを公開しています。アニメーションについて心配しないでください。私はそれに対処します。私が欲しいのは、親指のように親指を反応させることです。
私が持っていたもう1つのアイデアは、それに付いている親指で境界を作り、境界線の幅をアニメーション化することでしたが、正しいスタイルを得ることはできません。どんな助けもありがたい。ここではここ
コードは、あなたが(とき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>