Telerik blogs

The Silverlight team decided to remove the ScrollBar control that used to be part of CoverFlow's control template. One of the reasons behind this decision is the easiness by which you can now, using Silverlight 3 element binding, create your own navigation. To learn more about all changes introduced by the beta version check my previous blog post here. This article explains in details how to create your own navigation using a range control, e.g. one that inherits from the RangeBase class.

The first thing we need to do is to declare a CoverFlow control with some items in a straight-forward manner.

<StackPanel x:Name="LayoutRoot">
    <telerikNav:RadCoverFlow x:Name="cover" Height="600" ItemHeight="200" ItemWidth="200">
        <telerikNav:RadCoverFlowItem Background="White"/>
        <telerikNav:RadCoverFlowItem Background="Red"/>
        <telerikNav:RadCoverFlowItem Background="Green"/>
        <telerikNav:RadCoverFlowItem Background="Yellow"/>
        <telerikNav:RadCoverFlowItem Background="Blue"/>
        <telerikNav:RadCoverFlowItem Background="Pink"/>
    </telerikNav:RadCoverFlow>
</StackPanel>

 

To make things simpler you can either implement your own range control or choose among a ScrollBar, a RadNumericUpdown or a RadSlider. Using element binding you can easily associate the SelectedIndex of the CoverFlow to the value of your range control like this.

<telerik:RadSlider Value="{Binding SelectedIndex, ElementName=cover, Mode=TwoWay}"/>

Now if you change the value of the slider control, the binding will also change the SelectedIndex of the CoverFlow control declared above. However, you also need to constraint the range from the Minimum possible index to the Maximum one. You can safely associate the Minimum value to zero, on the other hand the Maximum value needs some further consideration as your collections will vary in size. That is why, you need a binding that will always check the size of the collection and constraint the range control to it. The easiest way to do that is to create another binding that binds to the count of the items of your collection similar to this:

<telerik:RadSlider Value="{Binding SelectedIndex, ElementName=cover, Mode=TwoWay}" Minimum="0" Maximum="{Binding Items.Count, ElementName=cover}"/>

 

Note that if you use ItemsSource for binding you should substitute the Items.Count Path to ItemsSource.Count. However, property Count is not zero based value like the index array. Due to that, we will have an extra element available in our range. Unfortunately, there is no way you can tell the expression binding tto evaluate an expression that binds the property less a certain number, e.g. Items.Count -1. However, you can create a simple ValueConverter that can do the heavy lifting for you. Here is a simple int to int value converter that just sums the value and the converter parameter.

public class IntToIntValueConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int val;
        int param;
        if ((int.TryParse(value.ToString(), out val) && (int.TryParse(parameter.ToString(), out param))))
        {
            return val + param;
        }
        return value;
    }
 
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is int && parameter is int)
        {
            return (int)value + (int)parameter;
        }
        return DependencyProperty.UnsetValue;
    }
}

You can easily declare the value converter class as a static resource part of the page and associate it with the Converter property of the Binding Expression. You also need to provide the converter parameter, in our case, -1. You final version should look similar to this:
<UserControl.Resources>
    <local:IntToIntValueConverter x:Key="IntToIntValueConverter"/>
</UserControl.Resources>
    <StackPanel x:Name="LayoutRoot">
    <telerikNav:RadCoverFlow x:Name="cover" Height="600" ItemHeight="200" ItemWidth="200">
        <telerikNav:RadCoverFlowItem Background="White"/>
        <telerikNav:RadCoverFlowItem Background="Red"/>
        <telerikNav:RadCoverFlowItem Background="Green"/>
        <telerikNav:RadCoverFlowItem Background="Yellow"/>
        <telerikNav:RadCoverFlowItem Background="Blue"/>
        <telerikNav:RadCoverFlowItem Background="Pink"/>
    </telerikNav:RadCoverFlow>
    <telerik:RadSlider Value="{Binding SelectedIndex, ElementName=cover, Mode=TwoWay}" Minimum="0" Maximum="{Binding Items.Count, ElementName=cover, Converter={StaticResource IntToIntValueConverter}, ConverterParameter=-1}"/>
</StackPanel>

Note that all properties used in this example are inherited from the RangeBase control, thus you can easily change name of the control and set some control-specific properties to have navigation based on RadNumericUpDown or ScrollBar like this:
<ScrollBar Orientation="Horizontal" Value="{Binding SelectedIndex, ElementName=cover, Mode=TwoWay}" Minimum="0" Maximum="{Binding Items.Count, ElementName=cover, Converter={StaticResource IntToIntValueConverter}, ConverterParameter=-1}"/>

Or
<telerik:RadNumericUpDown ShowTextBox="False" Value="{Binding SelectedIndex, ElementName=cover, Mode=TwoWay}" Minimum="0" Maximum="{Binding Items.Count, ElementName=cover, Converter={StaticResource IntToIntValueConverter}, ConverterParameter=-1}"/>

 

I hope this will alleviate some of the hassle cased by the lack of navigation in our new CoverFlow control. Stay tuned for all new things the Telerik team has prepared.


About the Author

Hristo Borisov

Hristo Borisov (@hristoborisov) is currently a product line manager in Telerik leading all cloud technologies part of the Telerik Platform after spending more than 6 years with the company. A passionate advocate of applying lean startup practices to existing organizations, Hristo is on the quest for discovering scalable and sustainable business models through product and customer development using tools like MVPs, Pivots, and Lean Business Model Canvases.

Comments

Comments are disabled in preview mode.