Click here to Skip to main content
16,016,750 members
Articles / Desktop Programming / WPF

A WPF TileView Control

Rate me:
Please Sign up or sign in to vote.
4.58/5 (12 votes)
29 Nov 2011CPOL3 min read 82.1K   8K   36   24
A simple WPF TileView control.

TileView control

The TileView control lets you arrange a collection of items (Tiles) in a tile fashion, and one among the rest of the Tiles become active and is shown in a relatively larger area. Activation and deactivation of a Tile is animated. This behaves more or less like a Carousel control, but they are different.

Preview.png

Choosing the base

TileView presents a collection of tiles and arranges them in a different fashion. When it comes to presenting a collection of items, ItemsControl is the best pick, and most of the controls we often use are derived from ItemsControl, ListView, TreeView, or Menu and each of them have their own Items as well. TileView simply presents a collection so it derives from ItemsControl, and each Tile presents content. Obviously we one can go for ContentControl so we can present any content, but for the needs that may arise in future, Tile is derived from HeaderedContentControl. By ‘future needs’ I mean one may want to show a header, or buttons to activate / deactivate a tile.

Primary (simple) requirements

The behavior of the control is well known, and is defined in the introduction part of it. Here is the list of requirements to achieve this behavior.

  1. Tiles need to be arranged in a uniform manner, and the active one gains more space.
  2. Given that a field is required to keep track of the active tile, we have ActiveTile.

    A layout mechanism is needed to proportionally divide the space between the ActiveTile and the others, all the other tiles equally share the remaining space.

  3. One of the Tiles becomes active on load, and any other Tile can be activated using the mouse.
  4. A tile must be aware of the mouse events, and notify the TileView when activated, and for this, we need the Activated event.

  5. Activation and deactivation should be animated and smooth. ActiveTile is relatively large so an inactive Tile needs two transformations: ScallingTransform - to make it larger, TranslateTransform - to move it to the active position.

Bringing the words into action

Let's see how these requirements are achieved in reverse order.

Animating the tiles

As stated, two transforms are involved in activating a tile which operates on four different properties of a Tile. To move a Tile to the active position, TranslateTransform is used and it operates on the X and Y values of it, and to make the Tile larger, ScaleTransform is used and it acts on the width and height values. The following code demonstrates how this is done. This is just for representation of the values and the actual implementations differ from the representation.

C#
tile.RenderTransform = new TranslateTransform();

/* defining StoryBoard and animations */
Storyboard tileActivator = new Storyboard();
DoubleAnimation translateX = 
  new DoubleAnimation { From = 0, To = 10, Duration = TimeSpan.FromSeconds(1) };

/* Sets the target and the target property for the animation to operate */
Storyboard.SetTarget(translateX, tile);
Storyboard.SetTargetProperty(translateX, 
  new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));

/* Adds the animation to the StoryBorad and initiate the activation */
tileActivator.Children.Add(translateX);
tileActivator.Begin();

The same approach is used in all four properties of the Tile to make it active from an inactive state.

Tile activation notification

The TileView must be notified when a user activates it by a mouse click, this implementation defines an event Activated and just overrides the mouse down event to raise the Activated event. TileView listens for this Activated event and sets the sender as the new ActiveTile.

C#
public event RoutedEventHandler Activated;

protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
{
    base.OnMouseDown(e);

    if (Activated != null)
        Activated(this, new RoutedEventgArgs());
}

TileView listens to this event, casts the sender as Tile, and activates it.

C#
tile.Activated += new RoutedEventHandler(OnTileActivated);

void OnTileActivated(object sender, RoutedEventArgs e)
{
    ActivateTile(sender as Tile);
}

Arranging the tiles

The layout process in WPF happens in two passes: MeasureOverride and ArrageOverride, both of these are explained well in many articles. The former lets the child know the space available for it and asks the child the space it would take. And the former gives the space it can take.

C#
protected override Size MeasureOverride(Size constraint)
{
    var sz = base.MeasureOverride(constraint);

        foreach (Tile tile in Items)
    {
            /* size is the value TileView gives to each tiles */
            tile.Measure(size)
        }
        return sz;
}

protected override Size ArrangeOverride(Size arrangeBounds)
{
    foreach (Tile tile in OrderedItems)
        {
            /* rect is the value TileView layout 
               mechanism gives to each Tile */
            tile.Arrange(rect);
        }
        return arrangeBounds;
}

History

  • 16/11/2011 - Initial post.
  • 30/11/2011 - Added the TileState API, source and demo files updated.

Hope this helps !!! Happy coding !!!

License

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


Written By
Technical Lead
India India
I code, learn, read and listen.

Comments and Discussions

 
GeneralMy vote of 2 Pin
Member 103088232-Dec-13 2:04
Member 103088232-Dec-13 2:04 
GeneralRe: My vote of 2 Pin
VallarasuS2-Dec-13 8:07
VallarasuS2-Dec-13 8:07 
QuestionList Scrolling Pin
Member 194432025-Jul-13 2:30
Member 194432025-Jul-13 2:30 
AnswerRe: List Scrolling Pin
VallarasuS25-Jul-13 4:01
VallarasuS25-Jul-13 4:01 
QuestionSizing Pin
Patrick Blackman3-Apr-13 18:08
professionalPatrick Blackman3-Apr-13 18:08 
SuggestionRe: Sizing Pin
VallarasuS3-Apr-13 20:03
VallarasuS3-Apr-13 20:03 
GeneralRe: Sizing Pin
Patrick Blackman4-Apr-13 13:22
professionalPatrick Blackman4-Apr-13 13:22 
thanks will take that approach.
QuestionA few questions Pin
Doublej61925-Oct-12 17:24
Doublej61925-Oct-12 17:24 
AnswerRe: A few questions Pin
VallarasuS25-Oct-12 19:01
VallarasuS25-Oct-12 19:01 
GeneralInteresting ! Pin
Mazen el Senih7-Apr-12 2:32
professionalMazen el Senih7-Apr-12 2:32 
QuestionVery good! Pin
paleGegg030-Nov-11 22:15
paleGegg030-Nov-11 22:15 
AnswerRe: Very good! Pin
VallarasuS30-Nov-11 22:31
VallarasuS30-Nov-11 22:31 
GeneralRe: Very good! Pin
paleGegg01-Dec-11 1:49
paleGegg01-Dec-11 1:49 
GeneralMy vote of 4 Pin
Kanasz Robert29-Nov-11 22:44
professionalKanasz Robert29-Nov-11 22:44 
GeneralRe: My vote of 4 Pin
VallarasuS29-Nov-11 23:45
VallarasuS29-Nov-11 23:45 
QuestionSuggestion Pin
Patrick Blackman29-Nov-11 7:47
professionalPatrick Blackman29-Nov-11 7:47 
AnswerRe: Suggestion Pin
VallarasuS29-Nov-11 20:23
VallarasuS29-Nov-11 20:23 
AnswerRe: Suggestion Pin
VallarasuS29-Nov-11 23:54
VallarasuS29-Nov-11 23:54 
GeneralRe: Suggestion Pin
Patrick Blackman30-Nov-11 3:34
professionalPatrick Blackman30-Nov-11 3:34 
GeneralMy vote of 4 Pin
Espiritu28-Nov-11 15:51
Espiritu28-Nov-11 15:51 
GeneralRe: My vote of 4 Pin
VallarasuS28-Nov-11 16:54
VallarasuS28-Nov-11 16:54 
QuestionFixed Title height and width Pin
Patrick Blackman28-Nov-11 7:14
professionalPatrick Blackman28-Nov-11 7:14 
AnswerRe: Fixed Title height and width Pin
VallarasuS28-Nov-11 7:27
VallarasuS28-Nov-11 7:27 
GeneralRe: Fixed Title height and width Pin
Patrick Blackman28-Nov-11 8:27
professionalPatrick Blackman28-Nov-11 8:27 

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.