Last night I had the pleasure of presenting “Unit Testing Made Easy” at NoDeNUG (Northern Delaware .Net User Group).  I’ll be doing the same demo at Philly.Net Code Camp next week.  The NoDeNUG crowd was great and asked good questions.  That made the demo fun for me and I think it went very well.  I hope it goes over great at Code Camp too. 

I’m attaching a zip file containing my slides and Visual Studio Solution.  The demo should work fine on it’s own, the references to NUnit, MOQ, and StructureMap are all included.  But if you don’t have VS2010 with Premium or Ultimate and Feature Pack 2, the CodedUI (testing for Silverlight UIs) won’t work.  I hope it will build and run ok though.  If not, let me know and I’ll upload the solution without references to the Coded UI stuff.  Also, the demo uses a Silverlight application for the front end.  If you don’t have the Silverlight tools set up, you can either add them to Visual Studio, or simply exclude the Silverlight projects.  You’ll still be able to run the services and the unit tests, even if you can’t see how the UI looks.

If you’ve just come across this and haven’t heard my presentation you have two options:

1. Come to Philly.Net Code Camp next week (April 9) and hear the presentation then!

2. Just open the enclosed solution and have a look!  I’ve got sample code in there to demonstrate using Dependency Injection to make services easier to unit test, sample unit tests, and sample tests using mocking of dependencies.  I’m coding my tests with NUnit, using StructureMap for my IOC, and MOQ as my mocking framework.

Here is the code:  UnitTestingMadeEasy.zip

Again, if you have any problems with the solution, let me know and I’ll upload a copy without the Coded UI, or even without the Silverlight part.

In a previous post I wrote about some tips for creating WP7 apps which included using the CameraCaptureTask.  A reader responded, asking how to save the picture.  So I figured I’d write a more detailed response with some samples.

In this post I’ll show 3 easy sample:

  1. How to simply use the camera and display a photo.
  2. How to save an image to IsolatedStorage (and change the size of the photo too!)
  3. How to save an image to the phone’s media library.

All of these are pretty simple.  I’m sure once you get started you can easily modify this code to do more creative things. 

First, you’ll need to define a CameraCaptureTask.  You should always do so as a class level variable.   You should also wire up the Completed handler in the constructor  These steps are important for dealing with application tombstoning.  For more on this, please read this article.

private CameraCaptureTask _cameraCaptureTask;

public MainPage()
{
    InitializeComponent();

    _cameraCaptureTask = new CameraCaptureTask();
    _cameraCaptureTask.Completed += CameraCaptureTaskCompleted;

}

How to simply use the camera and display a photo:

You’ll need to kick off the camera task, I’m using a button.  
private void SimpleTest_Click(object sender, EventArgs e)
{
    try
    {
        _cameraCaptureTask.Show();
    }
    catch (InvalidOperationException ex)
    {
        // Catch the exception, but no handling is necessary.
    }

}
In my XAML, I’ve defined an Image named MainImage
<Image x:Name="MainImage" />

Now when the CameraCaptureTask is complete, just bind the results of the task to the Image as I’m doing here:

void CameraCaptureTaskCompleted(object sender, PhotoResult e)
{
    if (e.TaskResult == TaskResult.OK)
    {
        //simply use the picture.
        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.SetSource(e.ChosenPhoto);
        MainImage.Source = bitmapImage;
    }
}

Easy, right?

How to save an image to IsolatedStorage (and change the size of the photo too!)

In this case I want to save the image to IsolatedStorage.  In addition, the app I was creating didn’t need full size images.  So I figured, why waste space in the user’s IsolatedStorage?  So I use a WritableBitmap and change the size of the image.  You’ll notice that after I save the image, I read it back and bind the results to another image named SmallerImage.  That’s just to prove that saving it really worked!

void CameraCaptureTaskCompleted(object sender, PhotoResult e)
{
    if (e.TaskResult == TaskResult.OK)
    {
        //here I save the image to Isolated Storage.  Also I am changing the size of it to not waste space!
        WriteableBitmap writeableBitmap = new WriteableBitmap(200, 200);
        writeableBitmap.LoadJpeg(e.ChosenPhoto);

        string imageFolder = "Images";
        string imageFileName = "TestImage.jpg";
        using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
        {

            if (!isoFile.DirectoryExists(imageFolder))
            {
                isoFile.CreateDirectory(imageFolder);
            }

            string filePath = Path.Combine(imageFolder, imageFileName);
         using (var stream = isoFile.CreateFile(filePath))
            {
                writeableBitmap.SaveJpeg(stream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 0, 100);
            }
        }

        //now read the image back from storage to show it worked...
        BitmapImage imageFromStorage = new BitmapImage();

        using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
        {
            string filePath = Path.Combine(imageFolder, imageFileName);
            using (var imageStream = isoFile.OpenFile(
                filePath, FileMode.Open, FileAccess.Read))
            {
                imageFromStorage.SetSource(imageStream);
            }
        }
        SmallerImage.Source = imageFromStorage;
    }
}

How to save an image to the phone’s media library.

This one is pretty easy too.  Just remember to add a reference to Microsoft.Xna.Framework or you can’t access the Media Library. Also, you’ll need this using statement:

using Microsoft.Xna.Framework.Media;
void CameraCaptureTaskForSavingToLibraryCompleted(object sender, PhotoResult e)
{
    byte[] imageBits = new byte[(int)e.ChosenPhoto.Length];
    e.ChosenPhoto.Read(imageBits, 0, imageBits.Length);
    e.ChosenPhoto.Seek(0, SeekOrigin.Begin);
    MediaLibrary library = new MediaLibrary();
    library.SavePicture("TestPhoto", imageBits);
}

Hopefully you’ll see that using this feature is pretty easy.

I recently started writing my first Windows Phone 7 Application.  I was shocked at how easy it was to get started although I’ll admit that has a lot to do with my existing knowledge of Silverlight.  If you don’t know Silverlight, now is a great time to learn it.  You can write apps for the web, desktop, and Windows Phone 7 too! 

As I wrote my application, I compiled a list of tips to share.  I spent a bunch of time tracking some of these down or figuring them out.  I hope this will be helpful to other people.  Plus, I’ll use this as a reference for myself when I create my next app!

Here you go.  The first two are pretty basic, but worth mentioning.

Tip:  Go For It!

The best advice is to install the tools and try it out for yourself.  If you create an application from one of the templates (you’ll get them after you install the tools for Visual Studio) you find that the templates themselves are a great learning tool.  Some include samples for styling, data binding, design time data binding, navigation, and more!  I recommend trying each of the templates out.

Tip: Install the Free Tools

This isn’t really a tip.  You can’t create apps without doing this!  Visit the App Hub to download the free tools.  You get all this for free: VS 2010 Express, the Windows Phone Emulator, Expression Blend for Windows Phone, and more!  Also, don’t forget to install Silverlight for Windows Phone Toolkit from the CodePlex site.  It includes some additional controls that are great like AutoCompleteBox, ContextMenu, GestureListener and more!  By the way, when you are at the App Hub, check out all the great learning resources.  By the way, you should keep in mind that Windows Phone 7 is a subset of Silverlight 3!  That means that most features of 3 are there but not all.  And Silverlight 4 features are obviously not included.

Tip: Using the Software Input Panel

The Software Input Panel (SIP) is the “on screen” keyboard that users use to key in data.  It’s pretty cool and has some great features.  First, you don’t need to turn it on.  If you include a TextBox in your app, when it gets focus the SIP will appear.  But there are many versions of the SIP and you can easily configure which one appears by setting the InputScope property of your TextBox.  You can get a full list of the options here.  If you want users to enter numbers, set InputScope to Digits.  For email address entry, try EmailNameOrAddress and the keyboard will include the @ sign.  Some choices are more subtle.  Choosing AddressCountryName may seem like the typical keyboard but the first letter typed will be capitalized, remaining character will be lower case.  There are many cool and smart features like that.  Also, options like Text or Chat will include word suggestions!  Here are some code samples and screen shots:

<TextBox InputScope="EmailNameOrAddress" Height="75" />
<TextBox InputScope="Text" Height="75" />

image     image

The first screenshot is the SIP when the EmailNameOrAddress version has focus.  In the second screen shot (TextBox InputScope set to Text), I typed a few letters and you can see the word suggestions!

Tip:  Orientation

If you want your application to support both portrait and landscape mode (when the user tilts the phone over), you need to set up each page’s SupportedOrientations property to do so as follows.  Set the default value in the Orientation property.

<phone:PhoneApplicationPage 
    x:Class="WindowsPhoneApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    SupportedOrientations="PortraitOrLandscape"  Orientation="Portrait"

Tip: UI Design

First, you should check out the UI Design and Interaction Guide for tips on how to properly design and style the look and feel of your application.  Also, you should try to use the standard styles provided when you create an application.  Setting the style in this way will give your application a consistent look.  Here are a few samples:

<TextBlock x:Name="ApplicationTitle" Text="Demo" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="first page" Style="{StaticResource PhoneTextTitle1Style}"/>

Tip: Using Isolated Storage

For simple values, you can easily get in and out of IsolatedStorageSettings.ApplicationSettings (Dictionary). For more complex data, you can put it into IsolatedStorage.  Since there is no database available in Wp7, one common approach to saving data is to simple serialize your model and save it as a file.  To do so, make sure you mark all of your Model’s classes with the attribute DataContract and make sure the properties have the DataMember attribute.  Here’s a sample class called ListOfStuff as well as the methods I use to read/write it to/from IsolatedStorage:

[DataContract]
public class ListOfStuff : Observable
{
    [DataMember]
    public string Title
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }
    }
    private string _title;

    [DataMember]
    public ObservableCollection<ListCategory> Categories
    {
        get { return _categories; }
        set
        {
            if (_categories != value)
            {
                _categories = value;
                NotifyPropertyChanged("Categories");
            }
        }
    }
    private ObservableCollection<ListCategory> _categories = new ObservableCollection<ListCategory>();
}
public static void SaveToFile(ListOfStuff listOfStuff)
{
    using (IsolatedStorageFile isolatedStorageFile =
    IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream =
        new IsolatedStorageFileStream(string.Format("{0}.dat", listOfStuff.Title), FileMode.Create, isolatedStorageFile))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(ListOfStuff));
            serializer.WriteObject(stream, listOfStuff);
        }
    }
}

public static ListOfStuff LoadFromFile(string listName)
{
    ListOfStuff listOfStuff = null;
    using (IsolatedStorageFile isf =
    IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream = 
        new IsolatedStorageFileStream(string.Format("{0}.dat", listName), FileMode.OpenOrCreate, isf))
        {
            if (stream.Length > 0)
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(ListOfStuff));
                listOfStuff = serializer.ReadObject(stream) as ListOfStuff;
            }
        }
    }
    return listOfStuff;
}

Tip: Using the Phone’s Camera

Using the phone couldn’t be simpler, just use the CameraCaptureTask as follows:

**NOTE: As reader Andy Wilkinson pointed out in a comment to this post, I’m not following best practices here.  The way I declare my CameraCaptureTask could lead to problems with tombstoning.  He points out a nice article on MSDN that explains the proper use, please read it here.  Thanks, Andy, for the assistance!

**Another Note:  Another user asked about saving the results of the CameraCaptureTask.  So I’ve written another post that you may find useful.  Please check it out here.

private void Camera_Click(object sender, RoutedEventArgs e)
{
    CameraCaptureTask cameraCaptureTask = new CameraCaptureTask();
    cameraCaptureTask.Completed += cameraCaptureTask_Completed;
    cameraCaptureTask.Show();
}
After the picture is taken, you can access it later, as a Stream.  You can assign it to an Image, save it, or do whatever you want.
void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
    var photoStream = e.ChosenPhoto;
}

Tip: Using Gestures

Of course, you want your application to react when users use common phone Gestures such as Flick, Pinch, Hold, etc.  Doing so is easy too!  The Silverlight Toolkit for Windows Phone (mentioned in second tip above) provides the GestureListener that you will need.  You can see how simple it is to wire up in the following example. In this case, I want the user to be able to hold their finger down on an image to go to “edit mode” where a description TextBox will appear.  In the NoteHold() method (not shown), you can imaging all I need to do is set the description TextBox to be visible.

<Image Source="{Binding Image}">
    <ToolkitControls:GestureService.GestureListener>
        <ToolkitControls:GestureListener Hold="NoteHold" />
    </< span>ToolkitControls:GestureService.GestureListener>
</< span>Image>

Now go start creating apps!

If you’ve been searching the web for a good sample of how to drag and drop data from one DataGrid to another in Silverlight, you’ve probably found some great samples out there, showing “how easy” it can be by just surrounding your DataGrid with DataGridDragDropTarget tags.  In fact, if you do that, you can drag and drop data from one grid to the other.  The problem is that most of these demos are about the visual aspect of drag and drop.  But in the real world, there is more work to be done.  Most of the samples that I found did not deal with how to save the data once it was dropped in the other grid.  I’m using the MVVM pattern so basically what I need to do is, once the drop is complete, update my ViewModel.

The tricky part was figuring out what information was actually dropped on my target DataGrid.  It’s not at all obvious how to do that.  The Drop event uses DragEventArgs which has a Data property.  You’d think this would be the data from the other DataGrid, but you’d be wrong.  Data has a GetData() method but you need to provide it a parameter specifying the format of the Data.  Once you figure out how to do that, you’ll find that GetData() doesn’t actually give you the data!  It give you ItemDragEventArgs, which also has a Data property.  Is this Data the data you want?  Not exactly, but you are getting close.  This Data can be cast as a SelectionCollection – that is because a DataGrid supports multiple selections at the same time!  And each Selection in the collection is the data you actually want.  Is it me, or is that pretty confusing? 

I wouldn’t have gotten this far, but searching the web for a while, I stumbled across a post on StackOverflow that was helpful.  The response also references a blog post found here as well. 

Those samples I found were really helpful but it seemed like it could be made easier.  Starting with sample code from the blog post mentioned above, I created a very simple, reusable, Extension Method that uses Generics and does all of the heavy lifting for you!  This should make things pretty easy now.

Here is some of the sample code and a sample solution is attached here.   

First, here is the extension method that gets the underlying data that was dropped on the target:

public static IEnumerable<T> GetData<T>(this DragEventArgs args)
{
    IEnumerable<T> results = null;

    // Get the dropped data from the Data property and cast it to the first format. 
    ItemDragEventArgs dragEventArgs = args.Data.GetData(args.Data.GetFormats()[0]) as ItemDragEventArgs;

    if (dragEventArgs == null)
        return results;

    // Get the collection of items
    SelectionCollection selectionCollection = dragEventArgs.Data as SelectionCollection;
    if (selectionCollection != null)
    {
        // cast each item to what is expected
        results = selectionCollection.Select(selection => selection.Item).OfType<T>();
    }

    return results;
}

Here is the XAML for the two grids.  Note that in this sample (you can change this of course) I’m using AllowedSourceEffects.Copy so that the data remains in the first grid and is copied to the second.

<Toolkit:DataGridDragDropTarget AllowedSourceEffects="Copy"
                                Grid.Column="0" Grid.Row="0">
    <Controls:DataGrid x:Name="Data"
                        ItemsSource="{Binding Data}" 
                        AutoGenerateColumns="False">
        <Controls:DataGrid.Columns>
            <Controls:DataGridTextColumn Header="Id" Binding="{Binding Id}" />
            <Controls:DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
            <Controls:DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
        </Controls:DataGrid.Columns>
    </Controls:DataGrid>
</Toolkit:DataGridDragDropTarget>

<Toolkit:DataGridDragDropTarget AllowedSourceEffects="Copy"
                                Drop="DataGridDragDropTarget_Drop"
                                Grid.Column="1" Grid.Row="0">
    <Controls:DataGrid x:Name="MoreData"
                        ItemsSource="{Binding MoreData}" 
                        AutoGenerateColumns="False" 
                        AllowDrop="True">
        <Controls:DataGrid.Columns>
            <Controls:DataGridTextColumn Header="Id" Binding="{Binding Id}" />
            <Controls:DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
            <Controls:DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
        </Controls:DataGrid.Columns>
    </Controls:DataGrid>
</Toolkit:DataGridDragDropTarget>

Lastly, here is the code behind piece that handles the Drop event, get’s the data and passes it to my ViewModel.  Note here that I specify e.Handled = true.  Without that, the DragDropTarget would automatically copy the data again.

private void DataGridDragDropTarget_Drop(object sender, Microsoft.Windows.DragEventArgs e)
{
    //use the extension method to get the data from the DragEventArgs
    var data = e.GetData<Person>();

    foreach (var item in data)
    {
        _viewModel.AddToMoreData(item);
    }
    e.Handled = true;
}

Once again, here is a link to a complete sample project

I’ve seen a few posts describing how to use a Uri as a source for a BitmapImage, and then the BitmapImage as the source for the WriteableBitmap.  But that didn’t work so well until I figured out the trick.  Here goes…

First, here is the code that I THOUGHT would work, but did not.

Uri uri = new Uri("http://somedomain.com/someimage.png");
BitmapImage bitmapImage = new BitmapImage(uri);
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);

When you run that, you’ll most likely get an exception (I did) because the BitmapImage is not set when it is used for the WriteableBitmap.  My hypothesis was that the BitmapImage doesn’t render itself until it is needed.  I started looking through the properties of the BitmapImage, luckily there aren’t too many, when I came across the CreateOptions property – that sounded interesting!  It is an Enum with 3 values: DelayCreation, IgnoreImageCache, and None.  Guess which one is set as the default?  DelayCreation!  Here was my next pass at the code:

Uri uri = new Uri("http://somedomain.com/someimage.png");
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.CreateOptions = BitmapCreateOptions.None;
bitmapImage.UriSource = uri;
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);

That’s it, pretty simple and it works.  But I took it one step further just in case.  I’m not positive this is necessary but I like to play it safe.  When inspecting the properties of the BitmapImage, I saw there is an ImageOpened event. I was thinking that some images may load slowly and I wasn’t sure if that happens asynchronously or not.  Would my application wait around for them to finish loading?  I don’t really know but it sure sounds like the ImageOpened event would be a way to make sure my images were loaded.  Here is my final take:

public void SomeMethod()
{
    Uri uri = new Uri("http://somedomain.com/someimage.png");
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.CreateOptions = BitmapCreateOptions.None;
    bitmapImage.ImageOpened += ImageOpened;
    bitmapImage.UriSource = uri;
}

void ImageOpened(object sender, RoutedEventArgs e)
{
    BitmapImage bm = (BitmapImage)sender;

    WriteableBitmap wbm = new WriteableBitmap(bm);

    //now I can use wbm for whatever I need...
}

Good luck with your WriteableBitmaps!