Silverlight (and WPF): How to make items stretch horizontally in a ListBox

Sometimes we need to use controls like TextBox, TextBlock etc (that set their width automatically depending on content) in a ListBox’s ItemTemplate. If we need to draw Borders or assign Background colors to each such controls then we may end up having non-equal rows. Read the rest of this entry »

RIA Services: Sending complex types to the client

Entity Framework 4 allows us to create complex types. Typically, such types are used to get the result of a stored procedure. However, when we try to send such a complex type using a WCF RIA Domain Service, the following error is encountered.

The entity ' StoredProcedure_Result' in DomainService 'MyDomainService' does not have a key defined. Entities exposed by DomainService operations must have at least one public property marked with the KeyAttribute.

What to do? Read the rest of this entry »

.NET Framework 4: A first look at the new features

Visual Studio 2010 Release Candidate has been made available a few weeks back. The .NET Framework 4 is arriving with some great new enhancements for all of us, and in this post, I plan to briefly discuss some of those exciting features that caught my eye. Let’s begin:

Parallel extensions
Introducing parallelism in our applications was never this much easier. The new Task Parallel Library offers a lot more control over the work items (called Tasks) as compared to our classic Thread Pooling techniques. The semantics of the new parallel loops are much similar to our existing sequential loops and hence our existing logic can be parallelized with minimal effort. I have discussed the new parallel programming features in .NET framework 4 in my followup post here.

Entity framework 4
The new version of Entity Framework seems to have quite a number of enhancements. It is great that Microsoft has addressed the user responses regarding the current limitations of Entity Framework 3.5. We are getting support for POCO (Plain Old CLR/C# Objects) and self-tracking entities which are great features for our enterprise and LOB applications having more than one tier. The new foreign key associations are another great enhancement since the users were finding it difficult to set associations without grabbing the entity from database. Model first development, lazy loading, code only abilities, complex types handling, better naming of entities, improvement in generated TSQL queries, ability to directly run store commands are some other wonderful features of the upcoming version of Entity Framework.

Managed Extensibility Framework
The Managed Extensibility Framework offer an excellent way for our enterprise LOB applications to dynamically expand. In previous versions of .NET, and without MEF, we need to manually load external assemblies and use reflective techniques to instantiate and use their objects/features. This has been made really easy with Managed Extensibility Framework in .NET 4. When an MEF enabled application is launched, it automatically discovers and loads all the extensions and hence allows us to easily add new features to an already deployed application. Here’s an excellent article by Glenn Block from last month’s MSDN magazine: Building Composable Apps in .NET 4 with the Managed Extensibility Framework. MEF seems quite promising I really look forward to use MEF in my future applications.

Silverlight 4
Wow!! We haven’t yet been able to fully digest Silverlight 3 and SL 4 is approaching. Microsoft is doing a lot of investment in Silverlight and the upcoming version has quite great features. The ability to consume COM objects has greatly reduced the limitations of Silverlight that were inherently present due to being a browser based technology. Tim Heuer once did a wonderful job by covering all the features of Silverlight 4 in this post. I will simply list a few ones here:

  • Drag and Drop support from desktop to a Silverlight App: This one would allow us for better UI experiences for some interactive applications. Imagine that we have got some Rich Text Editor application running and we drag a photo from our desktop and it finds its place in the current document. Cool!
  • COM integration: COM support in out-of-browser mode can lead us to achieving some very powerful interaction with the programs on the user machine. We can now access a SQL server database residing on user’s computer, we can now open a certain document in user’s MsProject app, and many more. For some insight, have a look at Justin’s wonderful post here.
  • MEF support: Now our Silverlight apps are extendable via MEF which is really cool.
  • Right click support: A perfect feature for our interactive applications, we now can control the context menu items as well.
  • Desktop Notifications: The Silverlight application can now show Taskbar notifications as well.
  • ICommand support : A great feature for MVVM lovers, we now have commanding support for in XAML without requiring any external MVVM framework.
  • Printing support: We can even control printing from our Silverlight application.

DLR and dynamic keyword
The CLR (Common Language Runtime) is now accompanied with DLR (Dynamic Language Runtime) in .NET Framework 4. This is going to allow easy interaction with dynamic languages and COM objects without explicitly using the reflection methods. More on this on this MSDN doc: DLR Overview.

Code contracts
This is a great enhancement for our architects who are always cautious about design principles. The new version of .NET now support specifying pre-conditions, post-conditions, and object invariants. This can result in improved testing and better contract verification in design-by-contract programming. More info on this MSDN doc: Code Contracts.

Optional Parameters
Like Visual Basic, we are getting support for optional parameters in C# with .NET 4. Although this is a debatable topic but it can be helpful in cases where we needed to develop several overloads of a single method. More on this topic in this MSDN doc: Named and Optional Arguments.

That’s all. These were my initial thoughts on the new features of .NET Framework. The full official list of the new enhancements can be viewed on MSDN here. Of course, the views and opinions will get richer by the passage of time when we start building our application in .NET 4. So let’s download Visual Studio 2010 RC from here and start enjoying the new features. Happy programming!

Article Posted: AutoCompleteComboBox for Silverlight

I have posted an article at CodeProject on customization of the Silverlight AutoCompleteBox to be used as a type-ahead ComboBox in LOB applications at CodeProject. The AutoCompleteComboBox can be used in typical Object-to-Object associations (one that we typically encounter when creating associations in Entity Framework) as well as Foreign Key associations (the new association type introduced with Entity Framework 4).

Here’s a sample usage of the control in a typical MVVM scenario:

  • Object to Object Association:

    Example data structure:

    public class SalesOrderDetail
    {
        Product product;
        public Product Product
        {
            get { return product; }
            set { product = value; }
        }
    }
    

    Example control usage:

     <custom:AutoCompleteComboBox
       SelectedItemBinding="{Binding Product, Mode=TwoWay}"
       ItemsSource="{Binding Path=Products, Source={StaticResource ViewModel}}"
     />
    
  • Foreign Key Association:

    Example data structure:

    public class SalesOrderDetail
    {
        int productID;
        public int ProductID
        {
            get { return productID; }
            set { productID = value; }
        }
    }
    

    Example control usage:

     <custom:AutoCompleteComboBox
       SelectedValue="{Binding ProductID, Mode=TwoWay}"
       SelectedValuePath="ProductID"
       ItemsSource="{Binding Path=Products, Source={StaticResource ViewModel}}"
     />
    

To view the implementation details, you can read the full article at :
http://www.codeproject.com/KB/silverlight/AutoComplete_ComboBox.aspx

The source code along with a demo project can be downloaded from the article as well as here (28 KB). Remember to rename the file as zip for extraction.

Silverlight: Update service reference for a WCF service generating empty class

My Visual Studio sometimes goes angry. I had a Silverlight 2 – WCF – LINQToSQL application that I recently converted to Silverlight 3. I noticed that sometimes the Update Service Reference does not function properly and instead blanks out the generated reference.cs. It broke once again today and I decided to blog it. Here are the contents of Error window when such abnormal activity happens:

Custom tool error: Failed to generate code for the service reference '..'.  Please check other error and warning messages for details.

The warning tab may have many warnings, some of which are:

Custom tool warning: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Custom tool warning: The type 'System.Collections.ObjectModel.ObservableCollection`1' could not be found.  Ensure that the assembly containing the type is referenced.  If the assembly is part of the current development project, ensure that the project has been built.

Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Exception has been thrown by the target of an invocation.
XPath to Error Source: //wsdl:definitions[@targetNamespace='']/wsdl:portType[@name=..]

Custom tool warning: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='..']/wsdl:binding[@name='..']

Custom tool warning: No endpoints compatible with Silverlight 3 were found. The generated client class will not be usable unless endpoint information is provided via the constructor.

Ok. Looks like something is wrong with the Observable Collection reference. This was further confirmed when I brought up the service configuration window (by right clicking the WCF service and selecting Configure Service Reference), and noticed that the ObservableCollection collection type has been replaced by { Custom } :

service-reference-incorrect

For comparison, here’s the normal screenshot for this window:

service-reference-correct

To get rid of this and regenerate service proxy properly, I had to remove the Reuse types in all referenced assemblies (or at least System assembly).

So, if such behavior ever happen to you, try to update the service reference after unchecking the reuse types checkbox. Once done, you can recheck the option and update your service reference again.

Avoiding hard-coded strings while raising or handling PropertyChanged event

While developing WPF/Silverlight applications, and more specifically while following the Model-View-ViewModel (MVVM) pattern we will find ourselves implementing INotifyProprertyChanged most of the times. The default implementation of PropertyChanged event takes the property name as string in the PropertyChangedEventArgs which is not much robust. There are several ways to address the issue:

  • Use reflection to verify that the property actually exists, as demonstrated once by Josh Smith.
  • Use Injection using some Aspect Oriented Programming framework, like PostSharp
  • Use Expression Trees as described by Michael Sync and Davy Brion

Personally, I prefer using expression trees. So, instead of writing this:

public string MyProperty
{
    get { return this.myProperty; }
    set { this.myProperty = value; this.RaisePropertyChanged("MyProperty"); }
}

We can write:

public string MyProperty
{
    get { return this.myProperty; }
    set { this.myProperty = value; this.RaisePropertyChanged( MyObj => MyObj.MyProperty ); }
}

The same issue exists looking at the other side. When we subscribe to PropertyChanged event of an object, we get the property name again as a string. One way is to use the GetPropertyName( ExpressionTree ) extension method from the above implementation in our if and case statements. Also, Josh nicely addressed the issue in this post, thus allowing us to write:

MyClass myObject = new MyClass();
PropertyObserver<MyClass> observer = new PropertyObserver<MyClass>(myObject)
    .RegisterHandler(myObj => myObj.MyProperty1, myObj => { /* handle change in MyProperty1 */ })
    .RegisterHandler(myObj => myObj.MyProperty2, MyProperty2HandlerMethod  );

Notice that Josh used IWeakEventListener that isn’t available for Silverlight but luckily Pete O’ Hanlon provided us with a Silverlight version of Josh’s work here.

So, combining the great efforts of all these people, we are going to have a better MVVM experience.

RIA Services: Working with Foreign Keys/Associations in Entity Framework

Yesterday, I got an strange observation regarding RIA Services. I needed to created an Entity Model from views instead of tables so it had no foreign key associations defined. I manually created the associations and was finally able to get a working model. I then added a RIA Domain Service and got the following error upon build:

“Unable to retrieve AssociationType for association ‘JobWBS_ResourceAssignment'”

Strange. But after some effort I came to know that the current(July 2009) preview of RIA services expects all the associations in the default foreign key naming convention, i.e., FK_ForeignKeyTable_PrimaryKeyTable. In my case, I had a 1-Many relationship between JobWBS and ResourceAssignment so I changed the association name to FK_ResourceAssignment_JobWBS and the project built successfully.

Update: If you are still not able to get rid of the error. Its probably because your SSDL schema does not have the proper associations defined. Have a look at this post on how to manually define associations in the physical (storage) model.

IValueConverters: A great tool in developing WPF/Silverlight applications

IValueConverters in WPF/Silverlight are a very powerful tool in UI presentation, especially, when following the MVVM pattern. In MVVM, where everything in the View is bounded to some property from ViewModel, IValueConverters come handy because often the properties in the ViewModel do not necessarily return the same data type that the View needs. For instance, we can have a boolean IsVisible property in the ViewModel but the UI controls need a Visibility enumeration (with values Visibility.Collapsed and Visibility.Visible) to properly consume it. The great thing about IValueConverters is that they take an object and return an object, so its upto the innovation of developer to make the most out of them.

In this post, I will be demonstrating the powers of IValueConverters by representing a simple boolean variable, that has just two possible values, in several ways. Here’s a screenshot from the application. The bindings in the left column are two way, thus the change in any one of the controls is immediately reflected in the whole view. Have a look:

ivalueconvertersdemo

The ViewModel class exposes only one boolean property to the View. Here’s the code:

public class SampleViewModel : System.ComponentModel.INotifyPropertyChanged
{
    bool boolProperty;

    public bool BoolProperty
    {
        get { return boolProperty; }
        set { boolProperty = value; RaisePropertyChanged("BoolProperty"); }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

}

The View consumes the boolean property using:

  • Default Boolean To String Converter (with Values = True, False)
  • Boolean to String Converter (with values = Yes, No)
  • Boolean to String Converter (with values = Start, Stop)
  • Boolean to Brush Converter (with colors Green, Red)
  • Boolean to Opacity Converter (with opacity 100%, 10%)
  • Boolean to FontStyle Converter (with styles Normal, Italic)
  • Boolean to Visibility Converter

Here’s the code for the View:

<UserControl x:Class="IValueConvertersDemo.View.SampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:IValueConvertersDemo.ViewModels"
    xmlns:converter="clr-namespace:IValueConvertersDemo.Converters"
    >
    <UserControl.Resources>
        <vm:SampleViewModel x:Key="ViewModel" BoolProperty="True" />
        <converter:BoolToColorConverter x:Key="BoolToColorConverter" />
        <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        <converter:BoolToStringConverter x:Key="BoolToStringConverter" />
        <converter:BoolToDoubleConverter x:Key="BoolToDoubleConverter" />
        <converter:BoolToFontStyleConverter x:Key="BoolToFontStyleConverter" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Margin="10" HorizontalAlignment="Left">
            <TextBlock Margin="10" FontSize="18" Text="Two-way" />
            <CheckBox Margin="10" Content="BoolProperty" IsChecked="{Binding BoolProperty, Mode=TwoWay}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay, Converter={StaticResource BoolToStringConverter}, ConverterParameter='Yes,No'}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay, Converter={StaticResource BoolToStringConverter}, ConverterParameter='Start,Stop'}" />
        </StackPanel>

        <StackPanel Grid.Column="1"  Margin="10">
            <TextBlock Margin="10" FontSize="18" Text="One-way" />
            <StackPanel Margin="10" Orientation="Horizontal">
                <Ellipse Height="50" Width="50" Fill="{Binding BoolProperty, Converter={StaticResource BoolToColorConverter}}" HorizontalAlignment="Left" />
                <TextBlock Margin="5" VerticalAlignment="Center" Text="Color(Green/Red) depending on bool property" />
            </StackPanel>
            <StackPanel Margin="10" Orientation="Horizontal">
                <Rectangle Fill="Blue" Height="50" Width="50" Opacity="{Binding BoolProperty, Converter={StaticResource BoolToDoubleConverter}}" HorizontalAlignment="Left" />
                <TextBlock Margin="5" VerticalAlignment="Center" Text="Opacity(100%/10%) depending on bool property" />
            </StackPanel>
            <TextBlock Margin="10" Text="Fontstyle(Normal/Italic) depending on bool property" FontStyle="{Binding BoolProperty, Converter={StaticResource BoolToFontStyleConverter}}" />
            <TextBlock Margin="10" Text="This text is visible only if bool value is true" Visibility="{Binding BoolProperty, Converter={StaticResource BoolToVisibilityConverter}}" />
        </StackPanel>

    </Grid>
</UserControl>

Notice that a boolean variable can only be assigned two values: True and False. Yet, still, we are able to use that in several different ways. Thus IValueConverters provide endless possibilities in WPF data presentation. Its only upto the brain of developer how to exploit them.

The sourcecode for the various converters is included with the sample application that can be downloaded here. Make sure you rename the file to .zip for extraction.

Beginning MVVM: The Basics

WPF and Silverlight experts talk a lot about the new Model-View-ViewModel pattern these days. The powerful databinding support in WPF framework provides the basis for MVVM pattern. In this post, I will be highlighting some points that beginners may need to know to start learning MVVM.

To start with MVVM, you must know the basics of WPF/Silverlight databinding and how to data-bind controls using XAML constructs. The thing to note is that if you data-bind a UI control to an object (using the DataContext dependency property), then all of the public properties of that data-object are available to the child controls. In MVVM, the view (a UI control/page) is data-bound to a ViewModel (a simple C# class). The ViewModel exposes all the data and commands the View needs via properties. The View, then declaratively binds its UI controls to corresponding properties and commands of the ViewModel via XAML constructs.

As concepts are more clarified through examples, I am presenting a very simple example. Lets build a Silverlight MVVM version for this UI:
mvvm-picture1

The Listbox presents a list of persons and the right section presents the details of a selected person. To start with MVVM, we will make a ViewModel class containing two properties: a PersonList property that will be providing list of persons for the Listbox, and a SelectedPerson property that will contain the reference to the selected person. Here’s a crud implementation for the class:

public class PersonViewModel : System.ComponentModel.INotifyPropertyChanged
{
    ObservableCollection<Person> personList;
    Person selectedPerson;

    public PersonViewModel()
    {
        //populate some sample data
        personList = new ObservableCollection<Person>()
        {
            new Person(){Name="Syed Mehroz Alam", Age=10, City="Karachi", Country="Pakistan"},
            new Person(){Name="Zinedine Zidane", Age=20, City="Marseille", Country="France"},
            new Person(){Name="Ronaldinho", Age=30, City="Porto Alegre", Country="Brazil"},
            new Person(){Name="John Smith", Age=40, City="Washington", Country="USA"}
        };
    }

    #region Properties

    public ObservableCollection<Person> PersonList
    {
        get { return personList; }
    }

    public Person SelectedPerson
    {
        get { return selectedPerson; }
        set
        {
            selectedPerson = value;
            RaisePropertyChanged("SelectedPerson");
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

Now we have this View-Model ready to be consumed by a View. So in a new UserControl, we will instantiate the ViewModel class through XAML in the resources section and will data-bind the View to it using DataContext property of the main control of the View, in our case, a Grid named LayoutRoot. Since the LayoutRoot is data-bound to the ViewModel class, we can use its public properties as the DataSources of our other controls in the View. For our example, we will assign Listbox’s ItemSource to ViewModel.PersonList property and Listbox’s SelectedItem to ViewModel.SelectedPerson property. The right section will be bound to the SelectedPerson and will contain TextBoxes for displaying details of that person. Here’s the XAML code:

<UserControl x:Class="MVVMExample1.View.PersonView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewmodel="clr-namespace:MVVMExample1.ViewModel"
    >
    <UserControl.Resources>
        <viewmodel:PersonViewModel x:Key="ViewModel" />
    </UserControl.Resources>

    <!-- Databind the root control to the ViewModel class -->
    <!-- This way, all the public properties of ViewModel class become available to us -->
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource ViewModel}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <!-- The listbox gets its ItemSource from ViewModel.PersonList property -->
        <!-- Also, the SelectedItem is bound to ViewModel.SelectedPerson property -->
        <ListBox Grid.Column="0" Margin="5"
                 ItemsSource="{Binding PersonList}"
                 DisplayMemberPath="Name"
                 SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"
                 />

        <!-- Databind the right section to ViewModel.SelectedPerson property -->
        <Grid x:Name="PersonDetails" Grid.Column="1" DataContext="{Binding SelectedPerson}" Margin="5" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="Person Details" FontSize="15" />

            <TextBlock Grid.Row="1" Grid.Column="0" Text="Name" />
            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name, Mode=TwoWay}" />

            <TextBlock Grid.Row="2" Grid.Column="0" Text="Age" />
            <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Age, Mode=TwoWay}" />

            <TextBlock Grid.Row="3" Grid.Column="0" Text="City" />
            <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding City, Mode=TwoWay}" />

            <TextBlock Grid.Row="4" Grid.Column="0" Text="Country" />
            <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding Country, Mode=TwoWay}" />
        </Grid>

    </Grid>
</UserControl>

That’s all, our sample application is ready to be run. Observe how selecting a person updates the person details section. Also observe that the databindings are TwoWay and changing the name of a person in the details section is reflected in the ListBox panel as well.

Note that in Silverlight, we do not have built-in support for commands and triggers like WPF. So in order to execute some code upon a button click, we will either need manual hooking of the button’s Click event, a separate third party extension(e.g. SLExtensions, Prism or SilverlightFX) or make our own implementation. More on this in some later post.

Notice that MVVM seems difficult at first, but as soon as you create your first UI using this pattern, you will find yourself thinking your application in terms of Dependency Properties and IValueConverters. Beware, MVVM is quite addictive. Karl Shifflett presents some great MVVM resources on this page. Be sure to bookmark that page for new MVVM stuff.

The source code for the example UI we discussed can be downloaded here. The file needs to be renamed to .zip for extraction. This is “WordPress File Download Pattern” 🙂

Saving data-objects to Isolated Storage in Silverlight

If you are developing an enterprise Silverlight application you will typically need to cache your business entities in the isolated storage. There are two apparent choices for this:

1. Use the powerful Linq-To-XML API from System.Xml.Linq namespace. This method is to be used when you want to have a fine grain control over serialization (e.g. you want to store some properties of the data objects).

2. Use the built-in DataContractSerializer class. This method is very simple and the only thing it requires is that our business objects need to have the [DataContract] and [DataMember] attributes. In this post, I am going to discuss this second method.

In an enterprise LOB (line of business) application, our business objects will typically be retrieved via WCF service and hence will already have the [DataContract] and [DataMember] attributes marked on them. So we can directly use the built-in DataContractSerializer to store them to, and later retrieve them from, the isolated storage. Here’s a generic class to simplify the process:

public static class IsolatedStorageCacheManager<T>
{
    public static void Store(string filename, T obj)
    {
        IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication();
        using (IsolatedStorageFileStream fileStream = appStore.OpenFile(filename, FileMode.Create))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T));
            serializer.WriteObject(fileStream, obj);
        }
    }
    public static T Retrieve(string filename)
    {
        T obj = default(T);
        IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication();
        if (appStore.FileExists(filename))
        {
            using (IsolatedStorageFileStream fileStream = appStore.OpenFile(filename, FileMode.Open))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                obj = (T)serializer.ReadObject(fileStream);
            }
        }
        return obj;
    }
}

Using the above code is really simple. Just add the class to your project and use it like this:

//for storing and retrieving a single object
Person myPersonObj = GetPerson();
IsolatedStorageCacheManager<Person>.Store("myfile.xml", myPersonObj);
Person myPersonObj2 = IsolatedStorageCacheManager<Person>.Retrieve("myfile.xml");

//for storing and retrieving a collection of objects
List<Person> myPersonList = GetPersonList();
IsolatedStorageCacheManager<List<Person>>.Store("myfile.xml", myPersonList);
List<Person> myPersonList2 = IsolatedStorageCacheManager<List<Person>>.Retrieve("myfile.xml");

Hope you will find this implementation useful.