Deprecated: Function set_magic_quotes_runtime() is deprecated in /home2/creabros/public_html/creabros.fi/textpattern/lib/txplib_db.php on line 14
CreaBros Oy: Window Phone Coding

Window Phone Coding

Oct 11, 03:22 AM

I’ve been coding using Cordova to create a cross platform app for ordering Taxis. I’m currently porting to WP7. This was the first time I coded for Microsofts Silverlight. It is funny how difficult simple tasks can become when you don’t know your way around the basics.

Problem was rather simple. Two classes the MainPage and a custom Plugin needed to communicate. Reason for this was that I had to add a native map and native buttons, because my Openlayer based solution didn’t give a nice user experience.

Adding the map and buttons to xaml file were easy, but how can I communicate with the map and buttons from my plugin? As an after thought it was quite easy, but it took a long time to figure it out.

So two classes MainPage and MyPlugin. MainPage had three buttons, which raised click events. These events needed to be relayed to the Javascript functions. Javascript needed to attach buttons to specific functions after it loaded.

It turned out that nothing needed to be done for the MainPage, but it took some figuring out.

Implementation

Steps were:

  1. find control from the xaml.
  2. manipulate or attach event handler to the control
  3. listen to events from control

First problem how to find the control? After many tries and reading documentation it become obvious that the way to go was to access the App instance and work my way current ApplicationPage. Then use FindName to find the control I wanted to manipulate or listen. Easy enough.

var mypage = App.Current.RootVisual.Content; – wrong
var button = mypage.FindName("mybutton") as System.Windows.Controls.Button; – ok

problems

  1. App is not defined – fix: namespace of the App needed to be used
  2. Need to do some casting to get my page
  3. At run time I get exeption, because UI is in different thread than the Plugin

fixes

so to get mypage
var mypage = ((PhoneApplicationFrame)MyApp.App.Current.RootVisual).Content as MyApp.MainPage;

next line:
var button = mypage.FindName("mybutton") as System.Windows.Controls.Button;

is ok. But there is a big problem. At run time there is the exception mentioned earlier. We can’t call the methods on MainPage directly. To by pass this we need to use Dispatcher, which will invoke the call in the correct thread.

Call becomes
Deployment.Current.Dispatcher.BeginInvoke(() => {
var mypage = ((PhoneApplicationFrame)MyApp.App.Current.RootVisual).Content as MyApp.MainPage;
var button = mypage.FindName("mybutton") as System.Windows.Controls.Button;
button.Click += new RoutedEventHandler(this.fireEvent);
});

or we can use a delegate

add a member to our plugin

public delegate void ButtonEventDelegate(string str);

Now it is possible do the previous bit more neatly

Deployment.Current.Dispatcher.BeginInvoke(new ButtonEventDelegate(HandleButtonClick), argument_array);

HandleButtonClick is simple function that executes same stuff that is inside brackets in the first BeginInvoke command.

fireEvent function needs to be something like this
public void fireEvent(object sender, EventArgs e)
{
var button = sender as System.Windows.Controls.Button;
// sending message to Cordova i.e. Javascript
string[] strs = new string[1];
strs[0] = button.Name;
var args = new ScriptCallback("testFunction",strs);
InvokeCustomScript(args)
}

And that is pretty much all there is to it.

Kalle Kuismanen

Mobile, Random

---

Comment

Commenting is closed for this article.

---