Dallas, Development, Events, Texas, WP7

Windows Phone Acceleration Labs

I’m very pleased to announce a new set of Windows Phone Acceleration Labs to be held in Dallas, Columbus, Chicago and Minneapolis.  Acceleration Labs are a week-long event where developer get a chance to break away from the office and minimize the distractions of email, the telephone and other work-related fire-drills to spend 3-5 quality days writing code and building applications. We ran a pair of these last year in Dallas and Chicago to great success, so now we’re doing them again in even more places! 

Here’s a listing of the cities, dates, times and locations for our upcoming Acceleration Labs.  Please register using the links provided to claim your seat. Space is limited, so register early.

Columbus, OH 11/15/2011 – 11/17/2011 8:30am – 5:00pm Microsoft Columbus Office
Minneapolis, MN 11/29/2011 – 12/1/2011 8:30am – 5:00pm Microsoft Minneapolis Office (old office)
Chicago, IL 12/6/2011 – 12/8/2011 8:30am – 5:00pm Microsoft Chicago Office
Dallas, TX 12/13/2011 – 12/15/2011 8:30am – 5:00pm Microsoft Dallas Office

 

A few additional pieces of information about these labs:

  • These labs are NOT training sessions – we expect that you have experience with XAML and C# or VB.NET before coming to the lab.
  • Experts will be on-hand and via phone / Live Meeting to help you work through problems with the applications you are in the middle of developing, or help you work through the ideas you’ve already developed to help get you started.
  • Please ensure that all development tools and SDKs are installed prior to arrival. If you don’t already have the tools installed, you can get them from http://aka.ms/PhoneCK.
  • You don’t have to attend all day every single day – if your schedule only allows for you to participate part-time, please let us know.  If your plans change, however, and you’re not able to attend at least most of the days, please let us know so that we can free up your seat for the next person on the waiting list.

If you have any questions about the labs, or building Windows Phone applications in general, please feel free to reach out to me through this blog, or directly via chris.koenig@microsoft.com.

Development, WP7

Using Databases with Mango

One of the top wish-list items for Windows Phone 7 developers was the ability to store data locally on the phone in a relational format. That was one of the top questions I always got asked when talking about Windows Phone – “Where is my local database?!?!”  Thanks to a LOT of feedback from all of you, and some clever engineering on the part of the Windows Phone team, we now have support for SQL Server Compact Edition with the new Windows Phone 7.1 SDK. This post will show some basic information on how to use the database platform on Windows Phone, as well as give some tips on how to update your database once it’s deployed, and how to deploy a database with your application.

Enter the Database

Using the SQL CE platform on Windows Phone is really straightforward – everything you need to do is done in code using the Linq to SQL framework. In a nutshell, creating a data model is as simple as creating classes for each of your model items, adding Linq to SQL attributes, and creating a subclass of DataContext. Then, with only a couple lines of code, you have a working, updatable SQL database.

Creating the Data Model

This is simply be done by creating a bunch of classes in your application and applying the appropriate attributes. For our sample application, we’re going to create a database that tracks widgets. We start off by creating the Widget class. I like to put all my Model classes in a Models folder, with associated Models namespace, but you can do whatever makes sense to you.

namespace DatabaseForMango.Models
{
    public class Widget : TableObject
    {
        // WidgetId
        private int _WidgetId;

        public int WidgetId
        {
            get { return _WidgetId; }
            set
            {
                if (_WidgetId == value)
                    return;
                NotifyPropertyChanging("WidgetId");
                _WidgetId = value;
                NotifyPropertyChanged("WidgetId");
            }
        }

        // WidgetName
        private string _WidgetName;

        public string WidgetName
        {
            get { return _WidgetName; }
            set
            {
                if (_WidgetName == value)
                    return;
                NotifyPropertyChanging("WidgetName");
                _WidgetName = value;
                NotifyPropertyChanged("WidgetName");
            }
        }
    }
}

Note that we’re using a base class here called TableObject, which only serves to implement INotifyPropertyChanged and INotifyPropertyChanging.  The former is used by the XAML DataBinding infrastructure, and the latter is used by Linq to SQL to detemine updates made to the data.

With the class defined, we have to tell Linq to SQL about it through the use of Attributes. To get access to these attributes, you need to add a reference to the System.Data.Linq.dll assembly – it should be in the list of default framework references for your Windows Phone 7.1 application

If you don’t see that dll in your references list, you are probably working on a Windows Phone 7.0 project that will have to be upgraded in order to take advantage of the database support, or you haven’t yet installed the Windows Phone 7.1 SDK tools from http://aka.ms/PhoneCK – so go do that now if you need to…

With the reference in place, we need to add some using statements to our Model class.

using System.Data.Linq;
using System.Data.Linq.Mapping;

Each class, in the Linq to SQL world, will map to a Table in the database. Each property in the Model class, can map to a Column (not all have to – just those that you want persisted in the database!) We can start off simple by adding the Table attribute to the Widget class, supplying the name of the database table we want created (this allows us to have a different table name than we do class name, if we so choose). Then for each of the properties, except the Id field, we add a plan vanilla Column attribute. For the Id field, we need to do something special because this field is going to be our Primary Key for the table, and is going to be generated by the system – like an Identity column in SQL Server. There are a lot of properties that you can set, but for our purposes, we will add only those that will help us get exactly the kind of column we want in the database:

using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace DatabaseForMango.Models
{
    [Table(Name = "Widgets")]
    public class Widget : TableObject
    {
        // Version column aids update performance.
        [Column(IsVersion = true)]
        private Binary _version;

        // WidgetId
        private int _WidgetId;

        [Column(
            IsPrimaryKey = true,
            IsDbGenerated = true,
            DbType = "INT NOT NULL Identity",
            CanBeNull = false,
            AutoSync = AutoSync.OnInsert)]
        public int WidgetId
        {
            get { return _WidgetId; }
            set
            {
                if (_WidgetId == value)
                    return;
                NotifyPropertyChanging("WidgetId");
                _WidgetId = value;
                NotifyPropertyChanged("WidgetId");
            }
        }

        // WidgetName
        private string _WidgetName;

        [Column]
        public string WidgetName
        {
            get { return _WidgetName; }
            set
            {
                if (_WidgetName == value)
                    return;
                NotifyPropertyChanging("WidgetName");
                _WidgetName = value;
                NotifyPropertyChanged("WidgetName");
            }
        }
    }
}

One other note – you’ll see that I added a Version column to the database. This isn’t something that the developer will update, or even expose to the end user, but it’s something that makes Linq to SQL very happy and can help improve update performance on our table. Update performance improvments this simple should be part of every project!

Now that we have the basic Widget class and attributes defined, let’s define another entity that we want to track, which we’ll call Category. The Category entity will be defined in a similar way as our Widget class:

using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace DatabaseForMango.Models
{
    [Table(Name = "Categories")]
    public class Category : TableObject
    {
        // Version column aids update performance.
        [Column(IsVersion = true)]
        private Binary _version;

        // CategoryId
        private int _CategoryId;

        [Column(
            IsPrimaryKey = true,
            IsDbGenerated = true,
            DbType = "INT NOT NULL Identity",
            CanBeNull = false,
            AutoSync = AutoSync.OnInsert)]
        public int CategoryId
        {
            get { return _CategoryId; }
            set
            {
                if (_CategoryId == value)
                    return;
                NotifyPropertyChanging("CategoryId");
                _CategoryId = value;
                NotifyPropertyChanging("CategoryId");
            }
        }

        // CategoryName

        private string _CategoryName;

        [Column]
        public string CategoryName
        {
            get { return _CategoryName; }
            set
            {
                if (_CategoryName == value)
                    return;
                NotifyPropertyChanging("CategoryName");
                _CategoryName = value;
                NotifyPropertyChanging("CategoryName");
            }
        }
   }
}

With both tables in place, we now can configure the relationship between them. This is not as straightforward as defining the Table attributes – for this we need to define a set of Associations and use a couple of new classes instead of data types.

Creating Associations

An association represents a one-to-many relationship in a database, and is represented in Linq to SQL by two special classes – the EntityRef, which defines the “1” side of the equation and the EntitySet which defines the “many” side. In our example, a Widget can be assigned one category, but each Category can know multiple Widgets. The way we represent this in our data model is to define an EntityRef property on the Widget class, and an EntitySet property on the Category class. First, the EntityRef.

// Category
[Column]
internal int _categoryId;

private EntityRef<Category> _category;

[Association(
    Storage = "_category",
    ThisKey = "_categoryId",
    OtherKey = "CategoryId",
    IsForeignKey = true)]
public Category WidgetCategory
{
    get { return _category.Entity; }
    set
    {
        NotifyPropertyChanging("WidgetCategory");
        _category.Entity = value;
        if (value != null)
        {
            _categoryId = value.CategoryId;
        }
        NotifyPropertyChanged("WidgetCategory");
    }
}

As you can see, defining the EntityRef requires 3 parts:

  • The EntityRef<Category> that holds the reference to the Category object,
  • The private int field that  holds a reference to the primary key of the associated Category object
  • The Category property that returns the EntityRef<Category> and also serves to define the Association attribute

We also account for that specialty EnityRef<T> property by assigning it’s Entity property to the associated Category instance, instead of assigning it’s value directly.

The properties of the Association attribute identify this relationship as a Foreign Key, and also define which fields relate the two objects together:

  • Storage = the name of the local EntityRef field (in this case, we’ve stored that above in the _category field)
  • ThisKey = the name of the local property that defines where we are storing the foreign “key” itself (in this case, we’ve stored that in the int field _categoryId)
  • ThatKey = the name of the Primary Key property on the Category object we’re referencing (in this case, that’s been defined as the Category property).

Note that the value for the ThatKey property in the Association has to match up with the property on the Category class that has been attributed as a column and has been indicated as the primary key.

With this in place, we can move on to the Category class, and defining the EntitySet for its associated Widget classes

// Widgets
private EntitySet<Widget> _Widgets;

[Association(
    Storage = "_Widgets",
    ThisKey = "CategoryId",
    OtherKey = "_categoryId")]
public EntitySet<Widget> Widgets
{
    get { return _Widgets; }
    set { _Widgets.Assign(value); }
}

// Assign handlers for the add and remove operations, respectively.
public Category()
{
    _Widgets = new EntitySet<Widget>(
        new Action<Widget>(this.attach_Widget),
        new Action<Widget>(this.detach_Widget)
        );
}

// Called during an add operation
private void attach_Widget(Widget w)
{
    NotifyPropertyChanging("WidgetCategory");
    w.WidgetCategory = this;
}

// Called during a remove operation
private void detach_Widget(Widget w)
{
    NotifyPropertyChanging("WidgetCategory");
    w.WidgetCategory = null;
}

Although this initially appears to be the same thing as we saw on the Widget class, we’re dealing some some different elements on the “many” side of the relationship:

  • A private storage field of type  EntitySet<Widget>  that will reference the associated set of Widget objects for this category.
  • A public property of type EntitySet<Widget> that defines the association between the two tables
  • Some delegate functions for handling the cases where a Category is attached or Detatched from a given Widget. These delegate functiions provide the simple “glue” for connecting the Category to the passed in Widget, thus ensuring the referential integrity of the foreign key relationship.

Like the Association attribute on the Widget class, this also defines a couple of key elements – although IsForeignKey is missing (we don’t put that on the “many” side of the relationship)

  • Storage = the name of the local EntitySet field (in this case, the _widgets field)
  • ThisKey = the name of the local property that identifies the Primary Key for this entity (in this case, the CategoryId property)
  • ThatKey = the name of the property (or field) on the Widget object that holds the Primary Key for this Category object (in this case, the _categoryId field).

Interestingly, the _categoryId field is private on our Widget class, but it still seems to work out! The same rule about the key properties still applies here – these fields have to be the ones attributed with the [Column] attributes, which applies both to _categoryId on Widget and CategoryId on Category.

Now with the Tables all defined and attributed, we are ready to move on to the DataContext

Creating the DataContext

The DataContext object is the portal by which your application interacts with the database. Linq to SQL defines a DataContext base class, loaded with behavior, for you to use in your own application.  The DataContext class we create will provide the endpoints – properties and methods – that our application will use to interact with our database. It is up to you how you choose to expose information here – you can provide methods, similar to Stored Procedures in SQL Server or you can provide a more OData-like interface where you just expose the IQueryable Table endpoints directly.  For our purposes, we’re going to forego the StoredProc-like route and just expose each table as an endpoint property on our custom DataContext:

using System;
using System.Data.Linq;

namespace DatabaseForMango.Models
{
    public class WidgetDataContext : DataContext
    {
        public WidgetDataContext()
            : base("Data Source=isostore:/WidgetDb.sdf")
        {
        }

        public Table<Widget> Widgets;
        public Table<Category> Categories;
    }
}

Not much to this one. We’ve provided a default connection string to the single constructor, and exposed each table as a public property of type Table<T> – one for Widget and one for Category. You could name these whatever you like, but it makes sense to use names that will make sense to the developer…

Now that the DataContext is in place, we can start to make our database a reality by actually creating it on the Phone platform.

Make the Database a Reality

With the DataContext, and all the classes in place, we can now ensure that our database is created and ready for action. Determining this information is really simple:

private static void SetupDb()
{
    WidgetDataContext db = new WidgetDataContext();
    if (!db.DatabaseExists())
    {
        db.CreateDatabase();
    }
}

Notice how simple it is to get the database created. There is a simple check to see if the database exists already, and if not it creates a new one.  The trick of course, is where to put this code, and what to do if the database in your application is newer than what has been deployed.  For the first part, I tend to put this information in the constructor for App.Xaml or in the Loading event. I know that adds time to the application’s load experience, but it’s probably pretty important that the database be up-to-date before doing any work. If you run into performance problems, you can always add some code around the loading of your Main Page and make some updates there, but don’t blame me if things go wonky Smile

Updating the Database

The other half of my question was determining how to make updates to your database after it’s been deployed. This is also pretty straight-forward, although not necessarily simple. Step 1 is determining if we need an update or not. For that, we use the DatabaseSchemaUpdater class from Linq to SQL. Here’s an expanded version of our SetupDB() method that includes this code:

private static void SetupDb()
{
    WidgetDataContext db = new WidgetDataContext();
    if (!db.DatabaseExists())
    {
        db.CreateDatabase();
        var updater = db.CreateDatabaseSchemaUpdater();
        updater.DatabaseSchemaVersion = 1;
        updater.Execute();
    }
    else
    {
        var updater = db.CreateDatabaseSchemaUpdater();
        if (updater.DatabaseSchemaVersion < 2)
        {
            // make some updates

            updater.AddTable<Log>();
            updater.AddColumn<Widget>("CreatedDate");
            updater.DatabaseSchemaVersion = 2;
            updater.Execute();
        }
    }
}

Using the the DatabaseSchemaUpdater class and it’s DatabaseSchemaVersion property, it’s fairly easy to figure out what updates need to be done. In this example we’re adding a Log table to the database, and adding a CreatedDate column to the Widget table. Of course, that Widget object needs to actually have a CreatedDate property exposed and properly attributed as a column, but this code here is all you need to do to get Linq to SQL to make the schema update for you.

For new tables and columns, the process is really pretty easy. What’s hard is dealing with changes to existing columns. Currently, Linq to SQL doesn’t provide a good way to do this, so we have to get creative. One approach might be to create a new column in your table just like another column, and copy all the data over. Then, delete the old column, recreating it with new properties. Lastly, move the data back over from the temporary column to the new column and delete the old one. Ugly, I know, but that’s where we are right now. If you have suggestions or ideas on better ways to manage this, I’m all ears.

Deploying a Database with your Application

Another situation can arise when you have a lot of data to deploy with your application, or you want to improve the initial startup of your application by pre-loading a database and deploying it with your application. This too is really simple to do, and is made even easier using a “buddy project” – just create a console application in your solution and add a SQL Database object to it. Console applications have designer support for databases, so you can create your schema and pre-load it however you like, and just copy it into your phone project when you’re ready to deploy. Don’t forget to set the database properties to “Content” and “Copy Always” or you might get unexpected results when running your application.

Once you have the database deployed, you can either use it as a reference database to read data from, or copy it over to Isolated Storage and use it as an application database. Here’s a code snippet showing how you can do the latter in only a few simple lines of code:

// Obtain the virtual store for the application.
IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();

// Create a stream for the file in the installation folder.
using (Stream input = Application.GetResourceStream(new Uri("ReferenceDB.sdf", UriKind.Relative)).Stream)
{
    // Create a stream for the new file in isolated storage.
    using (IsolatedStorageFileStream output = iso.CreateFile("ApplicationDB.sdf"))
    {
        // Initialize the buffer.
        byte[] readBuffer = new byte[4096];
        int bytesRead = -1;

        // Copy the file from the installation folder to isolated storage.
        while ((bytesRead = input.Read(readBuffer, 0, readBuffer.Length)) > 0)
        {
            output.Write(readBuffer, 0, bytesRead);
        }
    }
}

This code uses the stream infrastructure provided by Isolated Storage and Silverlight 4 to copy the ReferenceDB.sdf file from application storage into a file called ApplicationDB.sdf in IsolatedStorage. If you’d rather leave it as a read-only database in the application folder, just change the connection string to appstore:/ instead of isostore:/ and you’re good to go!

Parting Thoughts

Working with the SQL CE database on Windows Phone is pretty easy, thanks to Linq to SQL, but there is still room for improvement. The Visual Studio tooling for Windows Phone projects don’t yet support the SQL CE database designer, so you’ll either have to do all your coding by hand, or use a “buddy project” to create your data model. Once the model is created, you can use the techniques described here to deploy the database with your application, and provide updates to it as necessary. Keep in mind that the database you’re creating is running on a limited-capacity mobile device that is usually connected over an often slow network connection. For reliability and scalability, your application might still require the use of a server-side database to serve as a more permanent store for data as well as data archival. Think about the end users of your application when determining how much data to put in the database running on the phone, and how much to move over to a server. With the always available Windows Azure and SQL Azure platforms, data integrity is only a cloud-hop away…

Get the source code examples that accompany this post from my GitHub repository at the following URLs:

https://github.com/ChrisKoenig/DatabaseForMango – This is the Widget/Category code

https://github.com/ChrisKoenig/ReferenceDatabase – This is the Reference Database code

 

Development, Product Announcements, WP7

Windows Phone Icon Maker

My peer over in Japan released a new project on CodePlex this morning called the Windows Phone Icons Maker. From the web site:

This project makes multple icons necessary to build and publish Windows Phone Application.

When you build and register Windows Phone Application to Maketplace, you have to make 4 size of square Icons as bellow. Windows Phone Icons Maker makes these Icon files from single image. You can load image, trim it, and save Icons.

It’s a free tool that you can download and run from any PC that will generate the following images:

  • For Marketplace
    • 200×200: AppName200.png
    • 173×173: AppName173.png
    • 99×99: AppName99.png
  • For Application
    • 173×173: Background.png
    • 62×62: ApplicationIcon.png

It’s functions are very rudimentary and there is room for improvement (e.g. you have to re-draw your selection box instead of moving the selection) but it totally works like a champ for generating all the icon imagry that you need for your Windows Phone application.  Download it and give it a try!

Development, Events, Oklahoma, TechFest, Tulsa, WP7

Database for Mango

Here are the slides and source code from my talk this morning at Tulsa TechFest on using databases on Windows Phone. I will be writing up a longer technical post to go along with these resources, but since so many people asked for them today, I’m publishing them for your convenience.

Slides (via SlideShare)

Code (via GitHub)

https://ChrisKoenig@github.com/ChrisKoenig/DatabaseForMango.git
https://ChrisKoenig@github.com/ChrisKoenig/ReferenceDatabase.git

Events, Oklahoma, TechFest, Tulsa, WP7

Windows Phone Lab at Tulsa TechFest

My teammate Jeff Blankenburg will be hosting a Windows Phone Development Lab at Tulsa TechFest on Saturday, Oct 8th from 8am-5pm at OSU Tulsa.

The Windows Phone lab is a combination Instructor-Led and Self-Directed lab environment that is designed to help you learn about Windows Phone by building applications instead of just listening to sessions. This hands-on approach has been very successful in building technical chops for those that attend and we’re excited about bringing this lab to Tulsa TechFest. Also on hand will be several Windows Phone experts to help you navigate the labs as well as discuss any ideas for applications you might have, or consult with you on ways to get past any roadblocks you’ve encountered in your own Windows Phone development.

The agenda for the day for the day looks like this:

8:00 am – Check-In

8:45 am – Welcome/Announcements

9:00 am – Instructor-led Lab: Walkthrough building a simple WP7 application

10:00 am – WP7 Hands-on Labs (part 1)

12:00 pm – Lunch

1:00 pm – Glenn Block! Special Keynote!

2:30 pm – WP7 Hands-on Labs (part 2)

5:00 pm – Closing

For more information about the lab, visit the registration site at http://techfests.com/Tulsa/2011/WP7_Accelerator_Lab/default.aspx

Development, WP7

Upload Files from Windows Phone

When speaking to a crowd of Windows Phone developers the other day, I was asked an interesting question about uploading files. We talk about how, with Mango, you can use the BackgroundAgents to download tons of data to the device, but we never talk about uploading. As I understand it (at least as of this writing) although uploads are limited to 5MB, there are no good samples out there on *how* to upload them. Sure, I can use the built-in Facebook or Skydrive sharing features, but where's the fun in that? What if I want to be able to post to my *own* repository? This post is my attempt to answer that question – it’s as much for me to remember how I did it as it will hopefully be helpful to you to see how I accomplished it.

To make it more interesting, I decided that I would implement the server as an MVC application, and only accept REST-based POST actions through a FileController (that’s for you, Amir).

So, here’s the code – I hope you enjoy it!

Here’s my Controller (FileController.cs)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    public class FileController : Controller
    {
        [HttpPost]
        public ActionResult Upload()
        {
            string filename = Server.MapPath("/Uploads/" + Path.GetRandomFileName();
            try
            {
                using (FileStream fs = new FileStream(filename), FileMode.Create))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        using (BinaryReader br = new BinaryReader(Request.InputStream))
                        {
                            long bCount = 0;
                            long fileSize = br.BaseStream.Length;
                            const int BLOCK_SIZE = 4096;
                            byte[] bytes = new byte[BLOCK_SIZE];
                            do
                            {
                                bytes = br.ReadBytes(BLOCK_SIZE);
                                bCount += bytes.Length;
                                bw.Write(bytes);
                            } while (bCount < fileSize);
                        }
                    }
                }

                return Json(new { Result = "Complete" });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "Error", Message = ex.Message });
            }
        }
    }
}

And here's my MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;

namespace PhoneApp10
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void SelectButton_Click(object sender, RoutedEventArgs e)
        {
            PhotoChooserTask task = new PhotoChooserTask();
            task.Completed += task_Completed;
            task.Show();
        }

        private void task_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult != TaskResult.OK)
                return;

            const int BLOCK_SIZE = 4096;

            Uri uri = new Uri("http://localhost:4223/File/Upload", UriKind.Absolute);

            WebClient wc = new WebClient();
            wc.AllowReadStreamBuffering = true;
            wc.AllowWriteStreamBuffering = true;

            // what to do when write stream is open
            wc.OpenWriteCompleted += (s, args) =>
            {
                using (BinaryReader br = new BinaryReader(e.ChosenPhoto))
                {
                    using (BinaryWriter bw = new BinaryWriter(args.Result))
                    {
                        long bCount = 0;
                        long fileSize = e.ChosenPhoto.Length;
                        byte[] bytes = new byte[BLOCK_SIZE];
                        do
                        {
                            bytes = br.ReadBytes(BLOCK_SIZE);
                            bCount += bytes.Length;
                            bw.Write(bytes);
                        } while (bCount < fileSize);
                    }
                }
            };

            // what to do when writing is complete
            wc.WriteStreamClosed += (s, args) =>
            {
                MessageBox.Show("Send Complete");
            };

            // Write to the WebClient
            wc.OpenWriteAsync(uri, "POST");
        }
    }
}

I wrote this using the latest tools available at the time - which is the Windows Phone SDK 7.1 Beta 2 Refresh, so YMMV depending on which version of the tools you're using. I am hopeful that one day I'll be able to look back at this post and laugh at how much code it took to do this simple file upload...

Design, Development, Expression, Featured, Product Announcements, Students, WP7

Windows Phone ‘Mango’ OS beta available today!

Big announcement from the Windows Phone team – they’ve released the Windows Phone Mango OS beta along with the Windows Phone Developer Tools Beta 2 this morning. 

http://go.microsoft.com/?linkid=9772716

The best part? If you have a developer unlocked Windows Phone device (that means that you’ve gone through the Marketplace registration and can currently deploy development apps to your device) you can upgrade to the Mango OS beta! The Mango OS brings a LOT of new features that I’ve really come to enjoy in the short time I’ve had to try it out.  Unified inbox, threaded messages, Windows Live Messenger support, Double-sided Tiles, contact groups and more! 

There’s also some goodness for students too – do you have a Dreamspark account? Do you have an idea for next big Windows Phone application? If so, submit your ideas to the Windows Phone team for a chance to win a Mango phone! Here’s how you do it:

  1. Make sure you’re registered for DreamSpark
  2. Download and install Expression Studio Ultimate and the new Mango Windows Phone Developer Tools (available free as a member of DreamSpark!)
  3. Get the free Sketchflow Template for Windows Phone and create a Sketchflow mock-up of your app
  4. Post the Sketchflow mock-up somewhere online and tweet out the link using the hash tag #WPAppItUp
  5. The WP team will review all prototypes and will contact the developers who submit the best ones and send them a special Mango developer device

Your next steps should be to download the latest tools, start exploring them, their features, and upgrade your phone to the new Windows Phone Mango beta OS. As an added bonus, just like Beta 1, Beta 2 supports framework multi-targeting, which allows you to keep on building great Windows Phone 7 applications today while giving you the ability to explore new features in Windows Phone Mango  and the WPSDK 7.1.

Also, for more information, be sure to check out Brandon Watson's post on the Windows Phone Developer Blog: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/06/29/developers-get-goody-basket-full-of-mangos.aspx

Design, Expression, Featured, Product Announcements, WP7

SketchFlow Templates for WP7

http://wp7sketchflow.codeplex.com/

The SketchFlow Template for Windows Phone 7 adds a new SketchFlow template for Expression Blend* users that makes creating a prototype of a Windows Phone app quick and easy.

* Please note: To use the SketchFlow Template for Windows Phone 7 you need to be using Blend 4 with SketchFlow enabled (this is the version of Blend that comes with both Expression Studio 4 Ultimate and Visual Studio 2010 Ultimate) you also need to have the Mango developer tools for Windows Phone installed.

 

2011-06-09 09h43_52_thumb2011-06-09 09h47_52_thumb2011-06-09 09h47_25_thumb

Awesome stuff!

Development, Featured, Product Announcements, WP7

Windows Phone 7.1 (“Mango”) Tools Beta!

My friends over on the Windows Phone team are pleased to announce today’s release of the Windows Phone 7 “Mango” beta tools release! Loads of new and exciting stuff coming in these updated tools – here’s a slice from the announcement:

Support for the Windows Phone OS 7.1 – Build mobile apps that take advantage of the latest innovations the upcoming Windows Phone OS, including:

  • Additional sensors (camera; compass; gyro)
  • Background Agents
  • Fast Application Switching
  • IE9 Web Browser Control
  • Live Agents, making use of live tile and notification enhancements
  • Silverlight 4
  • Silverlight / XNA Interop
  • Sockets
  • SQL CE
  • And much, much more!

Profiler – A profiler allows you to identify and resolve performance problems quickly and easily.

Improved Emulator – The WPDT 7.1 emulator allows you to emulate provide sensor input, including feeding GPS information and accelerometer data.

Visual Basic – The WPDT 7.1 release provides in-the-box support for Visual Basic. With WPDT 7.1, you can now use Visual Basic to build Silverlight projects, XNA projects, and within both Visual Studio and Expression Blend.

Multi-targeting – The final release of WPDT 7.1 lets you specify the version of the Windows Phone OS that will run your app. This allows you to continue to develop your apps that target the Windows Phone OS 7.0, or target the new ‘Mango’ release. Because the WPDT provides a multi-targeting capability, the beta installation will replace an existing WPDT 7.0 installation. All of your existing projects and code that target Windows Phone OS 7.0 will remain on your box, and can be continued to be developed using the 7.1 tools.

Please note that for this release of WPDT 7.1, these are beta tools. While you are able to develop, test, and submit apps to the Marketplace – these tools have not been completely tested and you may encounter bugs; you should continue to develop and test your Windows Phone OS 7.0 apps using the released WPDT 7.0 tooling.

Here are some resources to help get you started building the next generation of Windows Phone applications:

 

  • WPDT 7.1 Beta Download – Download page for developers to download the beta tools.
  • Windows Phone Developer Blog – News and information about all things Windows Phone development happen on the Windows Phone Developer Blog.
  • Windows Phone sessions @ MIX11 – MIX11 provided 25 sessions on Windows Phone development, the recordings of which are available online for streaming or download. This provides a wealth of information for developers looking to come up to speed on what’s new in ‘Mango’.
  • App Hub – The App Hub is the single developer portal for the Windows Phone developer – providing registration, education, app submission and analytics, and support resources.