Click here to Skip to main content
14,385,566 members

A Custom WPF Carousel Control

Rate this:
5.00 (22 votes)
Please Sign up or sign in to vote.
5.00 (22 votes)
21 Nov 2019CPOL
This article presents a simple WPF Carousel Control

Introduction

A carousel control is a powerful and visually appealing way to present multiple items of data. Unfortunately, Microsoft does not provide a stock implementation. There are many freely available carousel controls available.

The two best known freeware carousel controls are arguably the following:

Initially, I tried using the first version, and adapting it to our own needs. Unfortunately, it is based on the Microsoft PathListBox control thereby hiding most of the implementation details. I found it rather difficult to modify it to suit our needs and eventually gave up.

The second carousel is a nice simple implementation, but the author has hard coded spheres as the carousel items, and he has not exposed any dependency properties which limits its usefulness.

I decided to use the second carousel as a starting point to create a more flexible carousel control.

This article includes the source code for the new WPF carousel control, and a simple demonstration application.

Background

You will need a good understanding of C# and a basic understanding of WPF.

Overview

The carousel control can arrange items horizontally:

Image 1

It can also arrange the items vertically:

Image 2

The new carousel control, which I have called WPFCarouselControl (no marks for originality, I fear) has the following dependency properties:

ItemsSource

The data displayed by the carousel items.
SelectedItem The currently selected item.
CarouselItemTemplate Defines the appearance and behaviour of each carousel item.
AutoSizeToParent If true, the control sizes itself to fit the available space.
TiltInDegrees The tilt of the axis about which the items appear to rotate.
RotationSpeed The speed at which the items rotate when a new item is selected.
Fade A value between 0 and 1 which determines how the opacity of items varies with position. Those furthest from the selected item have the lowest opacity.
Scale A scaling that is applied to the items in the carousel to create a 3D effect. A value of one means that all items have the same size. A value less than one creates perspective. The range is 0 to 1 inclusive.
VerticalOrientation If true items are arranged vertically, if false items are arranged horizontally.

Using the WPFCarouselControl

It is straightforward to use the control in an application.

First, create a class which stores the data displayed in one carousel item. For example:

public class RadioStation
{
    public string Name { get; set; }
    public string ShortName { get; set; }
    public string ImageSource { get; set; }
    public string Text { get; set; }
}

Next, add a CarouselControl to your view. For example:

<WPFCarouselControl:CarouselControl Grid.Row="5" Grid.Column="1" 

Grid.ColumnSpan="5" x:Name="_carouselDABRadioStations" 

ItemsSource="{Binding RadioStationsDAB}" 

SelectedItem="{Binding SelectedRadioStationDAB,Mode=TwoWay}" 

ShowRotation="True"  TiltInDegrees="10" 

AutoSizeToParent="true" RotationSpeed="100" 

VerticalOrientation="False" HorizontalAlignment="Stretch" 

VerticalAlignment="Stretch">
    <WPFCarouselControl:CarouselControl.Style>
        <Style TargetType="WPFCarouselControl:CarouselControl">
            <Setter Property="CarouselItemTemplate" >
                <Setter.Value>
                    <ControlTemplate>
                        <Border BorderThickness="1" 

                        BorderBrush="Gainsboro" Background="SteelBlue" 

                        Width="250" Height="150">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="30"/>
                                </Grid.RowDefinitions>
                                <Border Grid.Row="0" 

                                BorderThickness="0" Background="White">
                                    <Image Grid.Row="0" 

                                    Source="{Binding ImageSource}" 

                                    VerticalAlignment="Center" 

                                    HorizontalAlignment="Center" Height="100"/>
                                </Border>
                                <Label Grid.Row="1" 

                                Content="{Binding ShortName}" 

                                Foreground="White" Background="Transparent" 

                                FontSize="20" FontFamily="Arial" 

                                Style="{StaticResource labelStyleCentred}" 

                                DockPanel.Dock="Bottom" Height="Auto"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </WPFCarouselControl:CarouselControl.Style>
</WPFCarouselControl:CarouselControl>

Note the CarouselItemTemplate property which defines a carousel item consisting of a rectangle containing an image above a line of text.

The ItemsSource property is bound to the RadioStationsDAB property defined in the view model as follows:

private System.Collections.ObjectModel.ObservableCollection
                              <Model.RadioStation> _radioStationsDAB;
public System.Collections.ObjectModel.ObservableCollection
                              <Model.RadioStation> RadioStationsDAB
{
    get
    {
        return _radioStationsDAB;
    }
    set
    {
        _radioStationsDAB = value;
        NotifyPropertyChanged("RadioStationsDAB");
    }
}

Implementation Details

The WPF carousel control is a WPF user control containing a Canvas control.

The item controls are child elements of the canvas, laid out on a circle projected onto the plane of the screen.

The control implements a SelectionChanged event allowing the owner to receive a notification when an item is selected by means of a left mouse button click.

The rotation is implemented using a timer which is started when the selected item changes. The timer fires every 10 milliseconds to ensure a smooth rotation. On each tick, it moves the items by an amount proportional to the rotation speed.

Adding/Removing Items

The ItemsSource property assumes that it is bound to a collection object that implements the System.Collections.IEnumerable and System.Collections.Specialized.INotifyCollectionChanged interfaces. The latter interface must be implemented if items are added and/or removed from the items list. 

Limitations

The current control lays out the items uniformly around an imaginary circle. If you wish to change the layout, you will need to edit the SetElementPositions method. If you are feeling adventurous, you could layout the items along a Path dependency property.

History

  • 9th May, 2019: Version 1.
  • 9th May, 2019: Version 2: implemented the CarouselItemTemplate dependency property
  • 5th November, 2019: Version 3: fixed a bug with the rotation algorithm that caused the direction of rotation to reverse unexpectedly. The download code has been updated.
  • 21st November, 2019: Version 4: updated the ItemsSource property to allow the adding and/or removing of items.  
  • 22nd November, 2019: Version 5: Fixed the layout so that the selected item is now always centred. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Leif Simon Goodwin
United Kingdom United Kingdom
C#/WPF/C++ Windows developer

Comments and Discussions

 
GeneralMy vote of 5 Pin
m palotas3-Dec-19 15:50
Memberm palotas3-Dec-19 15:50 
GeneralRe: My vote of 5 Pin
Leif Simon Goodwin3-Dec-19 23:32
MemberLeif Simon Goodwin3-Dec-19 23:32 
QuestionDelete Item's from Carousel Pin
leighdar18-Nov-19 1:43
Memberleighdar18-Nov-19 1:43 
AnswerRe: Delete Item's from Carousel Pin
Leif Simon Goodwin21-Nov-19 5:35
MemberLeif Simon Goodwin21-Nov-19 5:35 
QuestionAwsome...One request Pin
faisalthayyil16-Nov-19 19:43
Memberfaisalthayyil16-Nov-19 19:43 
AnswerRe: Awsome...One request Pin
Jaroslav Mitrovic22-Nov-19 23:47
MemberJaroslav Mitrovic22-Nov-19 23:47 
QuestionNot all the items are centered correctly Pin
Member 1357019115-Nov-19 4:50
MemberMember 1357019115-Nov-19 4:50 
AnswerRe: Not all the items are centered correctly Pin
Leif Simon Goodwin24-Nov-19 23:52
MemberLeif Simon Goodwin24-Nov-19 23:52 
PraiseNice work Pin
Mike Hankey8-Nov-19 13:16
professionalMike Hankey8-Nov-19 13:16 
Praisevery nice Pin
BillW337-Nov-19 4:20
professionalBillW337-Nov-19 4:20 
GeneralRe: very nice Pin
Leif Simon Goodwin7-Nov-19 6:26
MemberLeif Simon Goodwin7-Nov-19 6:26 
GeneralMy vote of 5 Pin
Сергій Ярошко5-Nov-19 5:01
professionalСергій Ярошко5-Nov-19 5:01 
QuestionShowing only selected item Pin
Member 1459432011-Oct-19 3:40
MemberMember 1459432011-Oct-19 3:40 
AnswerRe: Showing only selected item Pin
Member 145943204-Nov-19 23:19
MemberMember 145943204-Nov-19 23:19 
Awesome so far,

but i would also like the same Option Smile | :)
AnswerRe: Showing only selected item Pin
Leif Simon Goodwin22-Nov-19 4:17
MemberLeif Simon Goodwin22-Nov-19 4:17 
Questionfew things Pin
Sacha Barber10-May-19 5:23
mvaSacha Barber10-May-19 5:23 
AnswerRe: few things Pin
Leif Simon Goodwin10-May-19 5:29
MemberLeif Simon Goodwin10-May-19 5:29 
GeneralRe: few things Pin
Sacha Barber10-May-19 5:42
mvaSacha Barber10-May-19 5:42 
GeneralRe: few things Pin
Leif Simon Goodwin5-Nov-19 2:14
MemberLeif Simon Goodwin5-Nov-19 2:14 
GeneralNice Pin
Meshack Musundi10-May-19 4:45
professionalMeshack Musundi10-May-19 4:45 
QuestionAs the author of one of the original ones you mentioned, let me just say Pin
Sacha Barber10-May-19 3:05
mvaSacha Barber10-May-19 3:05 
AnswerRe: As the author of one of the original ones you mentioned, let me just say Pin
Leif Simon Goodwin10-May-19 3:35
MemberLeif Simon Goodwin10-May-19 3:35 
GeneralRe: As the author of one of the original ones you mentioned, let me just say Pin
m palotas3-Dec-19 15:39
Memberm palotas3-Dec-19 15:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 9 May 2019

Stats

13.9K views
1.1K downloads
36 bookmarked