Home .NET Message Hub style message list

Message Hub style message list

by admin

If you’ve already developed apps for Windows Phone 7, you may have already noticed the absence of some controls such as Hub Tile, grouped list, or message list. You can find some of them in the Silverlight Toolkit for Windows Phone library. But what do we do when we need to create an application similar to the standard Message Hub? The main problem is that in the standard LisBox, the elements are placed from top to bottom, while in the Message Hub, it’s the other way around.
Message Hub style message list
I would like to demonstrate one solution to this problem. All we need is a standard ListBox control, the System.Windows.Interaction library from Blend SDK and some knowledge of visual component transformation.
So. As I said before, the standard ListBox places its elements in the VirtualizingStackPanel in a top-down direction. Writing your own VirtualizingStackPanel that will place elements from bottom to top can be very time consuming. In addition, the standard VirtualizingStackPanel already contains virtualization logic that solves the problem of consuming huge amounts of memory. All we need is to flip the ListBox upside down, so that the new items are placed at the bottom. To do this, we use ScaleTransform:

<ListBox> <ListBox.RenderTransform> <ScaleTransform ScaleX="1" ScaleY="-1"> </ListBox.RenderTransform> </ListBox>

Now our ListBox is upside down, but has moved up. In order to put it back in place, you need to specify the center of the transformation. In our case this is the vertical center, i.e:

_scaleTransform.CenterY = ListBox.ActualHeight / 2;

As you can see, the elements of our ListBox are also upside down. To return them to their normal position, let’s use the same method that we used for the whole list.
MVVM fans may cringe at the extra code in the .xaml.cs files. I usually write all extra logic in Behavior from the System.Windows.Interaction library. For this let’s create a MirrorBehavior class with code :

public class MirrorBehavior : Behavior<Control> {private readonly ScaleTransform _transform = new ScaleTransform();public MirrorBehavior(){_transform.ScaleX = 1;_transform.ScaleY = -1;}protected override void OnAttached(){UpdateCenter();AssociatedObject.SizeChanged += AssociatedObject_SizeChanged;AssociatedObject.RenderTransform = _transform;}protected override void OnDetaching(){AssociatedObject.RenderTransform = null;AssociatedObject.SizeChanged -= AssociatedObject_SizeChanged;ResetCenter();}private void AssociatedObject_SizeChanged(object sender, SizeChangedEventArgs e){UpdateCenter();}private void UpdateCenter(){_transform.CenterY = AssociatedObject.ActualHeight / 2;}private void ResetCenter(){_transform.CenterY = 0;}}

All that remains is to apply it to our controls :

<ListBox ItemsSource="{Binding Messages}"> <i:Interaction.Behaviors> <Interactivity:MirrorBehavior /> </i:Interaction.Behaviors> <ListBox.ItemTemplate> <DataTemplate> <ContentControl HorizontalContentAlignment="Stretch"VerticalContentAlignment="Stretch"ContentTemplate="{StaticResource MessageTemplate}"Content="{Binding}"> <i:Interaction.Behaviors> <Interactivity:MirrorBehavior /> </i:Interaction.Behaviors> </ContentControl> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

This solution is good because it uses standard styles and built-in virtualization.

You may also like