window phone 7 InputScope

by ManniAT 22. August 2010 12:58

Shawn Wildermuth made a nice video about Tombstoning.
In this video he also provided some information about InputScope.

In this post I’ll focus on input scopes – and on input in wp7 general.
And I’ll compare it to the iPhone input (keyboard) handling.

First of all what’s this InputScope – in simple words – you can change the behavior of the on screen keyboard by setting this value on an input element (like a TextBox). For this post I’ll always use TextBoxes.

Focusing a TextBox brings up the Keyboard. Depending on the InputScope this Keyboard has different features.
For an example the value TelephoneNumber brings up a keyboard like this:

PhoneNumberKeyboard

But InputScope does more – it also changes other behaviors like suggestions or capitalization.
Here an example which brings suggestions:

ChatKeyboard

It is defined like this: <TextBox InputScope="Chat" />

The thing is beta and some things will hopefully change!
My favorite (to change) is Url Eye-rolling

UrlKeyboard

Looks nice – maybe – lets check with the Microsoft windows phone 7 forum:

http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series

First of all – we can discuss about the need for that big space in Url input.
I would say (maybe I’m wrong) spaces are not so often part of a Url.
So this space key could be smaller to make place for a much more important key the slash.
In the above Url we have 5 slashes – I guess this is worth an extra key.
For the domain you can “touch and hold” the button which brings up a (very short) list of other domains.
iPhone: here you get extra: .eu (yes Europe exists), .us and a “local domain” (like .de for my German iPhone).

Anyhow – domains are not so important – but the slash…
So lets hope this will change till RTM.

Now two words on the differences to the iPhone.
With the iPhone in general you as a developer are fully responsible for handling the keyboard.
There are also “styles” (keyboard layout) – but Correction, Capitalization and so on depend on the system settings, not on the “style”.
Although the keyboard comes up automatically when you focus a TextBox this is more or less everything you get.
The rest has to be done via delegates (in simple words you have to write a “keyboard handler”).
This is even needed for simple things like “dismiss the keyboard”. Tapping somewhere (not on a TextBox) removes the keyboard in wp7 – but not so on the iPhone.

Also you are responsible for situations where the keyboard overlays your content. There is no “auto-scroll into view” like with wp7.

But there are also positive aspects with the iPhone:

  1. Clear button
    A settings which brings up a little button at the right side of a textbox which clears the content
  2. Select text
    Done with a nice magnifier and also (after you have a selection) “changeable” (drag start / end)
    Further there is a “context menu” – “select all” and so on.
  3. Clipboard support
    Simply by tap and hold you can do copy (selected text), paste and so on

Anyhow – we have Silverlight – so we can build or own TextBox which has these features – and even more.
And (except for the Magnifier) it is not much work I guess.

2 Points are left – a short look at the keyboard in the WebBrowser control – and of course some code.

About the WebBrowser control – there is a lot to say – but here I’ll only talk about some “keyboard aspects”.
Working on a port of my RPS iPhone application I have a facebook login page – take a look:

WebBrowserKeyboard

Looks good?
No it does definitely not! At least compared to the iPhone!
On the iPhone I get – a “Next” and a “Previous” button on top of the keyboard.
Further I get a “Done” button which dismisses the keyboard (only important if I find no “free area” to tap).
And – much more important – instead of the return I get an “Open” button.

These “little helpers” enable fast an “Desktop like” input.
Enter email – tap next – enter password – tap open – done.

On wp7 – enter email.
Tap “somewhere” (if “auto-zoom” did work).
Tap password
Tap somewhere
Tap login

With the auto-zoom I mean a look like this:

WebBrowserAZKeyboard
Sometimes when you hit a textbox the WebBrowser brings this up close.

Anyhow – this is beta – so there is hope Smile

Last not least a piece of code to play with the InputScope values.
Create a windows phone 7 application.
In MainPage.xaml add the following to the content grid:

Snippet created with CBEnhancer
<Grid x:Name="ContentGrid" Grid.Row="1">
    <ListBox x:Name="lbScopes">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200" />
                        <ColumnDefinition Width="270" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                    <TextBox InputScope="{Binding}" Grid.Column="1" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

Further add a handler for the loaded event of the page.
Add this code to the handler:

Snippet created with CBEnhancer
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
    List<string> m_lE = new List<string>();
    foreach(FieldInfo fI in typeof(InputScopeNameValue).GetFields(
        BindingFlags.Static | BindingFlags.Public)){
        m_lE.Add(fI.Name);
    }
    lbScopes.ItemsSource = m_lE;
}

This brings up a list with all available InputScope values. Simply scroll through the list, focus on of the TextBoxes and you can check what the keyboard does when you use the specific value.

Kudos to Shawn Wildermuth for his great videos and blog posts.

And I’m sure he would end a thing like this with: Makes sense? Thumbs-up

Manfred

Tags: , ,

Silverlight | windows phone 7 | wp7

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

Cool look out of the telerik box

by ManniAT 6. April 2010 13:33
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!

Like explained in the previous posts of the series we’ve been building a promotion game for our iPhone apps.
The facts:

  • We have skills on “game mechanics”
  • We have skills on “infrastructure”
  • We have skills on Silverlight
  • We are everything else than designers

Fortunately telerik introduced a new control the RadTransitionControl which helped us a lot with our project.
I already did some work with the RadGauge and the game has a part where this control could help.

Lets talk about this step first. Part (main) of the game is that you (the player) spread information about the promotion. As I wrote before we use twitter as “transport” for this. For us it is important that as much people as possible get informed about the game / product. To motivate the player to spread the news we offer promotion codes as prices.
Each promotion code has its own “win counter” – a number which must be reached to win.
We measure “how much” a player spreads the information via his "follower counter”. Depending on this value (we have limits and calculations behind it) we raise the “Promo code counter”.
The reason that every code has its own counter is to bring some kind of “dynamics” into the game.
The player never knows the number of points needed to reach the goal.

Anyhow – to give the player some feedback we decided to use a RadGauge to display the percentage of the current counter. RadGauge has some kind of animation built in which animates the “needle / bar” when the value changes. But in our scenario this was not enough. As I told before we use a WCF Service to query twitter. This can be a bit (Seconds) time consuming.

From the client perspective two things happen: The search (takes time) and the display of a new value.
I had the idea to simulate some kind of “tuning thing” while we retrieve the new information.
Maybe you remember old films where an actor hits his (monochrome) TV to get a better display.
The display “flickers” and after some time (punches) it becomes sharp. You may have also seen effects like this in “Space Movies” when the video link to the starship is bad.
I think an effect like this reflects best what’s going on behind the scenes – we have “un-sharp” information about the current value and we try to get better ones. Here is what I mean:

TE

We have 3 “pages” in the solution – First a manual, next the game itself and last not least a “popup” when we found a result.
The next thing we wanted to achieve was a “page transition”. Silverlight offers things for this – but RadTransition impressed me so much that I decided to do this also with that control.

We need such a “page transition” 2 times – once when the user starts the game (from manual to game) and a second time when the user clicks the “help button” (from game to manual).

And we need some kind of “popup” to display the game result a soon as we find the entry (tweet made by the player) in twitter.

The popup was very easy – we just used a RadWindow changed its style (we need no border or things like this) and called the “ShowDialog” method of the window.
The window contains a user control with the information. It also has two buttons OK / Cancel. OK ends the game, Cancel keeps the game open (with limited functionality). And the content of the popup depends on what happened. The player won, he did not win, he spammed…
For this our user control offers a function to set the information (yes no binding Happy).

As you may know everything (almost) in Silverlight is asynchronous. So RadWindow will not stop the calling thread. Instead it will fire an events when something happens. For us it is important to know when the window closes. There we have to find out if the user clicked OK or Cancel. Here is the window markup:

Snippet created with CBEnhancer
<telerikNavigation:RadWindow x:Name="rwFoundInfo" CanClose="True" CanMove="False" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" Style="{StaticResource RWInfoStyle}">
    <local:FoundInfoDisplay x:Name="fdFoundDisplay" />
</telerikNavigation:RadWindow>

In code behind we do:

Snippet created with CBEnhancer
    rwFoundInfo.Closed += new EventHandler<WindowClosedEventArgs>(rwFoundInfo_Closed);
    fdFoundDisplay.SetInfoText(strResult, strResultInfo, App.ThePromoInfo.CodePrompt, strCode, App.ThePromoInfo.OKInfo, App.ThePromoInfo.CancelInfo, App.ThePromoInfo.PromoImage, App.ThePromoInfo.PromoTitle);
    rwFoundInfo.ShowDialog();
}
void rwFoundInfo_Closed(object sender, WindowClosedEventArgs e) {
    if(e.DialogResult.HasValue && e.DialogResult.Value) {
        HtmlPage.Window.Navigate(btnResearch.NavigateUri);
    }
}

And the user control in the window does this to handle OK / Cancel:

Snippet created with CBEnhancer
private void btnOK_Click(object sender, RoutedEventArgs e) {
    RadWindow rW = RadWindow.GetParentRadWindow(this);
    rW.DialogResult = true;
    rW.Close();
}

private void btnCancel_Click(object sender, RoutedEventArgs e) {
    RadWindow rW = RadWindow.GetParentRadWindow(this);
    rW.DialogResult = false;
    rW.Close();
}

Very little code, and what we get is a modal (!!) popup which displays information.
OK – some code is not displayed here – it is the (stupid) transfer of values to control content in SetInfoText.
But this is “our problem” – we could have used bindings or other things.

Now back to the RadTransitionControl. We have a user control which holds the surrounding border the background image and the promotion title / icon. In it we display two different things – the manual and the game itself. It looks like this:
HolderManual HolderGame

Our goal was to have two different transitions – one for manual ==> game and the other for game ==> manual.
Here is what I mean (static):

HolderTrans1 HolderTrans2

To do this we needed a bit of code – first the markup (part of it) from the “holder”:

Snippet created with CBEnhancer
<telerik:RadTransitionControl Grid.Row="1" Grid.ColumnSpan="2" x:Name="rtcTrans" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="3,0,0,0">
</telerik:RadTransitionControl>

In Code behind we do the following:

Snippet created with CBEnhancer
public MainPage() {
    InitializeComponent();
    m_fwPTrans = new FlipWarpTransition();
    m_rtTrans = new RollTransition();
    rtcTrans.Transition = m_fwPTrans;
}

We create two “transitions” and assign one to the RadTransitionControl (Manual to Game).
Have a look at the telerik demos to see these animations live.

Snippet created with CBEnhancer
private void UserControl_Loaded(object sender, RoutedEventArgs e) {
    btnHelp.Visibility = Visibility.Collapsed;
    m_ucInfoPages = new InfoPages();
    m_ucInfoPages.StartClicked += new InfoPages.StartClickedDG(ucInfoPages_StartClicked);
    rtcTrans.Content = m_ucInfoPages;
}

void ucInfoPages_StartClicked() {
    if(m_gIC == null) {
        m_gIC = new GameInnerContent();
    }
    rtcTrans.Transition = m_fwPTrans;
    rtcTrans.Content = m_gIC;
    btnHelp.Visibility = Visibility.Visible;
}

private void btnHelp_Click(object sender, RoutedEventArgs e) {
    rtcTrans.Transition = m_rtTrans;
    rtcTrans.Content = m_ucInfoPages;
    btnHelp.Visibility = Visibility.Collapsed;
}

First we hide the “help button” (not needed when we display the manual). Next we create the manual user control assign a handler for the StartButton and simply set it as content of the RadTransitionControl.
The button handlers (Start / Help) are also very easy. They set the wanted transition and assign the Content to the RadTransitionControl. This (content changed) starts the transition automatically.

There is no hidden code or other “magic behind” – except (of course) the one provided by telerik.

As I told you before – the RadTransitionControl if “beta” (CTP) so there are some things missing at the moment. But it is very easy to implement those parts. We needed to do this for our “fade effect”. The things are (a little bit) tricky – so I made an extra post about that.

Stay tuned
Manfred

Tags: , ,

iPhone | Silverlight | telerik

The Silverlight side of life

by ManniAT 5. April 2010 23:33
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!

Before I wrote about WCF Services – here is the client part of this.
For the newcomers – here is the start of this series.

When we create a reference to a WCF service we get everything we need generated.
So we have the classes we use with the service, methods to invoke the service and so on.

I decided to keep these generated class as they are. The question was WHERE do I call the methods.
Since the service is “not perfectly designed” some calls contain things that are needed in multiple “forms”.

So my decision was to do the things in the application class. And I use simple .NET events and properties to handle WCF calls and their results.
The idea is simple and easy. App has some static properties (and methods) which interact with the WCF service.

A sample:

Snippet created with CBEnhancer
private static PromoInfo m_piThePromoInfo;
public static PromoInfo ThePromoInfo {
    get { return m_piThePromoInfo; }
    private set {
        if(m_piThePromoInfo != value) {
            m_piThePromoInfo = value;
            if(PromoInfoChanged != null) {
                PromoInfoChanged();
            }
        }
    }
}

And the “form” (user control) subscribes to this event (PromoInfoChanged) like this:

Snippet created with CBEnhancer
    App.PromoInfoChanged += new App.EntryChangedDG(App_PromoInfoChanged);
}

#region Promoinfo handling
void App_PromoInfoChanged() {
    SetPromoInfo(App.ThePromoInfo);
}
private void SetPromoInfo(PromoInfo pI) {
    if(pI == m_piLastSet) {    //we got this - nothing new to set
        return;
    }
    m_piLastSet = pI;    //remember it
    string strUriExtend = pI.PromoTweetStartText + App.CallKey + " " + string.Format(pI.SpreadTextAddition, pI.TwitterName);
    //btnFollowMe.NavigateUri = null;

    btnSpread.NavigateUri = new Uri("http://twitter.com/?status=" + HttpUtility.UrlEncode(strUriExtend));
    txtFollowMe.Text = pI.FollowMeText;
    App.SimpleFormatToHTML(pI.FollowMeTextInfo, tbFollowMeInfo);
    txtSpread.Text = pI.SpreadText;

And if the “form” wants to call a WCF method it looks like this:

Snippet created with CBEnhancer
if(!App.IsSearching) {
    if(App.SearchResult()) {
        rtcSearchResults.StartTransition();
    }
}

I know I could do some of these things using binding and dependency properties or “more Silverlight like” methods. But it fulfills my needs in this case and (as you see in the above method) one part of this project is the extended use of the new telerik RadTransistionControl.

The next post will handle this topic – and it will address readers which may not be so familiar with Silverlight as you might be. Since the RadTransitionControl is really new I feel (in my role as telerik MVP) a need to write something about this control which also helps newcomers.
So please excuse my “primitive” handling here.

To finalize the above shown things here the completed handler for the PromoInfo call:

Snippet created with CBEnhancer
void m_tsClient_GetPromoInfoCompleted(object sender, GetPromoInfoCompletedEventArgs e) {
        if(e.Error == null && e.Cancelled == false) {
            ThePromoInfo = e.Result;
        }
    }

That’s it about the WCF Silverlight client. In the next part I’ll show you how simple you can achieve stunning results, cool animations and other things like this – even if you are a “got to be used to designer” like me Happy

Stay tuned
Manfred

Tags: ,

Silverlight | twitter

WCF and the rest

by ManniAT 5. April 2010 22:31
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!

As I told before we used Silverlight to implement this game. And we do some UI localization (English, German) using Database Tables with “simple HTML”. I described this here.

I guess most of you know that Silverlight is a client technology. This (among others) means that we have no direct database access.

All we can do must be done with some kind of “Web Server Communication”. There are RIA Services (too enhanced for my simple project) and of course “plain” Windows Communication Foundation – or WCF Services.

That’s what I use. So I have a service which provides a list of “ManualPage entries”.
A manual page has: PageNumber, PageTopic, PageContent and “PageNumberText” (a formatted version of PageNumber).

The service method looks like this:

Snippet created with CBEnhancer
[OperationContract]
public List<PromoManualPage> GetManual(string strLangCode) {
    return (new PromoManual(strLangCode).PageList);
}

The constructor of PromoManual reads the pages from the database and provides it in it’s “PageList” memeber.
This looks good – BUT – there is a but.
Assume a lot of players are online. Every time a new player joins the game we create our instance of PromoManual, retrieve the manual from the database – send it to the client…

How often will this manual change? OK, while development often – you are right. But then? Almost never compared to the frequency of calls to this WCF method.

So it is a good idea to keep the things in memory somehow to prevent heavy (and useless) database access.

Static objects? No – we already have a cool thing for this – the cache!
Our call turns to this:

Snippet created with CBEnhancer
[OperationContract]
[OperationBehavior(AutoDisposeParameters = false)]
public List<PromoManualPage> GetManual(string strLangCode) {
    return (GetCachedManual(strLangCode).PageList);
}

And the method we call looks like this:

Snippet created with CBEnhancer
public static PromoManual GetCachedManual(string strLanguageCode) {
    //return (new PromoManual(strLanguageCode));

    string strCacheName = "PM_" + strLanguageCode;
    Cache cH = HttpRuntime.Cache;
    PromoManual pM = cH[strCacheName] as PromoManual;
    if(pM == null) {
        pM = new PromoManual(strLanguageCode);
        //reflect manual changes after 30 minutes - or simply free memory if the game "sleeps"
        cH.Insert(strCacheName, pM, null, DateTime.UtcNow.AddMinutes(30), Cache.NoSlidingExpiration);
    }
    return (pM);
}

This means we search for PM_xx (xx==Language Code) in the cache. If we don’t find it we create such an object and place it in the cache. In this case I decided to keep the things 30 Minutes in Cache.
So I can update my manual pages (fix typos or whatever) – and after max. 30 minutes the players will see the new version. And if the game “sleeps” (no one plays) I’ll free the memory.

Have you seen the commented line? – That’s for text editing when I want to see changes immediately.

Someone may have noticed that I added an OperationBehaviour to my WCF Method.
The reason for this (I had to learn it the bitter way) – WCF call Dispose if your class implements IDisposable.
While this is a good idea if the object dies (fast resource release) it turn into an enemy when you want to keep your objects in cache.

Our Access to twitter is also cacheable. But it is handled a bit different.

Snippet created with CBEnhancer
public static TwitterAccessor GetCachedTwitterAccessor() {
    string strCacheName = "TWA_Accessor";
    Cache cH = HttpRuntime.Cache;
    TwitterAccessor twA = cH[strCacheName] as TwitterAccessor;
    if(twA == null) {
        twA = new TwitterAccessor();
        cH.Insert(strCacheName, twA, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(10));
    }
    return (twA);
}

The difference is the insert call. Here we don’t use a absolute expiration. Instead we use a sliding expiration.
So as long as someone (within 10 Minutes) calls the accessor from the cache this timer starts again.
There is no need for “absolute” expiration – like with the manual pages.

One last “mystery” about the twitter access. If I search for a new “promotion tweet” I do it like this:

Snippet created with CBEnhancer
private static PromoSearchResult GetSearchResult(string strPromoName, string strEntryCode) {
        PromoList pL = GetCachedPromoList(strPromoName);
        if(!pL.DoesEntryExist(strEntryCode)) {    //we didn't find it
            TwitterAccessor twA = GetCachedTwitterAccessor();
            DateTime dtLastTwitterSearch = twA.GetLastSearchForThisPromo(strPromoName);
            //30 seconds would mean (if full running) 120 calls - 150 are available
            //50 means about 72 calls - thats fine for us - as long as we run not more than TWO promos a time (and fully loaded)
            if(dtLastTwitterSearch.AddSeconds(50) < DateTime.Now) {    //if older than - try to find it
                ulong ulLastPost = pL.GetLastPromoID();
                PromoInfo pI = GetCachedPromoInfo(strPromoName, "en");    //always use english
                List<PromoEntry> lPE = twA.SearchEntries(strPromoName, ulLastPost, pI.PromoTweetStartText);
                if(lPE != null && lPE.Count > 0) {    //we found something
                    pL.HandleTwitterData(lPE, twA);
                }
            }
        }
        return (new PromoSearchResult(strPromoName, strEntryCode));
    }

Notice that I avoid searches due to the “twitter call limit”. YES there are methods that allow me to check the current limit – and linq2twitter supports these methods. But I was lazy and avoided to implement it.
By the way it is not so easy as it looks (what if I have little calls in the beginning – and later massive access?) to implement a real good solution which brings the best (use almost all 150 calls) result.

Of course I could do this – but laziness is not the only reason to avoid it.
As a part of the game you should answer 3 questions – or in other words “learn more about the product”.

Who do you think would do this if he clicks a button – and at the very moment he gets a result?
By the way – this would never happen – twitter search also has some delay.

Anyhow – you do something in the game – I search for it – but I take time to do this – while you search for answers in the game. The balance is not to bad (boring) with less than a minute searches.
And if you follow the game (as I want you to do) – you initiate the call (tweet promotion) – look for the answers and normally I would have found your tweet before you could find the answers.

Two things also to consider – 50 seconds is “worst case” and even if you hit this – the “new PromoSearchResult” contains your result if the twitter search found it in the call 50 seconds before.

A last word about the Cache – always use it in scenarios like this! Online “things” (if successful) may have a lot of calls per second. And (in most cases) it makes no difference for the client if the data is 1 or 3 seconds old.
But it makes a lot of difference for your infrastructure (database and so on).
What I means is – even in situation where data is very volatile – it’s worth to cache for 2 seconds or even one if the load on your server is heavy.

In the next post I’ll handle the Silverlight parts of these WCF service.

Stay tuned
Manfred

Tags: ,

Silverlight | twitter

Infrastructure and RadGrid

by ManniAT 5. April 2010 20:39

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!

As I told in the post before I’ve built a promotion game using some telerik Silverlight Controls.

But let me start with some basics about the game.
One of the goals is to localize it. I know a bit English (my blog proof how bad it is) and (a bit more) German.
So I decided to build the game in those two languages.
This also follows the website where the game is hosted: http://iphone.pp-p.net

The database freaks will hate me for this – but I decided to use a “un-normal” table to fulfill my localization needs. This makes the things easy – but handling the things (many columns) is a bit uncomfortable.

Again the basics – I have to place text on my UI. This should be (at least a bit) formatted.
So I built a little “formatter” in Silverlight which is able to handle some (very basic) HTML.
As you’ll see later RadGrid provides a HTML Editor which (by default) has Bold, Underline, Italic, and Strike through as a “Attribute Buttons”. For my needs this is enough.
Bold, Underline and Italic do what they should – and Strike makes blue text.

Let me show you an example of the result:
FollowMe  FollowMeDE

As you see we have two things – the Button Text – and a description (a bit formatted).
This goes on for (almost) every UI element in the game.

The other thing is the “Game Manual”. It has limited Space, wrapping and so on.
What I wanted was to see how it will look in Silverlight when I edit it in my RadGrid.

The solution – in both cases is almost the same – and it’s easy.
I have to manipulate the “Grid generated” HTML Editor.
Let’s start with the manual:

The table looks like this: ID, LanguageCode, PageNumber, PageTopic, PageContent

The result is something like this:
ManualPage  EditManualPage

As you can see both (the result and the editor) have the same dimensions and line breaks.
So how long did it take me to build this thing?

Since the editor is part of a bigger project a build takes about 30-45 seconds. And I had to build the thing several times since I adjusted the width by “trial and error” until the line breaks were similar.

Using RadGrid it took me (including everything) about 7 Minutes Happy

Step by Step:

  • Create a new page
  • Drag a Linq2SQL Datasource, RadScript and RadAjaxManager to it
  • Drag a RadGrid to it (and add it to the AjaxManager)
  • Choose the data source for the RadGrid
  • Change telerik:GridBoundColumn to telerik:GridHTMLEditorColumn for the PageContent column
  • Add EnableAutomaticUpdates=”true” to RadGrid
  • Add a handler for OnItemDataBound to the grid
  • Code the handler (see below)
  • Build – Run - Check the size
  • Adjust the size
  • Build – Run – Check the size
  • DONE – I got a WYSIWYG editing tool for my manual pages!!

Snippet created with CBEnhancer
protected void rgPromoManual_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e) {
            if(e.Item is GridEditableItem && e.Item.IsInEditMode) {
                GridEditableItem item = (GridEditableItem)e.Item;
                RadEditor editor = (RadEditor)item["PageContent"].Controls[0];
                editor.Width = 222;
                editor.Height = 320;
                editor.ContentFilters = EditorFilters.ConvertToXhtml | EditorFilters.FixEnclosingP;
            }
        }

The handler changes the ContentFilters and the dimensions of the “Grid generated RadEditor”.
I had to change the Filters to avoid “extra good” formatting – which I don’t handle.
For an example it would (normally) change the U tag to a span with a style and other things like this.

Now to the “un-normal” UI texts. Here I have a lot of columns – most of the need “basic HTML” formatting.
A short look at the table: ID, PromoName, LanguageCode, FollowMeText, FollowMeTextInfo, SpreadText, SpreadTextInfo, ResearchText, ResearchTextInfo, QuestionText, QuestionTextInfo, Question1Text, Question2Text, Question3Text, CurPercentInfo,…

OK – hate me for “un-normal” table design Cool

How long did it take to build an editor for this?
It was less than for the manual – I saved time since I had no need for “fitting line breaks”.
The steps are almost the same as before – except:

  • Change telerik:GridBoundColumn to telerik:GridHTMLEditorColumn for a lot of colums
    I did it with “Search and Replace” in “Selection” after marking the colums
  • Changed the layout to two colums (to avoid massive scrolling)
  • Adding EditFormColumnIndex="1" to every second colums (copy and paste of course)
  • Copy all GridHTMLEditorColums to the code behind files
  • Using an “add hoc macro” to extract the UniqueName="LanguageCode" from every column
  • Change the code handler (see below)
  • DONE
Snippet created with CBEnhancer
private static string[] aEditorIDs ={"FollowMeTextInfo", "SpreadTextInfo", "ResearchTextInfo", "QuestionTextInfo", "Question1Text",
                                        "Question2Text", "Question3Text", "CurPercentInfo", "ResultTextInfo", "ResultSearching", "ResultFound",
                                        "ResultWon", "ResultSpam", "OKInfo", "CancelInfo", "CodePrompt", "WonInfo", "SpamInfo", "FoundInfo" };

protected void rgPromoTexts_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e) {
    if(e.Item is GridEditableItem && e.Item.IsInEditMode) {
        GridEditableItem item = (GridEditableItem)e.Item;
        foreach(string strColumnID in aEditorIDs) {
            RadEditor editor = (RadEditor)item[strColumnID].Controls[0];
            editor.Width = 330;
            editor.Height = 120;
            editor.ContentFilters = EditorFilters.ConvertToXhtml | EditorFilters.FixEnclosingP;
        }
    }
}

The result looks like this:

EditInfoTexts

Conclusio:
Using the telerik RadControl for ASP.NET AJAX it took me less than 15 Minutes to build two “WYSIWYG” editors for my game content.

One trick I forgot to tell you – since my Silverlight formatter uses Strike to show blue text I had to change a style in the containing page – here the code:

Snippet created with CBEnhancer
strike
{
    text-decoration:none;
    color:Blue;
}

That’s it for this part.
In the next part I’ll talk about linq2twitter and how easy it is to use this nice thing.
Then I’ll handle the rest of the infrastructure – WCF and a few other things.
After this the part about the (partial) new telerik Silverlight Controls will be handled.

Stay tuned
Manfred

Tags: ,

telerik | Silverlight

Online games – promotion, social marketing and my “bad hands”

by ManniAT 5. April 2010 19:21

This post is the introduction of a number of blog posts. To make it easier for you to find the parts you are interested in – here are the topics:

Years ago we did a large multiplayer online game for a customer.
It was built with Flash MX, Microsoft IIS 6 and Microsoft SQL Server 2000.

This development was real a pain – the reason – our customer had his “very special” design ideas.
In other words – for him at least 10 different fonts, 20 different colors (magenta also) and a brutal mixture of foreground / background colors was “the state of the art”.

We made some “good old style” proposals – but last not least what we could do was not “impressive”.
We joined the team after two other companies failed – and what we found was a “rough idea”, a flash developer (building those “multicolored” things our customer likes), a professional composer for music, some lawyers, and so forth.

Anyhow – about two months later the “rough idea” turned into a “highly configurable promotion engine” and the flash films handling static content turned into a thing which was controlled  via web services driven by a SQL Server.

That was the time we had to learn flash because it turned out that the flash developer was a “picture drawer” not really able to do action script and handle web service calls.
And after a short time (we also did the flash part at this time) a professional designer joined the team.

Unfortunately Silverlight didn’t exist at this time – and the separation of code / design was really hard.
But we built our own layers and so finally the designer made the film parts – and we revived them.

2006 we have been nominated for “BestPractice-IT” at CeBIT for this software!

This game was a kind of “social marketing toy” – and from it we learned two things:
Game mechanics – how an what people play.
Design is a hard thing Happy

To come to a point – so far we made three iPhone apps which sell… – let’s say they could do better Cool

We decided to do some kind of promotion. After some discussions we decided to build a little game to do this.
And we know – design is not our strength. The goals are:

  • Show a lot of people our software
  • Build the thing in a short time
  • Give the players an even chance to win something
  • Use existing skills / tools

The solution was to do something with twitter. We already have some routines from an earlier project I made.
Messing around with it (we needed to extend it) I stumbled over LinQ2twitter.

I want to thank Joe Mayo for this great piece of software.

Next we decided to use some new (and also “well known”) telerik controls.
Telerik has a new (CTP) control in their Silverlight Controls the RadTransitionControl.

This nice guy compensated some of our “design lacks”. Further we used the RadBook to show the game rules.
And (of course) for infrastructure needs we used the RadGrid for ASP.NET AJAX.

Since the RadTransitionControl is very new (CTP) I will show how to use this thing to achieve great effects without any “designer skills”.

I will divide the things in multiple parts – the first will be about infrastructure and I’ll show how I was able to build a “WYSIWYG” editor for game content.

Stay tuned
Manfred

Tags: , ,

Silverlight | telerik | twitter

Layered UI or how to reuse UIs with MonoTouch and Silverlight

by ManniAT 29. March 2010 12:23

When we started the development of TTMoney one of our main goal was a “UI Designer” which should enable the User to change the look of his UI.
Think of it like “dynamic Themes”. Themes mean – I choose one and my colors, fonts, backgrounds, … change their style.

We wanted to go a step further an let the user compose his UI using a web interface.
Due to our skills we decided that this designer should be built using Microsoft Silverlight.

Since we use MonoTouch for our iPhone applications it is not really hard to share a lot of code.

The only challenge is the UI itself. For the iPhone we use (could use) the interface designer and for Silverlight we got Microsoft Expression Blend.
Sounds good – but it is unfortunately totally different. Not only from “how to use” – the output is the problem.

So one idea was to build a XIB – File parser (XIB files are what the Interface Designer generates) or a XAML (Blend output) file parser.

We decided NOT to build such a thing. Instead we designed our UIs to use a layered design.
This means: we have a “native UI layer” which mimics for an example the differences between a UIImageView (iPhone) and an Image Control (Silverlight).
This layer has to be changed when we transfer an iPhone UI to Silverlight.

Such techniques are well know form DALs (Data Access Layer). Using generics and some abstract methods and extensions it was not really hard to do this.
The only limitation is that MonoTouch has to compile all the .NET code (no Generic Methods and things like this) to native iPhone code.

Anyhow – this was not really a stopper. Especially Generics work very well and the rest is nothing more than to avoid some C# (.NET) elements.

Most of the “basic layer” work by translating controls (UIView becomes a Canvas for an example) and Property setters.
myUIView.AddSubview(ControlX) becomes myCanvase.Children.Add(ControlX).
And instead of setting the Frame (iPhone) we set “CanvasLeft, CanvasTop” and so on.

The abstract methods enable the framework to do enhanced things like animating something or things like this. While I start a storyboard in Silverlight I add a transition or something like this for the iPhone.

Above that layer a set of Generics are implemented. For an example – it’s an often asked question “how to have a background image in a UITableView…”. We have BackGroundViewController<TableViewController> for this.

We build our UIs completely in (reusable) code.
Negative: No rich UI designer.
Positive: It is more or less “platform independent” and it enables the things to be driven by a database.

Last not least Microsoft has Silverlight for Windows Phone 7 – and that means (with very little work) that our application will also run on this platform.

A simple example is this (very basic) Silverlight implementation of the “UI Themer”:
SLDesigner

A note about this “designer” – we’ve used the Telerik Silverlight Controls for it. And that shows how independent you could be if your “UI Layers” are well done.
We could have done the same thing using native Silverlight controls – but why if we have an easy way to use these enhanced Telerik  things.

We made this framework for TTMoney but while building this project we had the need to build another app.
This is Sticker and uses the Framework built for TTMoney.

Which brings me to my answer to Shawn Burke's great Blog Series.

I like what he wrote – except the “code line counting”. I fact most of the code is there to make the things work.
And if I calculate how much money you have left it does not matter if this is Windows Mobile 7 or iPhone code.
Building Sticker was about 200 Lines of UI code – the rest is “business logic”.
And for TTMoney we have ration of about 8.5 BL to 1.5 UI.

Of course – in both cases we have several hundred lines of code for the “UI Framework” – but this is totally reusable and will work in future projects also.

From my point of view the more important thing is how to handle “mobile specific” things in Windows Mobile 7 / iPhone.

Just as an example – Sticker allows you to send your “existing / missing lists”.
In MonoTouch the code looks like this:

Snippet created with CBEnhancer
void m_hbDoSendMail_Click(object sender, EventArgs e) {
        if(MFMailComposeViewController.CanSendMail) {
            MFMailComposeViewController mail = new MFMailComposeViewController();
            mail.SetMessageBody(m_strLastText + m_strStickerLink, true);
            mail.Finished += HandleMailFinished;
            this.PresentModalViewController(mail, true);
        }
    }
    void HandleMailFinished(object sender, MFComposeResultEventArgs e) {
        e.Controller.DismissModalViewControllerAnimated(true);
        if(e.Result == MFMailComposeResult.Sent) {
            Globals.MessageBox("Info", ULocalizer.ULOC["ZS_MailSent"].TheText);
            CloseDialog(false);
        }
        else {
            Globals.MessageBox("Error", ULocalizer.ULOC["ZS_MailSendError"].TheText);
        }
    }

 

I hope Shawn Burke will keep on extending his iPhone SDK vs. Windows Phone 7 Series SDK Challenge.

A last note – of course I’m not comparing with Objective-C – I talk about MonoTouch – but it is an existing technology – so why don’t use it.

Manfred

Tags: , , ,

iPhone | MonoTouch | Silverlight | telerik

Silverlight 3 Local Communication API (addition)

by ManniAT 3. September 2009 10:56
Technorati-Tags: ,

There is a “problem” with the Silverlight Communication (Messaging) API.
It doesn’t provide a way to set the receiver scope to a single browser window.

Since it looks as if the problem is common I extended my sample with a simple solution for this:
A simple solution for the Receiver Scope in the Silverlight 3 Messaging API

Have fun

Manfred

Tags: ,

Silverlight

Silverlight 3 Local Communication API

by ManniAT 2. September 2009 14:56
Technorati-Tags: ,

Since “Silverlight Islands” become more and more common I made a sample which shows how such Islands can exchange data using the Silverlight 3 Local Communication API.

The sample is done in a “step by step manner”. Starting with the very basic layout of the page till extended communication handling you’ll find all the code in the sample.

The sample uses the telerik RadControls for Silverlight 3. The reason? These controls allow me to have some nice looking UI with very little need to style or code something.

You can download these controls (free trial version) from here

If you don’t want to use the telerik controls – no matter, with very little changes the sample works without them.

I also uploaded this sample to the telerik code library (in the Silverlight section).

As soon as it is screened you can download it from there.

Have fun

Manfred

PS: for those which missed the link above – here is the sample

Tags: ,

Silverlight

Powered by BlogEngine.NET 1.5.0.7

RecentPosts