2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【WPF】循環スクロールをUserControlで実装してみた

Last updated at Posted at 2022-04-28

はじめに

WPFでUWPのTimePickerを作ってみようとしたが、無限に循環するスクロールが標準コントロールになかったので、UserControlで作成してみることにした。

実装

CirculationScroll.xaml
<UserControl>
    <UserControl.Resources>
        <Storyboard x:Key="storyboardSlideDown" Completed="SlideDown_Completed">
            <DoubleAnimation
                Storyboard.TargetName="scrollItems"
                Storyboard.TargetProperty="(Canvas.Top)"
                From="-20"
                To="0"
                Duration="0:0:0.4" />
        </Storyboard>
        <Storyboard x:Key="storyboardSlideUp" Completed="SlideUp_Completed">
            <DoubleAnimation
                Storyboard.TargetName="scrollItems"
                Storyboard.TargetProperty="(Canvas.Top)"
                From="-20"
                To="-40"
                Duration="0:0:0.4" />
        </Storyboard>
        <Storyboard x:Key="storyboardSlideReset">
            <DoubleAnimation
                Storyboard.TargetName="scrollItems"
                Storyboard.TargetProperty="(Canvas.Top)"
                To="-20"
                Duration="0:0:0" />
        </Storyboard>
    </UserControl.Resources>
    <Grid ClipToBounds="True">
        <Canvas x:Name="slideCanvas" ClipToBounds="True">
            <ItemsControl
                    x:Name="scrollItems"
                    Canvas.Top="-20"
                    ItemsSource="{Binding ScrollList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:CirculationScroll}}, Mode=TwoWay}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock
                                Height="20"
                                Text="{Binding Text, Mode=TwoWay}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>
    </Grid>
</UserControl>

UserControl.Resourcesでスクロールっぽく見せるためのStoryBoardを用意。表示するテキストはItemsControlにTextBlockを用意する。

CirculationScroll.xaml.cs
    public partial class CirculationScroll : UserControl
    {
        public CirculationScroll()
        {
            InitializeComponent();

            ScrollList = new ObservableCollection<ScrollText>(); 
        }

        public readonly static DependencyProperty ScrollListProperty = DependencyProperty.Register("ScrollList", typeof(ObservableCollection<ScrollText>), typeof(CirculationScroll), new FrameworkPropertyMetadata(default(ObservableCollection<ScrollText>), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public ObservableCollection<ScrollText> ScrollList
        {
            get { return (ObservableCollection<ScrollText>)GetValue(ScrollListProperty); }
            set { SetValue(ScrollListProperty, value); }
        }

        private void SlideDown_Completed(object sender, EventArgs e)
        {
            var reset = FindResource("storyboardSlideReset") as Storyboard;
            reset.Begin();

            ScrollList.Move(ScrollList.Count - 1, 0);
        }

        private void SlideUp_Completed(object sender, EventArgs e)
        {
            var reset = FindResource("storyboardSlideReset") as Storyboard;
            reset.Begin();

            ScrollList.Move(0, ScrollList.Count - 1);
        }

        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
            {
                var slideDown = FindResource("storyboardSlideDown") as Storyboard;
                slideDown.Begin();
            }
            else
            {
                var SlideUp = FindResource("storyboardSlideUp") as Storyboard;
                SlideUp.Begin();
            }

            base.OnMouseWheel(e);
        }
    }

    public class ScrollText
    {
        public ScrollText(string text)
        {
            Text = text;
        }
        public string Text { get; set; }
    }

依存関係プロパティにObservableCollectionを公開し、ユーザー側で表示文字列のListを設定することで、スクロールっぽくアニメーションできることを確認した。連続的にスクロールした場合にカクつくので改良が必要と思う。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?