Messing around with the telerik RadTransitionControl

by ManniAT 6. April 2010 14:46
Technorati-Tags: ,,

This series is about a promotion game we built to support our iPhone apps.
You can play the game here – it is “early stage” but you can really win!

For the newcomers – here the things start.
In the previous post I showed how the first steps using the telerik RadTransitionControl.
And I showed what we are trying to achieve.

TE

Here the things start to be a bit more complicated. As I told before we want to play this animation while we search for new twitter entries. Or more technical – while we are in a WCF call.
The first thing – you can not really predict how long it will take till the service call returns.
And even if you could it wouldn’t help. Of course you can set the animation duration, but that means that the animation takes more time (runs slower) which will not really look good.

So what we need are repeated animations.

  • Make the call
  • Start the animation
  • When the animation finishes check if we are still in the call
    If so – restart the animation
    Else – display the new value in the RadGauge

Unfortunately the RadTransitionControl doesn’t inform you when a transition (animation) finished.
And although there is a property “IsTransitioning” it doesn’t do what the name promises.
By the way – there is a second reason why we want to know the end of the transition.
As I wrote before – RadGauge animates value changes. And we want to have this visible.
This means we have to wait until the fade effect ends else it would be hard to see.

A second missing thing is a “start animation” method. The RadTransitionControl starts its animation automatically as soon as the content changes. But in our scenario the content wouldn’t change (always the same RadGauge).
So we also needed to implement this.

OK – the .NET way is to enhance functionality is to derive from the base control. We did it this way:

Snippet created with CBEnhancer
public class MyTransitionControl : RadTransitionControl {
    public event EventHandler OnTransitionFinished;
    DispatcherTimer m_dptWatchTransition;

    #region InTrasition
    public bool InTransition { get; set; }
    #endregion

    public MyTransitionControl() {
        m_dptWatchTransition = new DispatcherTimer();
        m_dptWatchTransition.Tick += new EventHandler(m_dptWatchTransition_Tick);
    }

    void m_dptWatchTransition_Tick(object sender, EventArgs e) {
        m_dptWatchTransition.Stop();
        InTransition = false;
        if(OnTransitionFinished != null) {
            OnTransitionFinished(this, EventArgs.Empty);
        }
    }
    public void StartTransition() {
        if(!InTransition) {    //only if not running
            object o = Content;
            Content = null;
            Content = o;
        }
    }
    protected override void OnContentChanged(object oldContent, object newContent) {
        base.OnContentChanged(oldContent, newContent);
        if(newContent != null) {    //don't watch removing
            m_dptWatchTransition.Interval = Duration;
            m_dptWatchTransition.Start();
            InTransition = true;
        }
    }
}

That’s all. A timer which starts when the content changes. When the timer ends we fire an event.
And we handle a Boolean “InTransition”.
Last not least we provide a “StartTransition” which only changes the content to “nothing” and back to what was in.
This in fact tells the RadTransitionControl to start its animation.

How is this used? Let me explain the general approach:

  • We start a WCF call
  • At the same time we initiate a transition (StartTransition)
  • When ever a transition ends we check if we are still in the WCF call
    If so – we start a new transition
  • If not we assign the new value to the RadGauge

YES – the gauge (to animate) also needs a change – in this case the value must change.
To handle this is also very easy. You remember – as long as we are in a WCF call we have a running transition.
When the call finishes we get an event (the result value changes). In that event we set the value of the RadGauge to 0. We can (almost) be sure that AFTER this the running transition will end.
And there we assign the new value – which shows a nice bar animation.
Here is some code:

Snippet created with CBEnhancer
void App_LastStatusChanged() {
    if(!rtcGauge.InTransition) { //wait to end transition
        EnterStatus();
    }
}
void rtcGauge_OnTransitionFinished(object sender, EventArgs e) {
    if(App.IsUpdatingStatus) {
        rtcGauge.StartTransition();
        return;
    }
    EnterStatus();
}

rtcGauge is the RadTransitionControl which holds the RadGauge. To have this running we only have to assign the event handler which is done like this:

Snippet created with CBEnhancer
rtcGauge.Transition = new WaveTransition { Angle = 0.5, Amplitude = 0.15 };
rtcGauge.OnTransitionFinished += new EventHandler(rtcGauge_OnTransitionFinished);

When you play the game you will see that the product images change. Of course this is also handled by a RadTransitionControl. We simply load a list of images and with a timer we change the content. The nice “move and zoom effect” is done with one line of code:

Snippet created with CBEnhancer
    rtcPromoImages.Transition = new SlideAndZoomTransition { MinZoom = 0.6 };
}
void m_dtImageChanger_Tick(object sender, EventArgs e) {
    if(!m_bImVisible) {
        return;
    }
    m_nCurImageIndex++;
    if(m_nCurImageIndex == m_aImages.Length) {
        m_nCurImageIndex = 0;
    }
    rtcPromoImages.Content = m_aImages[m_nCurImageIndex];
}

The “complicated” function shown after this single line of code does only check the bounds of our image array and then it assigns the next image to the RadTransitionControl.

I need to write a last few words about the RadGauge. First of all I want to show my laziness again and second I want to proof that I’m able to handle binding. After doing so much the “plain .NET way” I’m really afraid some of you might thing – this guy has no idea how Silverlight works Happy

The lazy part – of course I could have “restyled” the RadGauge. Or even I could have built my own custom control derived from RadGauge. Instead I created a user control, set a RadGauge as the only content and changed the look of it in Blend.
The only problem with that approach – I can’t bind a the value like this: Value=”{TemplateBinding TheVal}”. Of course I can’t do this – the control is not a template control; it’s a user control.

But (and here is the “I have a bit Silverlight knowledge” part Happy) User controls can also be data bound.
Here is (a part of) the markup:

Snippet created with CBEnhancer
<gauge:IndicatorList Margin="1,0,0,0">
    <gauge:LinearBar x:Name="linearBar" IsAnimated="true"
                    StrokeThickness="0"
                    BorderBrush="White"
                    StartWidth="0.04"
                    EndWidth="0.04"
                    Location="OverCenter"  Value="100" Opacity="0.82"
                    RangeColorMode="ProportionalLastRangesBrush"
                    RangeColorGradientOrientation="Center"
                    UseRangeColor="True" />
</gauge:IndicatorList>

And to bind the value of “linearBar” I do this in code behind:

Snippet created with CBEnhancer
public partial class DispCurVal : UserControl {
    #region TheValue (DependencyProperty)
    public int TheValue {
        get { return (int)GetValue(TheValueProperty); }
        set { SetValue(TheValueProperty, value); }
    }
    public static readonly DependencyProperty TheValueProperty =
        DependencyProperty.Register("TheValue", typeof(int), typeof(DispCurVal),  new PropertyMetadata(0));
    #endregion
    public DispCurVal() {
        InitializeComponent();
        linearBar.SetBinding(LinearBar.ValueProperty, new Binding() { Source = this, Path = new PropertyPath("TheValue") });
    }
}

Last not least – I didn’t write anything about RadBook we used to display our “game manual”. That is beyond the scope of this series. Just take a look at the telerik site. The control is “old” (which means well documented) and you’ll see that changing a (boring) scroll view with a manual (which nobody reads) to a great looking book is extremely easy with this control.
We did nothing more than to pull a list of objects (icon, topic, page content, and “page number text”) from a WCF service and bind this list to the RadBook.

I hope you enjoyed this series and maybe you’ve learned something new about the brand new and fantastic RadTransitionControl. By the way – the control can do more than that what I showed – give it a try.

And if you found this blog useful – take a look at our Promotion Game.
Although I used the game as an example in this blog – the thing is live; it is working and you can really play it and win prices.
It is “early stage” (maybe we find bugs) – but it’s no demo.
The game is a working thing which shall help us to promote our iPhone apps.

Support us by playing the game here – it is “early stage” but you can really win!

Thank you for reading
Manfred

Tags: , ,

telerik | Silverlight | iPhone

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Powered by BlogEngine.NET 2.0.0.0