Vem är Johan Lindfors

Jag jobbar som teknisk chef på Microsoft i Sverige och ansvarar för vår tekniska evangelisering mot utvecklare. I den här bloggen har jag för avsikt att skriva om utveckling i allmänhet och på Microsofts plattform i synnerhet.

Är du intresserad av en XNA användargrupp?



Visa resultat!

Get Microsoft Silverlight

Hantera synlighet av element baserat på orientering

En dialog som nyss dök upp i en diskussionslista var angående hur det går att agera på förändring i orientering av enheten som då kan uppdatera gränssnittet. Med Windows Phone 7 och Silverlight så kan du markera dina sidor i en applikation till att ha stöd för både Portrait (stående) och Landscape (liggande) eller bara en av dem om så önskas. Med hjälp av de inbyggda panelerna så kommer sedan elementen i din applikation att automatiskt ställa in sig till skärmens orientering, mycket smidigt, men det finns begränsningar.

Exempelvis kalkylatorn i Windows Phone 7, har liksom kalkylatorer i andra plattformar, mer knappar synliga vid liggande orientering än vid stående. Men hur kan vi i våra applikationer förändra ett elements synlighet baserat på orientering?

Databinding och “value-converters” till räddningen.

Genom att helt enkelt databinda det element som vi vill ska kunna synas eller inte, specifikt egenskapen Visibility, till egenskapen på sidan som heter Orientation. Dessvärre så har dessa egenskaper olika typer och det är där en konverterare kommer till sin rätt. Följande kod skapar en en-vägs-konverterare (i och med att jag inte implementerar ConvertBack metoden) som hanterar konverteringen:

public class LandscapeVisibilityConverter : IValueConverter
{
    public object Convert(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        var orientation = (PageOrientation)value;
        Visibility visibility = Visibility.Collapsed;
        switch (orientation)
        {
            case PageOrientation.Landscape:
            case PageOrientation.LandscapeLeft:
            case PageOrientation.LandscapeRight:
                visibility = Visibility.Visible;
                break;
            default:
                break;
        }
        return visibility;
    }

    public object ConvertBack(
        object value, 
        Type targetType, 
        object parameter, 
        CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Hoppas att du får användning av den! Det är precis lika enkelt att skapa en PortraitVisibilityConverter, men det fixar du själv va, eller hur Smile

Postades 16. juni 2010 23:08 av Johan Lindfors

Optimera prestanda i Silverlight-applikationer för WP7

När du börjar utveckla applikationer för Windows Phone 7 med Silverlight så är det naturligtvis viktigt att kontinuerligt ha koll på systemresurser och optimera applikationens olika delar som exempelvis animationer. Allt för att få till en så bra upplevelse som möjligt för användaren.

Då kan det vara bra att slå på följande egenskap:

Application.Current.Host.Settings.EnableFrameRateCounter = true;

UPPDATERING:

I applikationer som väljer att visa SystemTray (som visar batteri osv) så kommer räknarna att hamna bakom denna, det betyder att för att vara säker på att se räknarna så är följande kodrader att föredra:

this.SetValue(Microsoft.Phone.Shell.SystemTray.IsVisibleProperty, false);
Application.Current.Host.Settings.EnableFrameRateCounter = true;

Då kommer du att få fem stycken räknare högst upp i vänsta hörnet som ger följande information:

  1. imageRender thread frame rate
  2. UI thread frame rate
  3. Vram used
  4. # textures used
  5. # intermediate textures used

Mer information om detta kan du få här: http://live.visitmix.com/MIX10/Sessions/CL60

Postades 11. juni 2010 17:35 av Johan Lindfors

MSDN TV Live – Silverlight och Windows Phone 7

I den här MSDN TV Live-sändningen kommer jag (Johan) att visa hur Silverlight kan användas i och med Windows Phone 7! Jag kommer att visa både Visual Studio 2010 och Expression Blend samt demonstrera en del av de koncept och exempelapplikationer som redan har byggts och publicerats på exempelvis CodePlex. Vi kommer bland annat att titta på navigering, kontroller, MVVM, animationer och teman.

Men den här presentationen kommer bara att bli en kortare introduktion till det som kommer att gås igenom under Developer Hub evenemanget den 9:e i Stockholm, det får du inte missa!

Datum Fredagen den 4:e juni
Tid 12:00-13:00
Plats Klicka här för att ta del av sändningen!

OBS: Webbsändningen använder Office Live Meeting och kommer att innehålla presentation, demonstration och ljud (via datorn). Innan du går med i webbsändningen så behöver du installera Office Live Meeting-klienten!

Windows Phone 7 Developer Hub den 9:e juni!

Nu har det äntligen blivit dags för den första utvecklardagen som helt fokuserar på Windows Phone 7. Till min stora glädje så har vi lyckats få hit två internationella talare som bidrar med ytterligare djup och förståelse för plattformen, Ben Riga och Neil Hutson!

image003 Under dagen kommer vi att titta på både Silverlight och XNA som tekniker för applikationer på Windows Phone 7. Vi kommer också att titta ytterligare på vilka typer av applikationer som redan har börjat skapas samt hur Metro, det nya designspråket för Windows Phone 7, kan användas för att göra eleganta och effektiva applikationer som följer mönster och rekommendationer för plattformen.

Mellan 09.00 och 16.30 håller vi på den 9:e juni på Hotell Clarion Sign i centrala Stockholm. Anmälan kan göras redan idag! Vi bjuder på både lunch och fika under dagen!

Jag hoppas kunna publicera en detaljerad agenda inom kort, men det kommer bli mängder av teknik, massvis med demos och riktiga telefoner på scenen, säkerligen lite klämma och känna möjligheter också!

Här följer agendan för dagen:

Titel Längd
Introduction to Windows Phone 7 45 minuter
Lap around tools 15 minuter
Building Silverlight Applications for Windows Phone 90 minuter
Hardware Access (camera, accelerometer, touch, etc. ) 60 minuter
Building Windows Phone games with XNA 60 minuter
Efficient Design 75 minuter
Market Place 30 minuter

Vi hoppas fortfarande på att ha några fysiska enheter på plats för dig som deltagare att klämma och känna på, inget går väl upp mot “the real thing”. I värsta fall får jag bygga några själv enligt den här beskrivningen Smile

Ben Riga
Ben RigaBen Riga is Senior Technical Evangelist for Windows Phone 7 in Microsoft's Developer and Platform Evangelism  (DPE) group.  His responsibilities include demonstrating the compelling business value of the Windows Phone platform and how it extends the Microsoft stack to the device to help customers and ISVs to more quickly deliver mobile applications.  Ben supports the Microsoft field by engaging in key projects, recruiting target customers/partners, engaging customers and partners with feedback and managing the all-up engagement pipeline.

Neil Hutson
Neil Hutson Neil Hutson is the Senior Director of Technical Evangelism at Microsoft Corp.  In this role he is responsible for exciting developers about Microsoft’s emerging platform technologies and tools and leading key activities for Microsoft’s Premier PDC and MIX events. Over the past year the group has been focused on a number of major launches such as Windows Azure, Windows 7, Sharepoint and Visual Studio 2010. With the developer announcement of Windows Phone 7 at MIX10, Neil would like to share his knowledge of the platform here in Sweden. Prior to his current role, Neil was Director of Technical Evangelism for Windows Server, Microsoft Corp and also Chief Architect for .NET, Microsoft Europe, Middle East and Africa.

Jag kommer inte heller att kunna hålla mig från scenen, vad hade du väntat dig? :)

Anmäl dig idag!!!

Postades 19. maj 2010 20:33 av Johan Lindfors

MSDN TV Live – Nyheterna i Silverlight 4 nu på Channel9

Fredagen den 14:e maj höll Danwei Tran en presentation om nyheterna i Silverlight 4 som nu går att se på Channel9. Det kom tre frågor efter presentationen som jag här vill ge lite svar på:

Fråga: Hur ser det ut för Silverlight på andra plattformar?
Svar: Silverlight utvecklas av Microsoft för Windows (både PC och Windows Phone 7), Mac OSX och även för Symbian. Novell håller sedan på i och med Moonlight projektet att göra tekniken tillgänglig även på Linux.

Fråga: Finns Expression Blend med i MSDN prenumerationer?
Svar: Jajamensan, i prenumerationern med MSDN Premium eller högre så finns Expression Studio med och där ingår Expression Blend.

Fråga: Kan olika Silverlight applikationer i samma webbsida kommunciera med varandra?
Svar: Japp, tekniken som används är så kallade Senders och Recievers. Det finns en bra artikel på MSDN och jag har laddat upp ett kodexempel som använder VS2010 om du vill testa på tekniken själv.

Nästa vecka kommer Dag König att gå igenom CodeContracts i och med .NET Framework 4.0!

Postades 14. maj 2010 22:50 av Johan Lindfors

MSDN TV Live – Nyheter i Silverlight 4.0

Silverlight har redan hunnit upp till version 4.0 och nu har det blivit dags för Danwei att via MSDN TV Live presentera några av nyheterna.

Datum Fredagen den 14:e maj
Tid 12:00-13:00
Plats Klicka här för att ta del av sändningen!

OBS: Webbsändningen använder Office Live Meeting och kommer att innehålla presentation, demonstration och ljud (via datorn). Innan du går med i webbsändningen så behöver du installera Office Live Meeting-klienten!

Postades 13. maj 2010 19:05 av Johan Lindfors

MSDN TV Live – Metro, Designspråket för Windows Phone 7

I och med Windows Phone 7 introduceras ett helt nytt och fräscht användargränssnitt som har hämtat inspiration från bland annat Media Center, Zune och en hel del andra källor. I den här presentationen kommer jag att gå igenom Metro, bakgrunden, visionen och hur du som utvecklare och designer bör dra nytta av rekommendationer och riktlinjer för att skapa applikationer som smakar och ser ut som Windows Phone 7 applikationer.

Datum Fredagen den 7:e maj20100507T120000+0200
Tid 12:00-13:0020100507T130000+0200
Plats Klicka här för att ta del av sändningen!

OBS: Webbsändningen använder Office Live Meeting och kommer att innehålla presentation, demonstration och ljud (via datorn). Innan du går med i webbsändningen så behöver du installera Office Live Meeting-klienten!

MSDN TV Live: Introduktion till Windows Phone 7

Windows Phone 7 annonserades på Mix10 och intresset är rekordstort. Om du ännu inte har hunnit titta på vad som presenterats eller vill ha en uppdatering av läget så vill jag be dig delta i den här webbsändningen. Jag kommer att berätta om hur Silverlight och XNA erbjuder den nya utvecklingsplattformen och hur du redan idag kan börja testa dina applikationer med hjälp av utvecklingsverktygen som är gratis att ladda hem (och kommer att fortsätta att vara så).

Om du har frågor redan nu som du vill ha besvarade under webbsändningen, skicka dem till mig via bloggen!

Datum Fredagen den 23:e april
Tid 12:00 – 13:00
Plats Klicka här för att ta del av sändningen!

OBS: Webbsändningen använder Office Live Meeting och kommer att innehålla presentation, demonstration och ljud (via datorn). Innan du går med i webbsändningen så behöver du installera Office Live Meeting-klienten!

Från noll till koll: Webbutveckling

OBS Uppdaterade datum för Umeå och Göteborg! Bland annat baserat på den senaste veckans händelser på Island så har vi blivit ombedda att flytta Umeå och Göteborg till senare datum. Jag vill med det varmaste be om ursäkt till de som redan har anmält sig och hoppas att det finns möjlighet att delta vid de nya datumen istället. Anmälningslänkarna ska fungera under dagen!

Med de senaste årens otroliga utveckling av tekniker, ramverk och verktyg så kan det vara svårt att hålla sig kontinuerligt uppdaterad. Under en femstäders roadshow kommer vi under några eftermiddagar låta några av Sveriges vassaste webbutvecklare dela med sig av sina kunskaper och rekommendationer för hur du kan använda Microsofts plattform i dina applikationer och lösningar. Vi kommer att titta på ASP.NET, HTML5, CSS, AJAX, jQuery, Silverlight och naturligtvis Expression och Visual Studio. Målsättningen är att du ska kunna gå hem, ivrig att själv komma igång med att utveckla kreativa, kraftfulla och interaktiva webblösningar, redo för morgondagen redan idag!

Datum och orter för roadshowen:

Datum Ort Plats
26 april 19:e maj Umeå SF Filmstaden
28 april 25:e maj Göteborg Folkets Hus Draken
5 maj Sundsvall Fokets Hus
10 maj Malmö SF Filmstaden
17 maj Stockholm SF Skandia Bio

Agendan ser ut som följer:

13.00 – 13.15

Introduktion till webbutveckling
Hur kommer vi igång, vilka är verktygen, teknikerna och programmen som är relevanta?

13.15 – 14.00 Från noll till koll på 90 minuter (pass 1)
File | New och så börjar vi göra en applikation samtidigt som vi diskuterar olika aspekter under utvecklingen. Skillnader mellan WebForms och MVC, standards (HTML5) och CSS, debuggning och rekommendationer.
14.30 – 15.15

Från noll till koll på 90 minuter (pass 2)
Fortsätter på ovanstående...

15.30 – 16.30 Rikare upplevelser med Silverlight 4
Med Silverlight erbjuds ytterligare rika upplevelser både på webben, pc’n och i telefonen. Fokus på färg och form, design.

Missa inte heller att vi under roadshowens förmiddagar även håller presentationer i SharePoint 2010!

Building a Northwind browser with oData and WP7

In this article I’ll go through the steps to develop a Windows Phone 7 Series application with Silverlight to browser the Northwind-database exposed through oData at http://services.odata.org/Northwind/Northwind.svc/. The end result will be an application with three pages that allow the user to browse the categories, products and product-details of the database. The following screenshots demonstrates the end result:

northwind_categoriesnorthwind_beveragesnorthwind_chai

If you’d like to skip the article and simply try out the application directly, please download the code here!

imageThe easiest way to get started is to create a new application with Visual Studio 2010 RC (either Express or higher, I’m using Express) and leverage the “Windows Phone List Application”-template which will help with the foundation for the application, choose an appropriate name and let’s go... When the solution have been created we can start by removing stuff we won’t be needing (or actually, stuff we’ll be adding ourselves later on). I will not be using the ViewModel, instead I’ll be leveraging a catalog that I’ll bind UI-elements to, this means we can remove the ViewModels-folder. I also remove the file MainViewModelSampleData.xaml since I’ll be adding custom sample data for the catalog recently mentioned. We should also add a reference to System.Service.Data.Client.dll which if you don’t already have installed can be found here! The image to the right shows the solution explorer with all folders and files expanded when all actions above have been taken.

The first thing we will do is to create the data-types required to communicate with the oData service that exposes the Northwind database. It can be done by opening a command-shell and browse to the following directory or the system-root:

c:\Windows\Microsoft.NET\Framework\v4.0.30128

And in that directory you enter the following command:

DataSvcUtil /uri:http://services.odata.org/Northwind/Northwind.svc/
/DataServiceCollection /Version:2.0 /out:C:\temp\NorthwindClientTypes.cs

I won’t discuss the different parameters here instead, other than the /out: parameter which lets you specify where you want the client-library to be generated. You should feel free to provide your own location and filename, as long as you remember where you generate the content. Then we can include this file in the solution created, I choose to add a folder to the solution which I call Northwind and then add the generated file there. If you try to compile the solution at this time you will most likely get an error complaining about the earlier removed MainViewModel, simply comment out that line of code and recompile. Everything should work just fine, but now you will also notice that the MainPage.xaml file in the visual editor doesn’t display that nice sample data earlier provided, lets fix that for the joy of visual experience while developing.

First we need to create the Northwind-catalog though. This is the component that we will use to fetch the appropriate data from the service, and also expose properties that the differenty UI-elements in our application can databind to. Add a class to the Northwind-folder and call it NorthwindCatalog.cs. I will also choose to change the namespace of this file to be the same as the earlier generated client-types, namely NorthwindModel. I’ve also made it a best practise for myself to leverage interfaces as much as possible while creating data-access layers which we can consider this to be, hence I create the following interface in the NorthwindModel namespace in the NorthwindCatalog.cs file:

public interface ICatalog
{
    DataServiceCollection<Product> Products { get; }
    void GetProductsByCategoryID(string id);

    DataServiceCollection<Category> Categories { get; }
    void GetCategories();
}

You will need to add a using-statement to System.Data.Services.Client above but thankfully Visual Studio gladly helps with such actions. Next we implement this interface in our actual NorthwindCatalog by simply inheriting from the ICatalog interface and let Visual Studio once again perform it’s magic, simply by hitting CTRL+. (period). We should now have the following implementation below the interface-definition:

public class NorthwindCatalog : ICatalog 
{ 
    public DataServiceCollection<Product> Products 
    { 
        get { throw new NotImplementedException(); } 
    } 

    public void GetProductsByCategoryID(string id) 
    { 
        throw new NotImplementedException(); 
    } 

    public DataServiceCollection<Category> Categories 
    { 
        get { throw new NotImplementedException(); } 
    } 

    public void GetCategories() 
    { 
        throw new NotImplementedException(); 
    } 
}

Before we move away from this file we need to add the basic features of the catalog and that is storing the actual Product and Category-collections. We add the following members to the NorthwindCatalog:

NorthwindEntities _context = null; 
DataServiceCollection<Category> _categories; 
DataServiceCollection<Product> _products;

Let’s also add a constructor, simply by typing ctor and hitting Enter within the NorthwindCatalog class. Populate the constructor with the instanciation of the _context and DataServiceCollections as below:

_context = new NorthwindEntities( 
           new Uri("http://services.odata.org/Northwind/Northwind.svc/")); 
_categories = new DataServiceCollection<Category>(_context); 
_products = new DataServiceCollection<Product>(_context);

The last thing we do is to make sure the Products and Categories properties return the correct collections:

public DataServiceCollection<Product> Products { 
    get { return _products; } 
}

public DataServiceCollection<Category> Categories 
{ 
    get { return _categories; } 
}

Now we’re done so far with the catalog, we do need to make the implementations of the actual fetching of data from the services, but that will be at a later stage. Instead we will move to fix the sample-data feature that I feel is so appealing to the entire development experience.

Add a text file to the SampleData-folder, call it NorthwindCatalogSampleData.xaml. Visual Studio will complain that there’s no root-element in the xaml-file, that’s easily fixed, paste the code below to get you started:

<northwind:NorthwindCatalog
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:northwind="clr-namespace:NorthwindModel"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <northwind:NorthwindCatalog.Categories>

    </northwind:NorthwindCatalog.Categories>

    <northwind:NorthwindCatalog.Products>
  
    </northwind:NorthwindCatalog.Products>

</northwind:NorthwindCatalog>

What we’re simply doing is creating an instance of the NorthwindCatalog and making sure that we also can use the northwind-namespace by referencing it with xmlns:northwind=... This namespace should be NorthwindModel if you have chosen the same name as I’ve had earlier.

Now let’s create some instances of the Category-class. You could either use the intellisense feature in Visual Studio and manually add a couple of your own categories with the appropriate properties. The properties that are important to this application is: CategoryID, CategoryName and Description. The Picture property could also create a more visually appealing UI, but Northwind stores the data for Pictures of the different categories in a binary format and that would require us to create a ValueConverter to easily bind the data, that’s out of this articles scope.

Add at least one category before you continue, here is one that you can use:

<northwind:Category
    CategoryID="1"
    CategoryName="Beverages"
    Description="Soft drinks, coffees, teas, beers, and ales"/>

Now let’s hook up the UI-elements to databind to this catalog and the Categories-collection.

Open the MainPage.xaml once again. You should already have a pretty visual guidance where your first action should take place, change the d:DataContext attribute in the root-element to be:

d:DataContext="{d:DesignData SampleData/NorthwindCatalogSampleData.xaml}"

But we still doesn’t see anything in the list, don’t worry, we have some more changes to make first. In the XAML-document you should be able to find the ListBox element with the x:Name=”ListBoxOne”. Make sure that the attribute ItemsSource is wired up to the Categories collection:

<ListBox x:Name="ListBoxOne" ItemsSource="{Binding Items}"...

Now you possibly will notice that at least one icon have appeared in the list, we must be doing something right. Shift your focus to the <mpc:ListViewItem element and wire upp the binding for the attributes Text and Details as below:

<mpc:ListViewItem 
    Text="{Binding CategoryName}" 
    Details="{Binding Description}"
    ...

Voila, you now have a visual represenation of your sample data, and also knows that the data-binding works as expected. The “only” thing we now have to make sure of in the application in runtime is to hook up the DataContext of the page to the actual representation of the data provided by the service. Let’s do that by first opening up the code-behind file for MainPage.xaml, quick way: Hit F7 when examining the XAML-file and Visual Studio will directly take you to the correct file, I love shortcuts, don’t you?

In the constructor, beneath the comment // Set the data context... add the following code which will instanciate the NorthwindCatalog, call the GetCategories method and make sure the catalog is being used as DataContext for the page.

var catalog = new NorthwindCatalog(); 
catalog.GetCategories();
DataContext = catalog;

Don’t forget to right-click the NorthwindCatalog() and hit CTRL+. (period) to include the using-statement to the NorthwindModel namespace.

Now we also will have to fix the NorthwindCatalog, so let’s open up that file again and focus on the GetCategories() method. The two lines of code that need to go here is the following:

public void GetCategories() 
{ 
    _categories.Clear(); 
    _categories.LoadAsync(_context.Categories); 
}

We first clear the current collection and then asynchrously load the categories from the oData-service. Let’s try it out, by hitting F5 and if everything compiles and launches correctly you should have the something very similar to the UI provided at the top for the MainPage UI with the actual categories displayed. We should also make sure the top-elements of the page are similar, therefore close the application and open up the App.xaml file, yes that’s right, we’re going to create an application-wide resource for our application name. Directly beneath the <Application.Resources>-tag add the following line:

<system:String x:Key="ApplicationName">Northwind oData</system:String>

Then open up the MainPage.xaml once again and mark the topmost textbox, open up the Properties Windows and click the small icon next to the Text property, this will open up a context menu that you simply choose Apply Resource and the select the ApplicationName resource in the next window. Finally also change the next textbox (currently with the text “list name”) to instead contain the local value “categories”.

There you go, you now have a first page that displays data from the Northwind database exposed with an oData service. Now we could easily go to the DetailsPage, but we want that page to display details for individual products and not categories. That’s why we now need another list-page and we could easily copy the MainPage.xaml file and paste it again in the products as ProductsPage.xaml, please do that and rename the file accordingly! You also need to apply the new name ProductsPage to three more positions in the copied files. Open up the ProductsPage.xaml and rename the x:Class attribute to be ProductsPage instead of MainPage. Then open up the ProductsPage.xaml.cs file and change the class name and the constructor to ProductsPage.

This page will be navigated to from the MainPage, when the user selects a category in the listbox, but first lets hook up the databinding as previous. Start by changing the ItemsSource binding in the ListBox (ListBoxOne) to instead of Categories use Products. The ListViewItem should then have the following attributes:

Layout="Custom"
Text="{Binding ProductName}"

We still don’t see any items in the list though, but that’s because we haven’t added any sample products to the sample data file, let’s add at least one to the file NorthwindCatalogSampleData.xaml in the <northwind:NorthwindCatalog.Products> element...

<northwind:Product 
    ProductID="1"
    ProductName="Chai"
    SupplierID="1"
    CategoryID="1"
    QuantityPerUnit="10 boxes x 20 bags"
    UnitPrice="18.0000"
    UnitsInStock="39"
    UnitsOnOrder="0"
    ReorderLevel="10"
    Discontinued="True"/>

Ok, so now the databinding appears to be working, when I go back to ProductsPage.xaml I can at least see one products, if you added more, they will appear as well. Now we have to fetch the actual Products for the Category selected in the MainPage. Lets begin with passing the categoryId (and alos the categoryName) from the MainPage to ProductsPage. Back to MainPage.xaml.cs. Change the PageTransitionList_Completed to the following:

private void PageTransitionList_Completed(object sender, EventArgs e)
{
    var category = ListBoxOne.SelectedItem as Category;
    NavigationService.Navigate(new Uri(
        String.Format("/ProductsPage.xaml?categoryId={0}&categoryName={1}", 
        category.CategoryID, category.CategoryName), 
        UriKind.Relative));
}

What we’re doing is making sure that when we have transition-animation is completed we get the selected Category from the listbox and pass it’s CategoryID and CategoryName properties to the ProductsPage.xaml page. Now onto the ProductsPage.xaml.cs file. Begin by creating a member of ICatalog in the class:

ICatalog _catalog = null;

Now in the constructor we create an instance of the NorthwindCatalog:

_catalog = new NorthwindCatalog();

But there’s no use fetching any products yet since we don’t have acccess to the parameters yet, instead we need to override another method as follows:

protected override void OnNavigatedTo(
    Microsoft.Phone.Navigation.PhoneNavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    string categoryId = "";
    string categoryName = "";
    
    if (NavigationContext.QueryString.TryGetValue("categoryName",
        out categoryName))
    {
        textBlockListTitle.Text = categoryName.ToLower();
    }

    if (NavigationContext.QueryString.TryGetValue("categoryId", 
        out categoryId))
    {
        catalog.GetProductsByCategoryID(categoryId);
        DataContext = catalog;
    }
}

The code above makes sure we grasp the parameters provided by the querystring to our page, and sets the title of the page to the category-name. It also calls the GetProductsByCategoryID on the catalog with the appropriate id passed to it, after that we connect the DataContext to the catalog. So how do we implement the function to fetch the products from the service? Over to the NorthwindCatalog.cs again. Implement the GetProductsByCategoryID as follows:

public void GetProductsByCategoryID(string id)
{
    try
    {
        //_categoryId = id;
        _products.Clear();
        Uri uri = new Uri(
            String.Format("{1}/Categories({0})/Products", 
            id, 
            _context.BaseUri.OriginalString));
        _context.BeginExecute<Product>(uri, QueryCallback, null);
    }
    catch (Exception ex)
    {
        MessageBox.Show("The query could not be completed:\n" 
            + ex.ToString());
    }
}

I’ve included some error-handling above cause I did have some issues when trying to get this code to work, naturally it’s also good practice to handle error as efficient as possible. We do need on more method though, since we are using the asynchronus method BeginExecute to fetch the products for the appropriate category. The following is the code for the QueryCallback method:

private void QueryCallback(IAsyncResult asyncResult)
{
    Deployment.Current.Dispatcher.BeginInvoke(
        () => {
            try
            {
                IEnumerable<Product> results = 
                    _context.EndExecute<Product>(asyncResult)
                    .ToList() as IEnumerable<Product>;
                Products.Clear();
                Products.Load(results);
            }
            catch (Exception ex)
            {
                MessageBox.Show("The query could not be completed:\n" 
                    + ex.ToString());
            }
        }
    );
}

If you try to compile now you will get some possibly strange compilation errors, these are easily fixed by making sure you have these two using-statements added:

using System.Collections.Generic;
using System.Linq;

Running the application now should give you the opportunity to browse both categories and products from the service, try navigating back and try different categories, pretty neat. What’s noticeable (or not) is that we don’t have any animation when going back to the MainPage. I’ll leave that as an exercise for later. Now onto the last page, the actual DetailsPage. Let’s open that up and begin with some sample-data. Make sure you’re using the NorthwindCatalogSampleData as the d:DataContext on the page’s root-element. Then update the Grid-element named “LayoutRoot” to have the following dataContext attribute:

d:DataContext=”{Binding Products[0]}”

Then we update the TitleGrid’s textboxes to the following:

<TextBlock Text="{StaticResource ApplicationName}"...

<TextBlock Text="{Binding ProductName}"...

This should cause the title of the page to be the name of the first product in the sample-data added earlier. Then it’s a simple exercise of providing the UI of the rest of the properties. Here’s is my resulting ContentGrid:

<Grid x:Name="ContentGrid" Grid.Row="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="60"/>
        <RowDefinition Height="60"/>
        <RowDefinition Height="60"/>
        <RowDefinition Height="60"/>
        <RowDefinition Height="60"/>
        <RowDefinition Height="60"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.Projection>
        <PlaneProjection/>
    </Grid.Projection>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="165"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBlock TextWrapping="Wrap" Text="unit price" VerticalAlignment="Center"
               Margin="5,0,0,0" Style="{StaticResource PhoneTextSmallStyle}"/>
    <TextBlock Text="{Binding UnitPrice}" VerticalAlignment="Center"
               Style="{StaticResource PhoneTextBodyTextStyle}" Grid.Column="1"
               Margin="23,0,0,0" HorizontalAlignment="Left"/>

    <TextBlock TextWrapping="Wrap" Text="units in stock" Margin="5,12,0,13"
               Style="{StaticResource PhoneTextSmallStyle}" Grid.Row="1"
               d:LayoutOverrides="Height"/>
    <TextBlock Text="{Binding UnitsInStock}" HorizontalAlignment="Left"
               Style="{StaticResource PhoneTextBodyTextStyle}" Grid.Column="1"
               Margin="23,8,0,10"  Grid.Row="1" d:LayoutOverrides="Height"/>

    <TextBlock TextWrapping="Wrap" Text="quantity per unit" Margin="5,12,0,13"
               Style="{StaticResource PhoneTextSmallStyle}" Grid.Row="2"
               d:LayoutOverrides="Height"/>
    <TextBlock Text="{Binding QuantityPerUnit}" HorizontalAlignment="Left"
               Style="{StaticResource PhoneTextBodyTextStyle}" Grid.Column="1"
               Margin="23,8,0,10"  Grid.Row="2" d:LayoutOverrides="Height"/>

    <TextBlock TextWrapping="Wrap" Text="reorder level" Margin="5,12,0,13"
               Style="{StaticResource PhoneTextSmallStyle}" Grid.Row="3"
               d:LayoutOverrides="Height"/>
    <TextBlock Text="{Binding ReorderLevel}" HorizontalAlignment="Left"
               Style="{StaticResource PhoneTextBodyTextStyle}" Grid.Column="1"
               Margin="23,8,0,10"  Grid.Row="3" d:LayoutOverrides="Height"/>

    <TextBlock TextWrapping="Wrap" Text="units on order" Margin="5,12,0,13"
               Style="{StaticResource PhoneTextSmallStyle}" Grid.Row="4" 
               d:LayoutOverrides="Height"/>
    <TextBlock Text="{Binding UnitsOnOrder}" HorizontalAlignment="Left"
               Style="{StaticResource PhoneTextBodyTextStyle}" Grid.Column="1" 
               Margin="23,8,0,10"  Grid.Row="4" d:LayoutOverrides="Height"/>

    <TextBlock TextWrapping="Wrap" Text="discontinued" Margin="5,12,0,13"
               Style="{StaticResource PhoneTextSmallStyle}" Grid.Row="5" 
               d:LayoutOverrides="Height"/>
    <CheckBox IsChecked="{Binding Discontinued}" HorizontalAlignment="Left"
               Style="{StaticResource PhoneToggleSwitch}" Grid.Column="1" Margin="0" 
               Grid.Row="5" d:LayoutOverrides="Width" VerticalAlignment="Center"/>
    <TextBlock Margin="149,15,67,0" TextWrapping="Wrap" Grid.Column="1"
               Text="{Binding Discontinued}" VerticalAlignment="Top" Grid.Row="5"/>
</Grid>

Now you should see a visual representation of the product from the sample data. Let’s hook this up to the actual service now. As a matter of fact, if we run the application now, you might be suprised to see that it already works!

The secret to this amazing behavior is that the solution template that we leverages as a starting point for this application has the beahavior of passing the selectedItem of the listbox to the DataContext of the next page, and since our databinding was only created on the design-surfaces everything works perfectly.

The only thing that I’m slightly discouraged by with the “finished” solution is that when we navigate back to the ProductsPage from the DetailsPage, the current implementation will actually go to the service again and bring down the products. This will cause some load on the network and I’m guessing we don’t want to hog the device-bandwidth with this traffic, unless we are the carrier of the network Smile. I still need to find some sort of nice caching implementation before I’m completely happy but still this article I hope have provided you with a good foundation of creating oData viewers with Windows Phone 7 Series.

Keep the comments coming, please!

Den här bloggen använder BlogEngine.NET 1.6.0.0
Temat anpassat av Johan Lindfors