Blog Archives

Generic Bing maps pushpin clustering component for Windows Phone 7

A couple of weeks ago I wrote my own Windows Phone app Lovely Neighbourhood which is showing pushpins on the Bing maps control for Windows Phone 7. Because there where quit some pushpins close to each other I decided to use pushpin clustering (sometimes called marker clustering) to make map in the app look less chaotic than with all the pushpins on the map. (There where a few regions where you couldn’t even see the map anymore.)

After a little search I found a blog post by Colin Eberhardt who has a guide to pushpin clustering in WP7. I started implementing and after a few changes it works fine in my app. But than I saw an app from my colleague which was not using pushpin clustering and also on his map view it was pretty hard to see the map. At that moment I started thinking about rewriting the pushpin clustering code in a generic way, so it would be easy to implement in any app.

In this article I want to show you how to use my pushpin clustering component in your app.

The first step that you need to do is add a reference to the PushPinClusterer.dllin your project.

The next step will be to add the IClusteredGeoObject interface to your entity which has the GeoCoordinate property.

1 public class MyGeoObject : IClusteredGeoObject 2 { 3 public string Name { get; set; } 4 public string Country { get; set; } 5 6 public GeoCoordinate Coordinate { get; set; } 7 8 }

When you implement the interface, you have to implement the Coordinate property which is of type GeoCoordinate. You can just use this property as your location property, or in the getter/setter return/set your own GeoCoordinate property. After implementing the IClusteredGeoObject your entity is ready to be clustered.

The next step will be to setup your xaml so you have a layer where you can add the pushpins and a DataTemplate so you can make a difference between the objects you want to show on the map in case of a clustered pushpin or a normal pushpin.

Below you find the XAML for my Bing maps control with the MapItemsControl where I bind the ObservableCollection<T> from my pushpin clusterer and we reference the “pushpinSelector” datatemplate.

1 <my:Map Height="601" Name="map1" Width="456"> 2 <my:MapItemsControl Name="pushPinModelsLayer" 3 ItemsSource="{Binding PushpinModels}" 4 ItemTemplate="{StaticResource pushpinSelector}" /> 5 </my:Map>

The next step is adding the datatemplate to our resources section like below:

1 <DataTemplate x:Key="pushpinSelector"> 2 <my:Pushpin Location="{Binding Location}" CacheMode="BitmapCache"> 3 <my:Pushpin.Template> 4 <ControlTemplate> 5 <clusterer:PushpinTemplateSelector Content="{Binding}"> 6 <clusterer:PushpinTemplateSelector.ClusterTemplate> 7 <DataTemplate> 8 <Grid VerticalAlignment="Center" HorizontalAlignment="Center"> 9 <Ellipse Fill="Red" Width="40" Height="40" /> 10 <TextBlock Foreground="White" Text="{Binding ClusterCount}" 11 HorizontalAlignment="Center" VerticalAlignment="Center" /> 12 </Grid> 13 </DataTemplate> 14 </clusterer:PushpinTemplateSelector.ClusterTemplate> 15 <clusterer:PushpinTemplateSelector.PushpinTemplate> 16 <DataTemplate> 17 <StackPanel Background="Black"> 18 <TextBlock Text="{Binding CurrentObject.Name}" Foreground="White" /> 19 </StackPanel> 20 </DataTemplate> 21 </clusterer:PushpinTemplateSelector.PushpinTemplate> 22 </clusterer:PushpinTemplateSelector> 23 </ControlTemplate> 24 </my:Pushpin.Template> 25 </my:Pushpin> 26 </DataTemplate>

As you can see in the above xaml markup we have two pushpin templates, one for the clustered pushpins and one for the normal pushpins. The pushpin clusterer is telling you how many pushpins there are clustered by binding the Count property. In the “normal” pushpin you will get your object back from the binding by calling the CurrentObject property. So if you have a property Name on your entity you can bind it here by calling CurrentObject.Name.

The only thing we now have to do is load our data, for example in the OnNavigatedTo event where you can load the list of entities which have IClusteredGeoObject implemented. The following code can be used to start clustering your pushpins.

1 var clusterer = new PushpinClusterer<MyGeoObject>(map1, pins, 50); 2 pushPinModelsLayer.DataContext = clusterer;

When instantiating the PushPinClusterer you give the Type of your entity to the clusterer and as parameters the map you have defined in your xaml, the list of entities and an integer with the distance in pixels in which pushpins have to be clustered.

If you need to know when the clustering is complete you can subscribe to the ClusteringCompleted event, which will fire when it is finished clustering the pushpins.

That’s it, if you start your app now it will start clustering your pushpins.

I have created an example solution with the steps as described above, which you can download from my blog.

Hope this will help you adding pushpin clustering to your app, and I love to hear it from you if used it and in which app. If you have any questions, suggestions or anything else you can contact me on twitter by using @bloodyairtimer or leave a comment on this post.

Happy coding!

Setting the focus to an textbox in the “iteminvoked” event in a WinJS metro app

The last time I focus alot on question regarding Windows 8 metro style development on Stackoverflow because I really like the new WinRT development environment and already have been doing some metro style app developement. A few days ago I saw this question on Stackoverflow and was interested, because it seems pretty simple. The question was that the asker was not able to set the focus to an input textfield.

First I tried it myself just with a little project, click a button and set the focus on the textbox. So far no problems, works like a charm. I send my testproject to the asker and asked him to test this on his machine to check if this works. Now the asker came up with additional requirements. (Just like every project Glimlach ) The focus needs to be set to the textbox when he has clicked a item in a listview. I have updated my project, added a listview with some testdata, attach the “iteminvoked” eventhandler to the listview and within the handler set the focus to the textbox. That’s where the problems start, somehow the focus is not set to the textbox anymore.

I started playing around with adding eventhandlers to the textbox and the listview “focusin” and “focusout” events. I saw that the textbox got focus but lost it when the “blur” event is re-attached to the listview. On MSDN I found the msSetImmediate method which I added to the “iteminvoked” event handler so the focus is set immediate after the processing is completed.

My code for attaching the “iteminvoked” eventhandler looks now like below.

var listView = document.getElementById("basicListView"); listView.winControl.addEventListener("iteminvoked", function (evt) { if (listView.winControl.selection.count() > 0) { msSetImmediate(setFocus); } });

And below the code for the setFocus function.

function setFocus() { //Set focus on input textbox; var input = document.querySelector("#input-box") input.focus(); }

Now when we run the solution and click an item in the listview, the focus is set to the textbox. For me it’s not totally clear why this is needed to make this work, but for now (Windows 8 Consumer Preview) this works.

The entire solution can be downloaded here TestFocusApplication

Happy developing!

Styling your WinJS / HTML5 controls in Windows 8 metro style apps with CSS

Inspired by a question on Stackoverflow on how to change a part of the Range control (which is a new input type control in HTML5) I decided to write this blog post on how to do this. Because it’s pretty easy to do and applies to all other WinJS controls. (At least the technique to find the applied styles and how to override them)

 

HTML5 range control in Windows 8 WinJS metro style app

Example of an HTML5 range control in a WinJS metro style app

Because this is a standard control that can be used there are already styles for created in the “Dark” en “Light” theme. We need to go find these styles to see what’s already applied to this control. As we can see from the example above there are already some color styles applied, blue on the left of the tracker, grey on the right and the tracker itself is white.

Okey, let’s find these styles and change them in the way we like to see this range control.

In our solution explorer under References we have the Microsoft Windows Library for JavaScript SDK where we can find the css folder which contain the ui-dark and ui-light css files. As you can see in below screenshot.

SolutionExplorer

Solution explorer for WinJS metro style application

When we open the ui-dark.css file we need to find the classes that apply for our range control. Luckily these file is well organized and with a small search we find the “Range” control section like below.

1 /* 2 Range control. 3 */ 4 input[type=range] { 5 width: 280px; 6 height: auto; 7 padding: 17px 0 32px 0; 8 } 9 input[type=range]::-ms-track { 10 padding: 0; 11 width: auto; 12 height: 11px; 13 border-style: none; 14 color: transparent; /* ticks hidden by default */ 15 }

I’m only showing part of the classes for this control, because you all will get how it looks like and you now know where to find the rest. You would probably expect that changing one of these properties would give you the desired result of changing the control. That’s only partial true, overriding one of these properties would change the control, but for example not all of the colors can be changed by overriding these classes.

Therefore you need to look further into the ui-dark.css file and look for the “Range control colors” section in the file. And as you can see below we found a complete section with the classes that we can override in our own css file to change the look and feel of our range control.

1 /* 2 Range control colors. 3 */ 4 input[type=range], input[type=range]::-ms-track { 5 background-color: transparent; 6 } 7 8 input[type=range]::-ms-fill-lower { 9 background-color: rgb(0, 130, 135); /* same in dark and light */ 10 } 11 input[type=range]:hover::-ms-fill-lower { 12 background-color: rgb(33, 146, 151); /* same in dark and light */ 13 } 14 input[type=range]:active::-ms-fill-lower { 15 background-color: rgb(37, 187, 196); /* same in dark and light */ 16 } 17 input[type=range]:disabled::-ms-fill-lower { 18 background-color: rgba(255, 255, 255, 0.24); 19 } 20 .win-ui-light input[type=range]:disabled::-ms-fill-lower { 21 background-color: rgba(0, 0, 0, 0.24); 22 }

And just like the other example this are only a subset of the available classes. If you would like to override these values, just copy the classes to your own css file and give them the value/color you like and you will see it being reflected on your control when you run your app.

RangeControlGreen

And as always if you have any questions don’t hesitate to contact me by mail, twitter or leave a comment on this post.

Happy styling…….

Lovely neighbourhood enters the Windows Phone marketplace

This weekend my official first Windows Phone app has been tested and certified for the Windows Phone marketplace. It’s called Lovely neighbourhood and can be downloaded by clicking on the name.

The concept of this app is that everyone knows the feeling that you are walking around somewhere and have the feeling “This is a lovely Neighbourhood”, I would like to live here. Well, with this app it shows you exactly what options you have to buy a house in this neighbourhood. You can filter the results based on price and distance from your location. When it has found the results it will show you them on the map. Based on how many items there are close to each other and your zoomlevel on the map it will cluster the pushpins.

When you tap on one of the house you would like to see it shows you the details about the the selected house. Besides that it will load the photo’s, neighbourhood information (average income, rental versus buying percentage etc) and also it shows which public objects (doctor, hospital, schools etc.) are close to this house so you can decide if this is really your “Lovely neighbourhood”.

Below you will find some screenshots of the app.

Screenshot_1Screenshot_2Screenshot_3Screenshot_4

In addition: This app only works when you’re located in the Netherlands because it will use the Huizenzoeker API to fetch data about the houses for sale.  

I’m open for feature requests, so if you have any good feedback or a feature request don’t hesitate to contact me by email or place a comment on this post.

And last but not least don’t forget to download the app.

WP-Download-English-Med

My TechDaysNL 2012 session is online

Friday 17 February I gave a presentation about Windows 8 ‘metro style’ development with JavaScript on the TechDays 2012 event in Den Hague, The Netherlands.

In this session I have covered the following topics:

  • - Metro design principles
  • - WinRT architecture
  • - WinJS library
  • - Demo’s on how to create your own ‘metro style’ app with Javascript.

Below you will find the recording of the session. Warning for my non-dutch readers: The session is spoken in Dutch.

 

Hope you enjoyed being at the Techdays 2012 and watching my session, or seeing it online on Channel 9.

If you have any questions about the presentation or the content don’t hesistate to contact me via the comments or via twitter @bloodyairtimer

Upgrading your MVC 3 project to the MVC 4 beta

Last week the MVC 4 beta is released with support for a “go-live” license. Which means that it’s in a state where we can build and deploy our applications with this beta.

So I decided to take my ‘old’ MVC 3 project and upgrade it to the MVC 4 beta. First I installed the MVC 4 Beta on my developer machine. (You can download it here) (Please make sure that you have the correct .Net framework version on your machine. During installation your environment will be checked for .Net 4.0 framework and that you don’t have the .Net Framework 4.5 installed)

After the installation I took the steps to upgrade from MVC 3 to MVC 4 Beta which are described in the release notes. You can find these steps  here.

So far so good……

When I tried to run my project, I get exceptions that it’s expecting version 2.0.0.0 for the System.Web.* dll’s. I did a clean solution and a  rebuild. No luck!

Than I remembered that I used the “Add deployable dependencies” feature in Visual Studio to make sure that the correct dll’s are copied when I publish my solution to my hosting provider. (I used this feature because my hosting provider didn’t has MVC 3 installed when I published my website.)

I removed all files from the “_bin_deployableAssemblies” folder in my solution. Than right clicked my webproject, clicked “Add Deployable Dependencies” and re-added the assemblies.

DeployableAssemblies

After re-adding the assemblies I rebuild my solution and started it. Now the errors are gone!

Hope this helps someone having also issues upgrading to MVC 4.

I’m speaking at TechDays 2012

The last few years I have been attending the DevDays (which are now callled TechDays) and always had alot of fun being there with colleagues, catch up with some guys and learning alot of the sessions being held during these days. This year will be totally different, because this year I will be doing a session myself.

I will be speaking about developing Metro style apps in Windows 8 with Javascript. In this session I will guide you through the different steps to build your own ‘metro style’ app. In this session I will cover the following topics:

  • Promisses
  • Dataloading with XHR (asynchronous)
  • Datatemplates
  • Databinding
  • Adding controls to the AppBar
  • Livetiles
  • Navigation

For most of the above points I will also show you in demo’s how to do this by yourself. I’m pretty sure that after this session you will say: “Wow, that’s really easy to start developing ‘Metro style’ apps with Javascript!”.

I really hope to see you on Friday 17 february in Den Hague! More details about my session can be found at the Techdays site

Last thing to say is that I’m really proud to have this opportunity to speak at an event like this size.

See you there!

Creating a dynamic layout with XAML in Windows 8 ‘Metro style’ apps

A big percentage of all apps is showing data to the user, formatted in different ways. Sometimes it are images, the other time graphs, but a lot of times you use a data grid to present your data to the user. To present this data in the most smooth way to the user, you often want to make the columns / rows scalable. With this approach the data is shown in the most comfortable way to the user when they use different devices and resolutions. When using XAML in your Windows 8 metro style app, you can easily define a dynamic layout for your grid by using the ColumnDefinition and/or RowDefinition classes.

Below I will show you the XAML of an dynamic layout grid and will tell you about the used properties and how to add controls to the different positions created in the grid.

1 <Grid x:Name="LayoutRoot" Background="#FF0C0C0C"> 2 <Grid.ColumnDefinitions> 3 <ColumnDefinition Width="Auto" /> 4 <ColumnDefinition Width="*" /> 5 <ColumnDefinition Width="Auto" /> 6 <ColumnDefinition Width="2*" /> 7 </Grid.ColumnDefinitions> 8 </Grid>

As you can see above right now we only use the ColumnDefinitions to define the columns in our grid. You can see this as the skeleton for our grid. Later we will make sure that every columndefinition will have the right controls added to it.

In this article we only focus on the (easy) dynamic part of the layout. In later articles I will talk about a more complex dynamic layout. That’s why we for now will only talk about the Width property. The Width property can be assigned with the following values: Auto, * or a double value.

Auto The size is determined by the size properties of the content object.
* The value is expressed as a weighted proportion of available space.
Double value The value is expressed in pixels.

So if you have a columndefinition with width set to Auto and you add a control to the column that has a width of 100 pixels, than your column will be 100 pixels + a small amount needed for borders etc. You can see Auto as the fit to content option.

* is the option if you want to make sure that your grid is filled up 100%, because this one will fill up the space that is left after all other columndefinitions have taken their space. If you have multiple columns with Width=”*” than the width will be equally divided over the columns. In our example you see that the third column definition has the width set to “2*”. This means that this column will take up twice as much space as the other column. If there is for example 300 pixels left in our grid, than column 1 will get 100 pixels and column 3 will get 200 pixels.

The last option is setting a width to a double value. This value is the exact value in pixels that the column will take.

Adding controls to the grid

Okay, lets add some controls to the grid to see how that works. First I will show you the full example of the dynamic layout grid, further I will explain what’s happening.

1 <Grid x:Name="LayoutRoot" Background="#FF0C0C0C"> 2 <Grid.ColumnDefinitions> 3 <ColumnDefinition Width="Auto" /> 4 <ColumnDefinition Width="*" /> 5 <ColumnDefinition Width="Auto" /> 6 <ColumnDefinition Width="2*" /> 7 </Grid.ColumnDefinitions> 8 <TextBlock Width="Auto" Text="Column 1" Grid.Column="0"></TextBlock> 9 <Button Width="Auto" Content="Column 2" Grid.Column="1"></Button> 10 <TextBlock Width="Auto" Text="Column 3" Grid.Column="2"></TextBlock> 11 <Button Width="Auto" Content="Column 4" Grid.Column="3"></Button> 12 </Grid>

As you can see in the above example we just start adding controls to are grid right after the ColumnDefinitions element. In our example we added two text blocks and two buttons. With the Grid.Column property we can define in which column these controls are added. Adding the controls to the grid can be done in a random order if you want. As you can see the Grid.Column property is a zero-based index.

Below is a screenshot of the dynamic layout that we created with the above XAML code.

DynamicLayout

You can repeat these above steps in the same way for rows. But than in the Grid.RowDefinitions. If you want to add a control to a specific row in your grid you should add the Grid.Row property to your control to define the row where you want your control to appear.

In a later post I will talk about a more complex dynamic layout and how you can measure the width/height of the columns/rows that are created with the * option. Also we will have a look at how work with these kind of layouts from the code behind.

MySQL sessionState provider adding strange ID to MVC3 url

Tonight I was working on an MVC3 project, which uses an MySQL database. For the admin area I’m using the MySQL membership provider to add users and roles. While clicking through the ASP.NET configuration wizard I have enabled all options for the MySQL membership provider.

After I ran the configuration wizard I started my project to check if the users and roles where working. It didn’t. HttpPost actions where not executed, instead the HttpGet action was executed. After a while I found out that there was a strange kind of folder / query string added to my url.

http://localhost/(S(0swhj3f12244dysv5nj445gx))/

I really had no idea where this thing came from. Compared my solution to another solution (I first checked if this solution was still working) and after a while I found out that my other solution was only using a few options of the MySQL membership provider. Than I started removing parts of the membership that I don’t really needed. After removing the sessionState provider the url was working normal again.

See below codeblock that I removed from my solution

1 <sessionState mode="Custom" cookieless="true" regenerateExpiredSessionId="true" customProvider="MySqlSessionStateProvider"> 2 <providers> 3 <add name="MySqlSessionStateProvider" type="MySql.Web.SessionState.MySqlSessionStateStore, MySql.Web, Version=6.4.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" 4 applicationName="my app" description="my app" connectionStringName="MyAppDB" writeExceptionsToEventLog="False" autogenerateschema="True" /> 5 </providers> 6 </sessionState>

Well that’s it. Seems like that MySQL sessionstate and MVC3 are not really working together.

I haven’t checked out why this behavior is occurring or if it’s also happening when using the ‘standard’ sessionstate provider. If you have any ideas please let me know.

“Integrate" Bing Maps directions in your WP7 app

in the upcoming “Mango” update for Windows Phone 7, Microsoft has already released the Windows Phone Developer Tools Beta 2 for this new version which has got version number 7.1.

One of the new cool features which is included in this beta release is the support to use the “Directions” feature in Bing Maps from your app. This feature makes it very easy to make a location aware app and makes it interactive to the user to help him find a specific spot. (Think about an app that helps users find only your restaurants, ATM’s, your company or anything else that has a coordinate)

Please note that I’m trying to keep away from the “integrate” part, cause actually it’s not integrating but more like navigating away from your app to Bing Maps with the location you specified in your app.

Okay, bring on this new feature and show us how to do this.

First, let’s start with the introduction of this feature/class/task or how you want to call it. We are talking about the BingMapsDirectionsTask which is a very simple class that lives in the Microsoft.Phone.Tasks namespace. You can use this task to create a route on Bing Maps from your app. In short terms this class has three important objects (2 properties / 1 method). It has a Start and an End property, and a method Show() which is it.

Both properties are of type LabeledMapLocation, which have a constructor that expected a string for the name and GeoCoordinate for the location.

In general below code will be enough to create a route on the Bing Maps app:

1 BingMapsDirectionsTask directionTask = new BingMapsDirectionsTask(); 2 directionTask.Start = new LabeledMapLocation("Start", new GeoCoordinate(52.512794, 6.091539)); 3 directionTask.End = new LabeledMapLocation("End", new GeoCoordinate(52.512794, 6.091539)); 4 5 directionTask.Show();

Just three lines of code. Can it be easier?

Yes it can!

If you don’t assign a value to the start property than it will automatically take your location and calculate a route to your End location.

I have created a sample solution where you can use the locations from the emulator to specify a start location and when you click on the map it will take your position (which is set by the emulator) and calculate a route to the location you have clicked.

BingMapsLocationChooser

Choose a location by using the Additional tools.

BingMapsDirections

And there it is our own created direction in the Bing Maps app.

To be honest I’m a bit in doubt about what I think about this feature. On one side it’s a very handy, easily to implement feature that will give you navigation/routing to your location in minutes.

Another thought I still have is I’m adding a map control to my app, a user clicks around and if it needs to calculate a route it exits my app, and starts Bing Maps. No real integration.

Anyone having some thoughts about it?

Download: