Archive of entries posted by Sergey Barskiy

Modular Silverlight Development, App.xaml, Blend and Resources

As I was working on one of my personal learning projects, I encountered a small problem. The project was Prism based with multiple modules.  I wanted to isolate my resource files, so I created a separate project that included my XAML resources, such as styles.  This approach works just fine by using merged dictionaries in App.xaml:

<Application 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   x:Class="MyApp.Silverlight.App"
            >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 

Now I can reference those resource in my other modules’ screens and use them.  Now back to the original issue.  I can use styles from MyResourceDictionary.xaml, but Blend generates an error for me – it cannot find my resources.  Here is an easy way to overcome this issue.  You have to add the same dictionary into the resources of each screen:  In the example below I am showing resources area for a user control called MySampleView from MyApp module.,

    <MyApp:MySampleView.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <resource:Resource x:Key="LocalizedResource"/>
        </ResourceDictionary>
    </MyApp:MySampleView.Resources>

As you can see, I combine the styles dictionary with a local resource, in example localized user strings.  You can just as easily add converters, etc… in the same fashion.

There is some cost of course associated with merging dictionaries into each screen, but using Blend is a big benefit.  You can get around this issue by keeping this code commented out, and uncomment when using Blend

There is also another solution, involving having #DEBUG that moves this exact code into code behind of each view.  Of course, this is annoying as well, and this is when the base class for the view comes in.  Here is the code I could add to it to accomplish the same as XAML approach:

#if DEBUG
            var dictionary = new ResourceDictionary() 
                { Source = new Uri("/MyResources.Silverlight.Common;component/Resources/MyResourceDictionary.xaml", UriKind.RelativeOrAbsolute) };
            Resources.MergedDictionaries.Add(dictionary);
#endif

 

This of course underscores the usefulness of having base classes for all your major components, such as views in your applications.  It could be an inconvenience since you cannot just add new user control.  You would have to edit both XAML and code behind to change the inheritance structure of your user controls (views).

<MyApp:MySampleViewBase
   x:Class="MyApp.Views.MySampleView"

public partial class MySampleView : MySampleViewBase, IMySampleView

 

You can further optimize this process by creating custom control templates that would write all this code for you.  This way you would not have to modify the files after creating a new user control.

Thanks.

Encryption in Silverlight and .NET Applications

Today I would like to cover a specific use case that came up a few times in Silverlight applications I wrote.  For example, I wand a user to enter some sensitive information, encrypt it in Silverlight client, transfer it over to the server, then decrypt it and perforation some operations on that data.

First step of course is to find sufficiently strong encryption protocol that can be implemented in both Silverlight and .NET and be completely compatible between both run times.  I am going to go for AES encryption.  AES stands for “Advanced Encryption Standard”.  This standard is widely used and approved by US government and standard bodies.  See this article for details.

Luckily, AES encryption is implemented in both Silverlight and .NET run times, using exact same set of classes, primary one being AesManaged class.  My goal is to create a class that I can cross-compile in both runt times, so this comes in super handy.  Second, I wand to implement two methods Decrypt and Encrypt, while paying attention to IDisposable interfaces that the vast majority of classes inside Cryptography namespace implement.  Both static methods take two parameters, input string and a password to be used.  Of course, you have to make sure you use the same password in both methods while encrypting and decrypting information.  You should probably dynamically generate a password during handshake process between a Silverlight client and a .NET server.  I will also use maximum key size and block size of encryption.  I will also dynamically generate key (Key) and initialization vector(IV) properties.    I am going to now spare everyone a number of boring details, and will simply post final version of my utility class:  You can include this class in both .NET and Silverlight project, and even link the physical .cs file from one to the other to ensure that you only have a single version in source control.

Thanks

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
 
namespace Encryption
{
    public static class EncryptionUtility
    {
 
        /// <summary>
        /// Encrypt the data
        /// </summary>
        /// <param name="input">String to encrypt</param>
        /// <returns>Encrypted string</returns>
        public static string Encrypt(string input, string password)
        {
 
            byte[] utfData = UTF8Encoding.UTF8.GetBytes(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string encryptedString = string.Empty;
            using (AesManaged aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
 
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform encryptTransform = aes.CreateEncryptor())
                {
                    using (MemoryStream encryptedStream = new MemoryStream())
                    {
                        using (CryptoStream encryptor = 
                            new CryptoStream(encryptedStream, encryptTransform, CryptoStreamMode.Write))
                        {
                            encryptor.Write(utfData, 0, utfData.Length);
                            encryptor.Flush();
                            encryptor.Close();
 
                            byte[] encryptBytes = encryptedStream.ToArray();
                            encryptedString = Convert.ToBase64String(encryptBytes);
                        }
                    }
                }
            }
            return encryptedString;
        }
 
        /// <summary>
        /// Decrypt a string
        /// </summary>
        /// <param name="input">Input string in base 64 format</param>
        /// <returns>Decrypted string</returns>
        public static string Decrypt(string input, string password)
        {
 
            byte[] encryptedBytes = Convert.FromBase64String(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string decryptedString = string.Empty;
            using (var aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform decryptTransform = aes.CreateDecryptor())
                {
                    using (MemoryStream decryptedStream = new MemoryStream())
                    {
                        CryptoStream decryptor = 
                            new CryptoStream(decryptedStream, decryptTransform, CryptoStreamMode.Write);
                        decryptor.Write(encryptedBytes, 0, encryptedBytes.Length);
                        decryptor.Flush();
                        decryptor.Close();
 
                        byte[] decryptBytes = decryptedStream.ToArray();
                        decryptedString = 
                            UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
                    }
                }
            }
 
            return decryptedString;
        }
    }
}

XAML Intellisense Stops Working in Visual Studio 2010

Today as I was working on a Silverlight application in Visual Studio 2010, XAML Intellisense just stopped working for me.  Quick internet search yielded no useful results, so I was to figure this out on my own.  Just to test I created a brand new application, and Intellisense was fine there.  Logical answer was that there was something wrong with my project.  I re-created the project, and slowly retraced my steps, testing XAML Intellisense  after each step.  The feature broke again as soon as I added a reference to  third party library I downloaded off the internet.  Something wrong with a file, obviously.  What I saw is that the DLL in question was blocked by Windows security.  I unblocked by right-clicking on the file in Windows explorer, going to properties and clicking Unblock button.

The package that I downloaded included many files, and I really hated to go through each one. Next internet search yielded a great solution from SysInternals.  You can download it here.  Once I got streams utility, I ran it on entire folder, and voila – Intellisense was back.  The command line is “streams –s –d ‘Folder with DLLs to Unblock’”, in my case “streams –s –d “c:\ThirdParty””

So, my research solved two problems for me – missing XAML Intellisense  and ability to unblock multiple files which is something I wanted to find an answer to a while ago,

Unit Testing Silverlight Applications – UI testing and Test Automation

In my last post I am going to cover the last two topics I set out to address.  The first topic is UI testing.  What unit test frameworks lack sometime is the actually UI testing.  What I mean by that is for example, click on a button, then see what happens.  In case of Silverlight, Silverlight framework itself has a number of helper classes to help us achieve this goal.  For example, ButtonAutomationPeer class allows us to drive button actions from within unit tests.  Also, Microsoft Silverlight unit testing framework allows developers to insert UI components onto unit testing surface.  Let me illustrate both concepts via an example.  Here is my code for such unit test”

[TestMethod]
[Asynchronous]
[Description("Asynch Get Companies in UI")]
[Tag("Asynch")]
public void TestUIGetCompanies()
{
 
    var companyVM = new CompanyModule.ViewModels.CompanyListViewModel(
        new Microsoft.Practices.Composite.Events.EventAggregator());
    CompanyListView companyV = new CompanyListView();
    companyV.DataContext = companyVM;
    TestPanel.Children.Add(companyV);
    ButtonAutomationPeer buttonPeer = 
        new ButtonAutomationPeer(companyV.FindName("GetCompaniesButton") as Button);
    DataGrid grid = companyV.FindName("CompanyGrid") as DataGrid;
    IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;
 
    IGridProvider gridPeer = new DataGridAutomationPeer(grid);
 
    EnqueueCallback(() => buttonInvoker.Invoke());
    EnqueueConditional(() => { return companyVM.CompanyList != null; });
    EnqueueCallback(
        () => Assert.IsTrue(companyVM.CompanyList.Count() > 0, "Should have data"),
        () => Assert.IsTrue(grid.Columns.Count == 3, "Should have 3 columns"),
        () => Assert.IsTrue(gridPeer.RowCount > 0, "Should have rows"));
    EnqueueTestComplete();
}

 

Let’s trace down what is going on in this test.  First of all, I am creating view model class.  Since I do not have a bootstrapper, I manually create EventAggregator myself.  Next, I am create a view to put my view model into.  I create view, then put my view model into the data context of my view.  Nest important step is to add my view to unit te3swt harness.  This is accomplished by adding my view to test panel.  My screenshot below illustrates where test panel is in terms of test runnier UI.  I added hand cursor to illustrate the test panel referred to in UI below as “Test Stage.”  As I run the unit tests, I will actually see my view there in the test stage.  Just like I added the view, I can remove it from test stage.

image

Next I am setting up code to invoke a button.  I am creating new instance of ButtonAutomationPeer class.  Of course, I need to find a button to attach the automation peer to, and I am using FindName method to find an i9nstance of my button.  To use this functionality I had to name my button.  Then, I am setting up an automation peer for my grid as well.  In general, most user input controls in Silverlight framework have matching automation objects.  In my case, I am testing the results of my button invocation directly against the grid, making sure that the grid has correct number of rows and columns.  I can also combine this type of testing with mocking,  Here is the unit test for this case:

[TestMethod]
[Asynchronous]
[Description("Asynch Get Companies in UI With Mocking")]
[Tag("Asynch")]
public void TestUIGetCompaniesWithMock()
{
    var companyVM = new Mock<ICompanyListViewModel>();
    companyVM.SetupGet(testVM => testVM.CompanyList).
        Returns(new ObservableCollection<Company>(new[] {
        new Company(){
            CompanyID = Guid.NewGuid(), DateAdded = DateTime.Now, CompanyName = "some random company"},
        new Company(){ 
            CompanyID = Guid.NewGuid(), DateAdded = DateTime.Now.AddDays(-1), CompanyName = "another company"}}));
    companyVM.SetupGet(testVM => testVM.GetCompaniesCommand).
        Returns(new DelegateCommand<object>((o) =>
        companyVM.Raise(vm => 
            vm.PropertyChanged += null, new System.ComponentModel.PropertyChangedEventArgs("CompanyList"))));
 
 
    CompanyListView companyV = new CompanyListView();
    companyV.DataContext = companyVM.Object;
    TestPanel.Children.Add(companyV);
    ButtonAutomationPeer buttonPeer = new ButtonAutomationPeer(companyV.FindName("GetCompaniesButton") as Button);
    DataGrid grid = companyV.FindName("CompanyGrid") as DataGrid;
    IInvokeProvider buttonInvoker = (IInvokeProvider)buttonPeer;
 
    IGridProvider gridPeer = new DataGridAutomationPeer(grid);
 
    EnqueueCallback(() => buttonInvoker.Invoke());
            
    EnqueueCallback(
        () => Assert.IsTrue(companyVM.Object.CompanyList.Count() > 0, "Should have data"),
        () => Assert.AreEqual(3, grid.Columns.Count, "Should have 3 columns"),
        () => Assert.AreEqual(2, gridPeer.RowCount, "Should have rows"));
    EnqueueTestComplete();
}

 

In the case above I am mocking property changed event by invoking it when a button is clicked, causing UI to re-bind.  The rest of testing code is very similar to actual invocation of server side code.

The last topic I would like to cover is StatLight framework.  You can take a closer look at the framework here.  This framework allows developers to invoke unit tests written with Microsoft unit testing framework for Silverlight from a command line and also read in results of such runs.  Once you download and unzip the DLLs into a folder, you will need to do one more thing – Unblock those DLLs in the properties of each file in Windows explorer.  Also, if you want to test server side code using StatLight, you will need to convert your web site to use local IIS inste4ad of Cassini (Visual Studio built-in IIS Server).  You will also need to put clientaccesspolicy.xml into the root of your IIS in order to avoid cross domain exceptions.  Using the StatLight framework is very simple.  Simply call StatLight.exe and pass XAP file on command line that contains your unit tests.  Here is a screenshot of what it looks like:

image 

As you can see, your –x parameter is the only one you have to specify to test.  You will also see that unit test is launched at the same time.  Now, to test results you have to add one more parameter – r.  Here is what that command would look like:

image

Once you run this, you will end up with out.txt in the specified folder.  Here is the content of this file:

image

The last parameter I want to mention is ability to limit test run by tag attribute I covered in an earlier post.  To user this feature, you have to add –t command line attribute like so:  Here is what this command line look like:

image

You can download complete solution here.

Thanks.

Windows Phone 7 Beta is here

Windows Phone 7 Developer tool beat has been released by Microsoft.  You can download it here.
Make sure to download and read release note available on the page above.

 

Thanks.

Unit Testing Silverlight Applications – Mocking

In this post I will explore ability to mock various Silverlight classes in order to enable mocking in your unit tests.  There is a variety of mocking frameworks available, but I will pick one for my testing – Moq.  You can download the framework here,  Once this is done, I need to add some references to my Silverlight unit test project.

Moq requires three assemblies available in the folder where Moq is installed:

image

If we are mocking view model or another object relying on Prism, we also need to add Prism references

image

Now we are ready to mock!

Let’s start by doing something simple.  I will mock my view model.  The only property I really want to test is my model property, which in my case exposes list of companies.  TO do so, I just need to setup property getter that contains my model.  The getter will be called when first accessed.  Here is what we have:

[TestMethod]
[Tag("Mocking")]
[Description("VM Mocking")]
public void TestMocking()
{
    var vm = new Mock<ICompanyListViewModel>();
    vm.SetupGet(testVM => testVM.CompanyList).
        Returns(new ObservableCollection<Company>(new[] {
            new Company()
                { CompanyID = Guid.NewGuid(), DateAdded = DateTime.Now, CompanyName = "some random company"},
            new Company()
                { CompanyID = Guid.NewGuid(), DateAdded = DateTime.Now.AddDays(-1), CompanyName = "another company"}}));
    Assert.AreEqual(2, vm.Object.CompanyList.Count, "Mocking failed");
 
}

 

I am only mocking view model in this case.  With Moq framework, as it is the case with most mocking frameworks, you are required to have interfaces in order to mock.  In case of RIA Services, this is an issue because client side classes are sealed and do not implement interfaces.  If you are using your own WCF service with custom classes, you can avoid this small issue.  You can also mock events as well.  This is how I would mock property changed event in my view model:

companyVM.SetupGet(testVM => testVM.GetCompaniesCommand).Returns(new DelegateCommand<object>((o) =>
    companyVM.Raise(vm => vm.PropertyChanged += null, new System.ComponentModel.PropertyChangedEventArgs("CompanyList"))));

 

As you can see, mocking is pretty easy concept, and the web page for Moq has quick start guide to help you get started.  Feel free to use a different mocking framework as well.  In the next post I will show how to unit test user interface using Silverlight unit testing framework.

Thanks

Unit Testing Silverlight Applications – Asynchronous Testing

In this post I will describe how to create asynchronous unit tests for Silverlight applications.  First of all, I’d like to point out that any communication with a server component in Silverlight must be asynchronous.  Reason being is that if communication was synchronous and the remote service was not responding, browser which host Silverlight application would lock up.  As you can see, asynchronous communication with a RIA Services WCF service is very important in our case. 

Let’s take a look on how to write a test that would assert that we can successfully get a list of companies from the server.  To do so, we must first take a look on how to write such a test.  This can be accomplished using asynchronous constructs available in Silverlight unit testing framework.  First of all, we have to change inheritance for our test class.  When you create a new test class, it does not inherit from any class, and we have to change this first of all.  Here is what old test class declaration look like:

[TestClass]
public class Tests

Here is what we are going to change it to:

[TestClass]
public class Tests : Microsoft.Silverlight.Testing.SilverlightTest

Now we must decorate our test method with appropriate attribute to signal to test running harness that it is about to execute asynchronous test:

[TestMethod]
[Asynchronous]
[Description("Asynch Get Companies")]
[Tag("Asynch")]
public void TestGetCompanies()

Now, let take a deeper look into framework itself to see the key methods that we can use in base class – SilverlightTest.

First one is EnqueueConditional.  This method is designed to let unit test wait until condition specified as an argument to EnqueueConditional is met.  It is very useful when you want to wait until a method call to the service is completed.  Here is how I would use this method:

        [TestMethod]
        [Asynchronous]
        [Description("Asynch Get Companies")]
        [Tag("Asynch")]
        public void TestGetCompanies()
        {
            bool isLoaded = false;
            Exception error = null;
            IEnumerable<Company> results = null;
            CompanyDomainContext context = new CompanyDomainContext(new Uri(@"http://localhost:4988/SilverlightTestingDemo-Web-CompanyDomainService.svc", UriKind.Absolute));
            var query = context.GetCompaniesQuery();
 
            context.Load<Company>(query, (result) =>
            {
                isLoaded = true;
                results = result.Entities;
                error = result.Error;
            }, null);
            EnqueueConditional(() => isLoaded);

 

What I am doing above is declaring a Boolean variable isLoaded that would signal to the framework to continue the test once data has been loaded.  I am setting this variable to true in the lambda expression callback that is called one server method’s execution is completed – (result)=> expression.

Next interesting method is EnqueueCallback.  This method simply declares multiple or in Action delegates that will be executed one they are popped off execution stack when harness processes test method calls.  What I mean is that the harness will execute all Action delegates that EnqueueCallback declares when it proceeds with running a test method once condition that  EnqueueConditional declares is met. If there are no such calls in the method body and there are no calls to EnqueueDelay that would also pause execution, then EnqueueCallback has no meaning, and asynchronous test essentially becomes synchronous.  Here is what we have so far:

        [TestMethod]
        [Asynchronous]
        [Description("Asynch Get Companies")]
        [Tag("Asynch")]
        public void TestGetCompanies()
        {
            
            bool isLoaded = false;
            Exception error = null;
            IEnumerable<Company> results = null;
            CompanyDomainContext context = new CompanyDomainContext(new Uri(@"http://localhost:4988/SilverlightTestingDemo-Web-CompanyDomainService.svc", UriKind.Absolute));
            var query = context.GetCompaniesQuery();
 
            context.Load<Company>(query, (result) =>
            {
                isLoaded = true;
                results = result.Entities;
                error = result.Error;
            }, null);
            EnqueueConditional(() => isLoaded);
            EnqueueCallback(
                () => Assert.IsTrue(results.Count() > 0, "Should have data"),
                () => Assert.IsNull(error, "Should have no errors"));

 

The last important method is EnqueueTestComplete.  This method puts Test Completed signal onto the execution stack. This method is typically the very last statement of the test method body.  Here is our final version of the method:

        [TestMethod]
        [Asynchronous]
        [Description("Asynch Get Companies")]
        [Tag("Asynch")]
        public void TestGetCompanies()
        {
            
            bool isLoaded = false;
            Exception error = null;
            IEnumerable<Company> results = null;
            CompanyDomainContext context = new CompanyDomainContext(new Uri(@"http://localhost:4988/SilverlightTestingDemo-Web-CompanyDomainService.svc", UriKind.Absolute));
            var query = context.GetCompaniesQuery();
 
            context.Load<Company>(query, (result) =>
            {
                isLoaded = true;
                results = result.Entities;
                error = result.Error;
            }, null);
            EnqueueConditional(() => isLoaded);
            EnqueueCallback(
                () => Assert.IsTrue(results.Count() > 0, "Should have data"),
                () => Assert.IsNull(error, "Should have no errors"));
            EnqueueTestComplete();
        }

 

You can download the complete code here.  In the next post I will cover mocking for synchronous and asynchronous unit tests.

Thanks..

Unit Testing Silverlight Applications

I am starting a short series of posts on unit testing of Silverlight applications.  I will be using the following set of technologies. 

  • Microsoft Silverlight Unit testing framework that ships with Silverlight tool kit
  • Moq – mocking framework that supports Silverlight 4
  • StatLight – unit testing automation framework that will allow for unattended / automated running unit tests

I am going to start with a simple Silverlight application that is using RIA services and Prism.  First things first, let’s create unit test project.  Project template will be installed when you install the Silverlight toolkit.  Here is what add project dialog looks like.  The template is located under Silverlight tab

image

Here are the setting for the next dialog:

image

Once project is created, a simple test class is also created.  If you ever worked with Microsoft unit testing in Visual Studio, you will find the API quite familiar, including all key classed, attributes and namespaces.  I am going to create a simple synchronous test first, testing my RIA services class to ensure that validation rules are setup properly.  To do so, I first add a reference to my simple Company module to my Silverlight unit test project.  Since I am also testing RIA services classes, I will add two more references: System.ComponentModel.DataAnnotations and System.ServiceModel.DomainServices.Client.dll.  Now with this our of the way, here is what my test class and method look like:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SilverlightTestingDemo.Web;
 
namespace SilverlightUnitTest
{
    [TestClass]
    public class Tests
    {
        [TestMethod]
        [Tag("Synch")]
        [Description("Rules")]
        public void TestCompanyRules()
        {
            Company company = new Company();
            company.CompanyName = "test";
            Assert.AreEqual(0, company.ValidationErrors.Count, "Should be valid");
            company.CompanyName = string.Empty;
            Assert.AreEqual(1, company.ValidationErrors.Count, "Should be in valid");
        }
    }
}

 

Let me go over the attributes I used.  TestClass attribute is what signals to Unit testing framework as to what classes contain unit tests.  TestMethod attribute identifies methods that represent a single unit test.  Tag attribute is used by unit test runner UI to filter out what tests based on attributes will be run.  Description attribute data will be shown in runner UI when unit tests are run. Assert class is used to assert test results.  For example, in my first Assert statement I make sure that Company instance is valid once name is set.

When I run unit tests after setting up unit test application’s web site as start up project, here is what I see.

image

Test are setup to auto-run by default.  You will see the countdown label, and if you click on count down label, you will have a chance to select specific tests to run.

image

After tests are run, you will see test run summary in the top left cornet of the screen.  In my case I see that I had total of 1 test, and 2 test has passed.  if a test fails, you will see that in the test run summary.  You can download solution so far here.  In my next post I will cover asynchronous testing in Silverlight application.

Thanks.

Implementing Double-Click In Silverlight DataGrid

As I was working on one of my presentations, I wanted to go to a detail from from query form by letting user double-click.  No standard Silverlight controls implement double-clicks, and this includes DataGrid.  So, naturally one would need to listen to click events and interpret clicks within a certain time to be a double-click.  In my case I will use 300 milliseconds.  Another fact to consider is that if you try to do hook up double-click to the DataGrid itself, you will be disappointed because LeftMouseButtonUp event only fires when there are no rows to get in the way.  So, to make this work we will have to use each row’s mouse events.  I am going to wrap this up in a behavior first.  I am going to call this behavior  DataGridMouseLeftButtonDownCommandBehavior.  Here is what my class looks like, and it is very simple.  As you see, I am inheriting from CommandBase from Prism (Composite Application Guidance for Silverlight/WPF).

using System;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Windows.Controls;
using System.Windows.Input;
 
namespace CompanyModule.Converters
{
    /// <summary>
    /// Inherit from command base from Prism
    /// </summary>
    public class DataGridMouseLeftButtonDownCommandBehavior : CommandBehaviorBase<DataGrid>
    {
        /// <summary>
        /// Last time mouse was clicked
        /// </summary>
        private DateTime _lastTime;
 
        /// <summary>
        /// Number of milliseconds to interpret as doible-click
        /// </summary>
        private const long MillisesondsForDoubleClick = 300;
 
        /// <summary>
        /// Create new instance
        /// </summary>
        /// <param name="dataGrid">DataGrid to attach behavior to</param>
        public DataGridMouseLeftButtonDownCommandBehavior(DataGrid dataGrid)
            : base(dataGrid)
        {
            dataGrid.LoadingRow += OnLoadingRow;
            dataGrid.UnloadingRow += OnUnloadingRow;
        }
 
        /// <summary>
        /// Hook up mouse events
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnUnloadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.MouseLeftButtonUp -= OnMouseLeftButtonDown;
        }
 
        /// <summary>
        /// Unhook events to avoid memory leaks
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnLoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.MouseLeftButtonUp += OnMouseLeftButtonDown;
        }
 
 
        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // if timing is right, fire command
            if ((DateTime.Now.Subtract(_lastTime).TotalMilliseconds) < MillisesondsForDoubleClick)
            {
                ExecuteCommand();
            }
            // reset the time
            _lastTime = DateTime.Now;
        }
    }
}

 

Now that we have behavior of the way, we need to come up with a clean way to hook it up as well as setting a command and command parameter onto a DataGrid.

I am going to use a static class and attached properties.  Attached properties are a feature of Silverlight that would allow us to set properties on one object via properties defined on another object.  Most common example of them is Grid control in Silverlight.  If you add a child control to a Grid, you set its location by using Grid.Column or Grid.Row on child control itself, such as Textbox.  Properties that I am going to need are Command and CommandParameter as well as a property I can attach my behavior to.  I am again using Prism for my project.  Here is what my attached properties look like:

    public static class DataGridDoubleClick
    {
        private static readonly DependencyProperty DataGridDoubleClickCommandBehaviorProperty = 
            DependencyProperty.RegisterAttached(
                "DataGridDoubleClickCommandBehavior",
                typeof(DataGridMouseLeftButtonDownCommandBehavior),
                typeof(DataGridDoubleClick),
                null);
 
        public static readonly DependencyProperty CommandProperty = 
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(DataGridDoubleClick),
                new PropertyMetadata(OnSetCommand));
 
        public static readonly DependencyProperty CommandParameterProperty = 
            DependencyProperty.RegisterAttached(
               "CommandParameter",
               typeof(object),
               typeof(DataGridDoubleClick),
               new PropertyMetadata(OnSetCommandParameter));

 

I am defining call backs in order to be able to attach my behavior to the DataGrid in those.  The reason I cannot just put behavior inside XAML is because I need to pass DataGrid to my behavior as a parameter.  I am using attached property for the behavior because this makes it easy to store in static environment.

Here is how I am hooking up behavior in call back methods.


        private static void OnSetCommand
            (DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            DataGrid dataGrid = dependencyObject as DataGrid;
            if (dataGrid != null)
            {
                DataGridMouseLeftButtonDownCommandBehavior behavior = GetBehavior(dataGrid);
                behavior.Command = e.NewValue as ICommand;
            }
        }
 
        private static void OnSetCommandParameter
            (DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            DataGrid dataGrid = dependencyObject as DataGrid;
            if (dataGrid != null)
            {
                DataGridMouseLeftButtonDownCommandBehavior behavior = GetBehavior(dataGrid);
                behavior.CommandParameter = e.NewValue;
            }
        }

 

The final part is how to set the behavior.  Here is the short method for it:

        private static DataGridMouseLeftButtonDownCommandBehavior GetBehavior(DataGrid dataGrid)
        {
            DataGridMouseLeftButtonDownCommandBehavior behavior =
                dataGrid.GetValue(DataGridDoubleClickCommandBehaviorProperty) 
                    as DataGridMouseLeftButtonDownCommandBehavior;
            if (behavior == null)
            {
                behavior = new DataGridMouseLeftButtonDownCommandBehavior(dataGrid);
                dataGrid.SetValue(DataGridDoubleClickCommandBehaviorProperty, behavior);
            }
            return behavior;
        }

 

Now the final step – XAML for my data grid:

<UserControl
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  
   xmlns:command="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;
           assembly=Microsoft.Practices.Composite.Presentation"

   xmlns:converters="clr-namespace:CompanyModule.Converters"
   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
   x:Class="CompanyModule.Views.CompanyListView"
   mc:Ignorable="d"
   d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Content="Get Companies" command:Click.Command="{Binding GetCompaniesCommand}"/>
        <my:DataGrid 
           Grid.Row="1" 
           ItemsSource="{Binding CompanyList}" 
           HorizontalAlignment="Stretch"
           converters:DataGridDoubleClick.Command="{Binding Path=DoubleClickCommad}"
           converters:DataGridDoubleClick.CommandParameter="{Binding RelativeSource={RelativeSource Self},
             
Path=SelectedItem}"
           SelectionMode="Single">
           
        </my:DataGrid>
        <Rectangle Grid.RowSpan="2" 
                  Fill="LightBlue" 
                  Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}" 
                  Opacity="0.3"/>
    </Grid>
</UserControl>

 

Here is what my command looks like in ViewModel:

public DelegateCommand<object> DoubleClickCommad { get; private set; }

DoubleClickCommad = new DelegateCommand<object>(SelectCompanyForEdit);

 

private void SelectCompanyForEdit(object load)
{
  if (load != null && load is Company)
    {
      MessageBox.Show(((Company)load).CompanyName);
    }
}

 

And that is all there is to it.

Thanks.

First Stab at Reactive Framework

Today I made an attempt to make some sense of Reactive Framework(Rx).  Rx allows developers to write queries against events.  I know, I had hard time wrapping my head around this concept as well.  I hope the example below will help.

I downloaded and installed Rx extensions for Silverlight from the page above.  I created new Silverlight project and added references to three DLLs that are included with Rx:

System.CoreEx, System.Observable, System.Reactive.

In attempt to save time I created RIA Services project.  Rx is not as good of a fit for the Rx pattern, so my example is a bit contrived.

First, I am creating new instance of domain context

RXContext context;

Now, I am creating new query and starting the load for it:

            var talks = context.GetTalksQuery();


            var op = context.Load<Talk>(talks, LoadBehavior.RefreshCurrent, false);

Now, the fun part:  I am creating two event handlers by querying completed event with two different where clauses – one for error, the other for success:


    var events = Observable.FromEvent((EventHandler<EventArgs> eventInstance) =>
        new EventHandler(eventInstance),
            eventInstance => op.Completed += eventInstance,
            eventInstance => op.Completed -= eventInstance);
    var subsc = events.Where(ev => op.Error == null).Subscribe((args) =>
        { gridTalks.ItemsSource = op.AllEntities; });
    var errorSubs = events.Where(ev => op.Error != null).Subscribe((args) =>
        { MessageBox.Show(op.Error.ToString()); });

In the first statement I am converting regular event to observable event.  In the other two statement I am creating two event subscriptions with different where clauses.

Rx supports other clauses, such as group by as well.  I can see that Rx in general can result in cleaner, more readable code.  You can find more details at this Rx 101 page.

Tool Tip Usage in Silverlight Application

I have not blogged in a month.  What I found out in that time is that working 60-70 hours a week on two separate projects with deadlines is not very conducive to blogging :-) .  Now that I am off one of the projects, I should have more time to get into the routine of blogging weekly which has been my goal for a while.

Tooltips are pretty common in business applications.  They save real estate on the screen for developers.  They also provide users with ability to see more details without any button clicks.

It is very easy to setup a simple tool tip.  Here is a quick example:

        <TextBox 
           TextWrapping  ="Wrap" 
           Text="{Binding Path=CurrentPerson.FirstName}" 
           d:LayoutOverrides="Width, Height" 
           Grid.Column="1" 
           ToolTipService.ToolTip="{Binding Path=CurrentPerson.FullName}"/>

In this example I am binding text of a TextBox to FirstName of my person class.  Here is what my person class looks like:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace SilverlightToolTipDemo
{
    public class Person
    {
        public Person()
        {
            LastName = "Barskiy";
            FirstName = "Sergey";
            FullName = "Mr. Sergey Barskiy";
            Occupation = "Programmer";
            MaritalStatus = "Married";
            BitmapImage image = new BitmapImage(new Uri("../Images/Sergey_Barskiy.jpg", UriKind.RelativeOrAbsolute));
            Photo = image;

        }

        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string FullName { get; set; }
        public string Occupation { get; set; }
        public string MaritalStatus { get; set; }
        public ImageSource Photo { get; set; }


    }
}

This looks pretty boring though.  Too much like old WinForms :-) .

Let’s now use Silverlight capabilities and jazz it up a bit.

In the simple case you can just assign a string to tool tip and it will be shown on mouse-over event.  However, ToolTip property of ToolTipService can do a lot more.  You can put a control inside of it!  In my case, I want to show full name, photo, occupation and martial status.  Sounds complicated?  It is not.  Here is what it should look like:

        <TextBox
            Text="{Binding Path=CurrentPerson.LastName}"
            Grid.Column="1"
            d:LayoutOverrides="Width, Height"
            Grid.Row="1">
            <ToolTipService.ToolTip>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Image
                        Source="{Binding Path=CurrentPerson.Photo}"
                        Grid.ColumnSpan="2"
                        Grid.Row="0"
                        Width="100"
                        Height="100"
                        Stretch="UniformToFill"/>
                    <TextBlock
                        Grid.Row="1"
                        Text="Full Name:"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"/>
                    <TextBlock
                        Grid.Row="1"
                        Text="{Binding Path=CurrentPerson.FullName}"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                        Grid.Column="1"/>
                    <TextBlock
                        Text="Occupaton:"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"
                        Grid.Row="2"/>
                    <TextBlock
                        Text="{Binding Path=CurrentPerson.Occupation}"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                        Grid.Column="1"
                        Grid.Row="2"/>
                    <TextBlock
                        Text="Marital Status:"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"
                        Grid.Row="3"/>
                    <TextBlock
                        Text="{Binding Path=CurrentPerson.MaritalStatus}"
                        d:LayoutOverrides="Width, Height"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                        Grid.Column="1"
                        Grid.Row="3"/>
                </Grid>
            </ToolTipService.ToolTip>
        </TextBox>

Pretty easy, hah?  When I move my mouse over this textbox, I will see my photo along with additional information:

image

You can download full sample application here.

Thanks.

ReMix Talk

As I posted previously, I talked at Atlanta ReMix 2010 conference past Saturday.  Entire event was a a success, we had over 200 people there.  We had great presenters and good topics.  My topic was “Microsoft Silverlight and Windows Azure: A Match Made for the Web”

You can download PowerPoint presentation here.  You can download solution here.  To get solution up and going, you need to have Visual Studio 2010 installed, along with Silverlight 4 tools and Azure tools.  You will also need to sign up for an account on Azure and SQL Azure.  You will need to update web.config file and ServiceReference.ClientConfig file.

Please let me know if you have any questions.

Thank you.

ElementName Binding Inside Silverlight DataGrid

If you ever used ComboBox inside a templated columns inside DataGrid in Silverlight, you probably encountered the following issue. 

If you use ElementName to bind ItemsSource for a ComboBox in this situation, you will find that ElementName cannot be resolved.  Typically, you have to put your items source inside Resources collection on your use control, and use binding with StaticResource.  This is quite a pain, especially if you are using MVVM pattern, such as Prism.  This problems has been a sore spot for me for a while, but I did not have time to come up with a good solution.

Today I gave it some thought, and it hit me.  I should use a behavior to solve the problem.  The approach I took is manually look for the bound element one the ComboBox is part of visual tree.  I can do this inside Loaded event.  Here is how I got started:

    public class ResolveElementName : TargetedTriggerAction<FrameworkElement>

    {

        protected override void OnAttached()

        {

            base.OnAttached();

            Target.Loaded += Target_Loaded;

        }

 

        protected override void OnDetaching()

        {

            base.OnDetaching();

            Target.Loaded -= Target_Loaded;

        }

 

        private void Target_Loaded(object sender, RoutedEventArgs e)

        {

I also added a Dependency Property:

        public string PropertyName

        {

            get { return (string)GetValue(PropertyNameProperty); }

            set { SetValue(PropertyNameProperty, value); }

        }

 

        public static readonly DependencyProperty PropertyNameProperty =

            DependencyProperty.Register("PropertyName", typeof(string), typeof(ResolveElementName), new PropertyMetadata(string.Empty));

 

        protected override void Invoke(object parameter)

        {

            // do nothing

        }

 

The next step is to look how I typically setup ComboBox inside data gird.  I would like to keep the code as close to usual setup as possible to minimize the learning of new functionality.  Here is XAML from my test program.  This also shows how behavior is setup.

        <grid:DataGrid

            ItemsSource="{Binding People}"

            x:Name="PoepleBox"

            Grid.Row="3"

            AutoGenerateColumns="False" >

            <grid:DataGrid.Columns>

                <grid:DataGridTemplateColumn>

                    <grid:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <TextBlock Text="{Binding Path=Name}" Margin="7"/>

                        </DataTemplate>

                    </grid:DataGridTemplateColumn.CellTemplate>

 

                </grid:DataGridTemplateColumn>

                <grid:DataGridTemplateColumn>

                    <grid:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <TextBlock

                                Text="{Binding Path=StatusID}"

                                Margin="7"/>

                        </DataTemplate>

                    </grid:DataGridTemplateColumn.CellTemplate>

 

                </grid:DataGridTemplateColumn>

                <grid:DataGridTemplateColumn>

                    <grid:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <ComboBox

                                SelectedValue="{Binding Path=StatusID, Mode=TwoWay}"

                                DisplayMemberPath="StatusName"

                                SelectedValuePath="StatusID"

                                ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.Statuses}" 

                                Margin="7"

                                Width="200" >

                                <i:Interaction.Triggers>

                                    <i:EventTrigger>

                                        <behavior:ResolveElementName PropertyName="ItemsSource" />

                                    </i:EventTrigger>

                                </i:Interaction.Triggers>

                            </ComboBox>

                        </DataTemplate>

                    </grid:DataGridTemplateColumn.CellTemplate>

 

                </grid:DataGridTemplateColumn>

            </grid:DataGrid.Columns>

        </grid:DataGrid>

Also, you will need to import name spaces to get this to work as following:

<UserControl x:Class="ResolveElementNameBehaviorDemo.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:local="clr-namespace:ResolveElementNameBehaviorDemo"

    xmlns:grid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

    xmlns:behavior="clr-namespace:ResolveElementNameBehavior;assembly=ResolveElementNameBehavior"

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  

 

Now, I would like to show you how I am updating ItemsSource binding by replacing element name binding with regular source based binding:

        private void Target_Loaded(object sender, RoutedEventArgs e)

        {

 

            if (Target != null)

            {

                var fields = Target.GetType().GetFields(

                    System.Reflection.BindingFlags.Public |

                    System.Reflection.BindingFlags.FlattenHierarchy |

                    System.Reflection.BindingFlags.Static);

                foreach (var field in fields)

                {

                    if (field.FieldType == typeof(DependencyProperty) &&

                        (field.Name == PropertyName ||

                        field.Name == string.Concat(PropertyName, "Property")))

                    {

                        DependencyProperty dp = field.GetValue(Target) as DependencyProperty;

                        var binding = Target.GetBindingExpression(dp);

                        string elementName = binding.ParentBinding.ElementName;

                        if (!string.IsNullOrEmpty(elementName))

                        {

                            DependencyObject boundToElement = GetElementBasedOnName(Target, elementName);

                            if (boundToElement != null)

                            {

                                Binding newBinding = new Binding();

                                Binding oldBinding = binding.ParentBinding;

                                newBinding.BindsDirectlyToSource = oldBinding.BindsDirectlyToSource;

                                newBinding.Converter = oldBinding.Converter;

                                newBinding.ConverterCulture = oldBinding.ConverterCulture;

                                newBinding.ConverterParameter = oldBinding.ConverterParameter;

                                newBinding.FallbackValue = oldBinding.FallbackValue;

                                newBinding.Mode = oldBinding.Mode;

                                newBinding.NotifyOnValidationError = oldBinding.NotifyOnValidationError;

                                newBinding.Path = oldBinding.Path;

                                newBinding.Source = boundToElement;

                                newBinding.StringFormat = oldBinding.StringFormat;

                                newBinding.TargetNullValue = oldBinding.TargetNullValue;

                                newBinding.UpdateSourceTrigger = oldBinding.UpdateSourceTrigger;

                                newBinding.ValidatesOnDataErrors = oldBinding.ValidatesOnDataErrors;

                                newBinding.ValidatesOnExceptions = oldBinding.ValidatesOnExceptions;

                                newBinding.ValidatesOnNotifyDataErrors = oldBinding.ValidatesOnNotifyDataErrors;

                                if (Target is ComboBox)

                                {

                                    ComboBox combo = Target as ComboBox;

                                    combo.SetBinding(dp, newBinding);

                                    combo.SetBinding(ComboBox.SelectedValueProperty,

                                        combo.GetBindingExpression(ComboBox.SelectedValueProperty).ParentBinding);

                                }

                                else

                                {

                                    Target.SetBinding(dp, newBinding);

                                }

                               

                            }

                        }

                    }

                }

            }

        }

 

Last step, let me show you how to look for an element with a specific name inside visual tree.  I will use a recursive function that will use VisualTreeHelper class:

        private static DependencyObject GetElementBasedOnName(DependencyObject startPoint, string elementName)

        {

            DependencyObject returnValue = null;

            if (startPoint != null)

            {

                DependencyObject parent = VisualTreeHelper.GetParent(startPoint);

                if (parent != null)

                {

                    FrameworkElement fe = parent as FrameworkElement;

                    if (fe != null)

                    {

                        if (fe.Name == elementName)

                        {

                            returnValue = fe;

                        }

                        else

                        {

                            returnValue = GetElementBasedOnName(fe, elementName);

                        }

                    }

                    else

                    {

                        returnValue = GetElementBasedOnName(fe, elementName);

                    }

                }

            }

            return returnValue;

        }

 

This is it.  There as couple of downsides of this approach.  First of all, there is a small flash when combo is bound.  It is hard to notice though.  The other downside is the overhead of looking for a parent.  However, this is not visibly noticeable.  I tested with a data grid with 100 items, and I do not see any hesitation when scrolling.

You can download the entire solution with behavior and test application here.

I also published it to Microsoft Expression Gallery.

Please let me know if you have any questions.. 

Windows Phone 7 Database

I just uploaded and published new CodePlex project I have been working on.  It is an Isolated Storage based database for Windows Phone 7.  I converted my existing Silverlight database project I published a long time ago and adapted it to Windows Phone 7. It supports multiple strongly typed tables, basic Linq based operations, addition and deletion of ranges of items, deletion of items based on condition.  You can also directly bind data to UI in Silverlight because base table inherits from ObservableCollection.  It supports encryption along with lazy loading of table. 

Please take a look at http://winphone7db.codeplex.com/

 

Here are key classes of the project.  ITable interface makes it easy to write generic code in Database class.  It is a simple interface as you can see:

using System;
using System.IO;

namespace SilverlightPhoneDatabase.Core
{
    /// <summary>
    /// Interface that is used for tables in a database
    /// </summary>
    public interface ITable
    {
        /// <summary>
        /// Type of object that database contains
        /// </summary>
        Type RowType { get; }

        /// <summary>
        /// Save table le to the Isolated Storage
        /// </summary>
        void Save();

        /// <summary>
        /// Write content of a table to a file stream
        /// </summary>
        /// <param name="stream">Stream to write table to</param>
        void WriteDTableToStream(Stream stream);

        /// <summary>
        /// Set internal variables data when a table is de-serialized
        /// </summary>
        /// <param name="databaseName">Database name that table belongs to</param>
        /// <param name="password">Password to use for encryption</param>
        void SetTableDefinition(string databaseName, string password);
    }
}

I use XML Serializer to store table to Isolated Storage:

using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        string fileName = string.Concat(_databaseName, ".", typeof(T).FullName);
#if SILVERLIGHT
                        if (store.FileExists(fileName))
                        {
                            store.DeleteFile(fileName);
                        }
#else
                        if (store.GetFileNames(fileName).Length > 0)
                        {
                            store.DeleteFile(fileName);
                        }
#endif
                        using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.OpenOrCreate, store))
                        {
                            WriteDTableToStream(stream);
                        }
                    }

 

Writing data to stream is very easy:

 /// <summary>
        /// Write content of a table to a stream
        /// </summary>
        /// <param name="stream">Stream to write table to</param>
        public void WriteDTableToStream(Stream stream)
        {
            string content = string.Empty;
            using (StringWriter stringWriter = new StringWriter())
            {
                XmlSerializer serializer = new XmlSerializer(this.GetType());

                serializer.Serialize(stringWriter, this);
                stringWriter.Flush();
                content = stringWriter.GetStringBuilder().ToString();
                if (!string.IsNullOrEmpty(_password))
                {
                    content = Cryptography.Encrypt(content, _password);
                }
                stringWriter.Close();
            }

            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(content);
                writer.Flush();
                writer.Close();
            }
        }

The most interesting part of Database class is probably table loading.  This is done via generic function Table<T>:

/// <summary>
        /// FInd instance of a table that contains specific row type
        /// </summary>
        /// <typeparam name="T">Type of object that this table contains</typeparam>
        /// <returns></returns>
        public Table<T> Table<T>()
        {
            ITable returnValue = (from oneTable in Tables
                                  where oneTable.RowType == typeof(T)
                                  select oneTable).FirstOrDefault();
            if (_useLazyLoading && !_loadedTables[typeof(T)])
            {
                Type tableType = typeof(Table<>).MakeGenericType(new Type[] { typeof(T) });
                string fileName = string.Concat(_databaseName, ".", typeof(T).FullName);
                using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream tableStream = new IsolatedStorageFileStream(fileName, FileMode.Open, store))
                    {
                        LoadTable(tableStream, tableType);
                        tableStream.Close();
                    }
                }
                _loadedTables[typeof(T)] = true;
                returnValue = (from oneTable in Tables
                               where oneTable.RowType == typeof(T)
                               select oneTable).FirstOrDefault();
            }
            return (Table<T>)returnValue;

        }

 

I would very much appreciate comments and feature requests related to this project.

Thanks in advance for the feedback.

ReMix 2010 in Atlanta

If you have not registered for this fine event I blogged about previously, you have a week left.

You can register for it here: http://reMIXatlanta.org.  You can also check out the list of session that will be presented there.

Yours truly will be presented a session there as well.  The title will be “Microsoft Silverlight and Windows Azure: A Match Made for the Web”.

Here is what they session is about:

By combining the rich user experience of Silverlight with the scalability of Windows Azure compute and storage, you can build some incredible end-to-end web applications. In this session we will discuss the business advantages of running Silverlight applications in the cloud. We will cover the steps necessary to build Silverlight applications for deployment in Azure including: data access with SQL Azure, cloud storage, communication mechanisms and data access options. We will also demonstrate how the same approach works for Windows Phone 7 development.

I am just as excited about speaking as I am about attending other sessions.  One can always learn a ton at the community events.

Windows 7 and IIS Errors

I just re-installed Windows 7 on my machine.  Once I opened and tried to run an old web project configured for VS 2010 and .NET 4.0, my IIS server threw an exception.  I went into Windows features and enabled all IIS features related to ASP.NET and WCF.  Even after all this I still got the following error:

HTTP Error 500.21 – Internal Server Error
Handler "PageHandlerFactory-Integrated" has a bad module "ManagedPipelineHandler" in its module list

I checked web.config, and it looked correct, plus it has not changed in a while.  After some research I found out that  even though ASP.NET 4.0 was showing up in properties of my virtual directory, ASP.NET still did not function properly.  The solution was to run aspnet_regiis –i after all.  One thing to remember is to run this utility from Microsoft.NET v4 folder, not 2.0 folder.  Once I ran the utility, I was back in business.

 

I hope this helps someone with the same issue.

reMix Atlanta 2010

image

Mark your calendar and purchase your ticket now for Atlanta’s premiere Design & Developer Event

THE WEB BELONGS TO US, AND MOBILE WILL BE NEXT.

reMIX LOCATION

Saturday May 8th 8:00AM-5:00PM

Atlanta Marriott Perimeter Center

246 Perimeter Center Pkwy NE

Atlanta, Georgia 30346

Phone: 770-394-6500

reMIX Atlanta is the one-day conference for developers and designers who want to take their skills to the next level. Come out to see the exciting new technologies and techniques that can be used to build the next generation of interactive websites and mobile applications.

This is a “Don’t Miss Event” with only 400 seats. Get yours today!

REGISTER TODAY!

http://reMIXatlanta.org

Tickets only $25 until 4/27, then $35

Limited seating, filling fast! Act Now!

SPECIAL BONUS

A very awesome FREE pre-event:

Friday May 7th 6:00PM-9:00PM

Hosted by Carl & Richard, this is a .NET Rocks! fun evening about Visual Studio 2010 & .NET 4

image

http://dotnetrocks.com

 

What to Expect:

Learn about the completely new Windows Phone 7 and the excitement about quickly developing applications using Silverlight and building 2D/3D games using XNA.

Learn about the Designer/Developer workflow used to create great user experience (UX) in your applications.

Learn about building next-generation web applications with the new Silverlight 4 features, how to build with Windows Azure, and the improved ASP.NET MVC 2.0

image

Metro Icons for Windows Phone 7

I found this link that will allow you to download set of Metro icons for Windows Phone 7.  You will need to scroll down closer to the bottom of the page to find the actual links.

Enjoy

Atlanta .NET Talk on Windows Phone 7

I had a privilege to present on Silverlight development for Windows Phone 7 at local Atlanta.NET Users Group today, March 29th 2010.

You can download PowerPoint presentation here.  Please email me any questions you have regarding the presentation.

Thanks.

Windows Phone 7 Application with OData

In this post I will continue exploring Windows Phone 7 development.  Almost any application needs a data source.  There are a few options available for Silverlight applications on Windows Phone.  You can use plain WCF service.  You can optionally put it on Azure.  You can also use Isolated Storage.  Essentially it becomes your custom database.  Of course, you have to write all the API in this case.  Or, you can use OData.  OData approach is the one I am exploring in this post.

First things first, you need to download CTP for OData on Windows Phone.  Here is the link for this download:

http://www.microsoft.com/downloads/details.aspx?FamilyID=b251b247-70ca-4887-bab6-dccdec192f8d&displaylang=en

Download and unzip the files into a folder.  You will need a DLL that is contained in this download – System.Data.Services.Client.Dll

You can follow my previous post and create new Silverlight application for Windows Phone.  There is small change you will need to make.  You need to select the following project template:

image

Now we need to pick an OData source.  I am going to look at www.OData.Org to find one.  I am picking Mix 2010, but you can select any other.  Here is the link I found on OData site – http://api.visitmix.com/OData.svc/

You can always browse the service.  In my case I am going to generate a proxy for this service by running the following command from Microsoft.NET/v4 directory on your local machine:

DataSvcutil.exe /uri:http://api.visitmix.com/OData.svc /DataServiceCollection /Version:2.0 /out:VisitMixClientTypes.cs

DataSvcuil is the .NET utility that generates proxies for ADO.NET Data Services or OData.

Once this is done, copy generated file (VisitMixClientTypes.cs) into the project folder and include it in the project.  What we have inside the file is the proxy for OData service.

Nest step is to update the XAML to match our proxy.  In my simple example I will use the list of sessions and show it on the front page.  Here is what my XAML looks like for my main page (MainPage.xaml)

 

 

<!--ContentGrid contains ListBox. Place additional content here-->
<Grid x:Name="ContentGrid" Grid.Row="1">
    <Grid.Projection>
        <PlaneProjection/>
    </Grid.Projection>
    <ListBox x:Name="ListBoxOne" MouseLeftButtonUp="ListBoxOne_MouseLeftButtonUp"
             Style="{StaticResource PhoneListBox}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel x:Name="DataTemplateStackPanel" Orientation="Horizontal">
                    <Border x:Name="DataTemplateBorder" Height="44" Width="44" BorderBrush="White"
                            BorderThickness="2.5" CornerRadius="100" Margin="10,16,0,0"
                            VerticalAlignment="Top">
                        <Path x:Name="DataTemplatePath" Height="16" Width="11" Fill="White"
                              Stretch="Fill" Margin="4,0,0,0" HorizontalAlignment="Center"
                              VerticalAlignment="Center" UseLayoutRounding="False"
                              Data="M337.59924,129.61948 L337.59924,141.51501 L345.5704,135.87381 z"/>
                    </Border>
                    <mpc:ListViewItem Layout="TextAndDetailsWithIcon" Text="{Binding Title}"
                                      Details="{Binding Body}" Style="{StaticResource PhoneListBoxItemLayout}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

I am only copying the main portion of UI, not entire page here.

I am also going to update the details page that is generated by the project wizard to match my data as well.  Here is what it looks like:

<Grid x:Name="LayoutRoot"
      Background="{StaticResource PhoneBackgroundBrush}"
      d:DataContext="{Binding Items[0]}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <!--TitleGrid is the name of the application and page title-->
    <Grid x:Name="TitleGrid" Grid.Row="0">
        <Grid.Projection>
            <PlaneProjection/>
        </Grid.Projection>
        <TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextPageTitle2Style}"/>
    </Grid>
    <!--ContentGrid contains the details-->
    <Grid x:Name="ContentGrid" Grid.Row="1">
        <Grid.Projection>
            <PlaneProjection/>
        </Grid.Projection>
        <TextBlock TextWrapping="Wrap" Text="{Binding Body}"
                   Style="{StaticResource PhoneTextBodyTextStyle}"/>
    </Grid>
</Grid>

Now, let’s work on code behind to call our OData service.  Here is entire code behind for MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using EventModel;
using System.Collections.ObjectModel;
using System.Data.Services.Client;
using System.Windows.Input;
namespace WindowsPhoneListApplication1
{
    public partial class MainPage : PhoneApplicationPage
    {
        object _selectedItem;
        EventEntities _entities = new EventEntities(new Uri("http://api.visitmix.com/OData.svc/"));
        public MainPage()
        {
            InitializeComponent();
            SupportedOrientations = SupportedPageOrientation.Portrait;
            Loaded += new RoutedEventHandler(MainPage_Loaded);
            PageTransitionList.Completed += new EventHandler(PageTransitionList_Completed);
            var query = _entities.CreateQuery<Session>("Sessions");
            query.BeginExecute(ar =>
            {
                DataLoaded(ar);
            }, query);
        }
        private void DataLoaded(IAsyncResult result)
        {
            try
            {
                DataServiceQuery<Session> query = result.AsyncState as DataServiceQuery<Session>;
                List<Session> sessions = query.EndExecute(result).ToList();
                Dispatcher.BeginInvoke(() =>
                    {
                        this.ListBoxOne.ItemsSource = sessions;
                    });
            }
            catch (Exception ex)
            {
                Exception thing = ex;
            }
        }
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // Reset page transition
            ResetPageTransitionList.Begin();
        }
        private void ListBoxOne_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // Capture selected item data
            _selectedItem = (sender as ListBox).SelectedItem;
            // Start page transition animation
            PageTransitionList.Begin();
        }
        private void PageTransitionList_Completed(object sender, EventArgs e)
        {
            // Set datacontext of details page to selected listbox item
            NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));
            FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
            root.DataContext = _selectedItem;
        }
    }
}

The code above is fairly easy.  First, I create a DataSericeQuery of type Session.  Session type is part of our generated proxy.  It then call BeginExecute and pass it a handler.  Inside the handler (DataLoaded) I fire EndExecute, then set the items source for my ListBox.  I have to make sure to use Dispatcher for this call, otherwise I will get cross thread access exception because handler is not firing on UI thread.

That is it.  You can now run the application and see the list of sessions at the MIX 2010.  You can also click on an item to see the details.

Please post your questions here.

Thanks.

Getting Started with Windows Phone 7 and Silverlight

In this post I will go through the steps of creating my first Windows Phone 7 application using Silverlight.  It will be simple and will mostly concentrate on tools rather than phone specific functionality.  Of course, I will do more posts describing features that are specific to Silverlight for Windows Phone 7.

First thing I have to do is download the tools and install them on my machine.  You can find all appropriate link on www.Silverlight.net.  If you click on Getting Started menu, you can look for phone development tools.  You will download and install Visual Studio 2010 Express for Windows Phone.  Once you are done with that task, start the studio.

Here is what the screen look like.

image

Let’s go ahead and click on New Project link.  Let’s select Silverlight tree node, then Windows Phone application.  One side note – no VB.NET menu inside Studio for Phone.

image

Once project is created, you will see the screen that contains three parts by default – solution explorer, XAML view and Design view.

image

Now we can even run the application.  Let’s go ahead and do this.  What we will see is the Phone emulator as well as studio going to debug mode.  it will take a few minutes first time you run as emulator initializes.  You can resize the emulator by clicking on the menu that I have pointed to with a hand cursor on the picture below.  Eventually application loads, and you will the application just created, more precisely title and subtitle blocks.

image

Let’s add a few controls and some code now.  You will notice that when you stop debugging the studio that emulator keeps running.  This is good, and you want to keep it running in order to save deployment and initialization time. 

We will use the studio’s designer surface to add controls to the surface.  To do so, activate toolbox and pin it.

image

Let’s drag and drop a button onto design surface.  Here is what we will see now.

image

Let’s now add event handler for click event.  To do so, double-click on the button on design surface.  Code view will open and handler will be created.  We will do something really simple, we will change the title as follows:

 

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.textBlockPageTitle.Text = "I changed the title";
        }

Let’s run the application and see our code in action by clicking on the button.  Now, the step we are going to do is explore debugging.  To do so, set a breakpoint inside the event handler.

image

Run the application again from studio by clicking on debug button inside the studio.  I put hand cursor next the button.

image

Once the emulator loads the application, click on the new button inside the application we added.  Voila!  Our break    point got hit.

 

I illustrated in this post how to create a sample application inside Express Studio for Windows Phone, add controls to the design surface, write code behind and set breakpoints.

One last note.  You will notice that even new controls dropped onto design surface are styled certain ways to match overall phone design.  If you wonder why, it is because new project wizard comes preloaded with default styles for all basic controls.  To look at those styles, just open app.xaml.  For example, you can search for TargetType="ButtonBase" to see style for button.

There will be more to come as I explore phone specific features in Silverlight for Windows phone.

Thanks.

CodeStock Talk

I submitted sessions to this year’s CodeStock event.  You can vote now for all sessions here.

If you would like to see my session, please vote for them.  Here is my list

 

Thank you and I hope to see you there.

Getting Started with PowerPivot

Last week I took a stab at creating my first PowerPivot spreadsheet, and I wanted to document the steps.  Maybe this post will help someone, but it will help me remember, that is for sure!

Before you get started, you will need to download all the software required.  Here is my list:

Of course, you will need and instance of SQL Server 2008.  You can just use Express edition if you do not have one installed.

Now that I have everything installed and configured, I can start with PowerPivot.  One note – look for Hand shaped cursor in the screens below.s

Step 1 – Start up Excel 2010 and look for PowerPivot menu, then click on PowerPivot Window to launch pivot.

image

Step 2 – click on From Database in the window, then Select from SQL Server

image

Step 3 – Fill in SQL Server details.  I am choosing to use Data Warehouse DB.  Click Next when done.  On the next screen select an option to Select for a list of tables and views.

image

Step 4 – Select dimension tables and fact table to analyze.  Here is my list in alphabetical order

  • DimCustomer
  • DimDate
  • DimProductCategory
  • DimSalesTerritory
  • FactInternetSales

You can select any tables you like of course.  Wait while data is imported into PowerPivot, then click Close.  PowerPivot window will now have five tabs with data and columns directly imported from the database.  Here is what it looks like.

image

Now click on PivotTable menu and select  Chart and Table – Vertical option.  We will simply create a chart and an analysis table to go with it.  Click on New Worksheet when prompted.  This step will return you back to main Excel window.  You will see chart, table and on the left hand side Gemini task pane – listing of imported data.  Gemini used to be Microsoft code name for this product/functionality.

image

Step 5 – Building a chart.  We are going to analyze sales based on customer marital status by linking it to sales amount.  Click on the chart first, then in Gemini pane expand DimCustomer table and select MaritalStatus.  Then, expand FactInternetSales and select SalesAmount.  PowerPivot will guess what we are trying to do and MaritalStatus as Axis field and Sum(SalesAmount) as Values.  Here is what it looks like:

image

 

Step 6 – building table with filters. 

Click on table first, then check the following tables/fields in Gemini pane:

  • DimCustomer – MaritalStatus and Gender
  • DimDte – CalendarYear
  • DimProductCategory – EnglishProductCategoryName
  • DimSalesTerritory – SalesTerritoryCountry
  • FactInternetSales – SalesAmount

At this point your bottom of Gemini pane should look like this:

image

if you have anything else in Values, click on that item and select “Move to Row labels”.  What you will see also is that your have a report built for you in table area that uses all the analysis points.  You could leave it as is, but I will do more.

 

Step 7 Now I can analyze the data by “slicing it”.  To do this we will create two groups of slices – horizontal and vertical.  We will split our analysis categories as follows:

  • Horizontal Slices: Marital Status and Gender
  • Vertical Slices –English Product Category and Calendar Year.

I will leave Sales Territory country as a column in my table. To perform this I will click on each of my slices and select “Move to Slices Horizontal (or Vertical) as appropriate.  Then I click on each slice and choose Move Up or down until my pane looks like this:

image

Now here is what my table looks:

image

I will go ahead and move things around to make spreadsheet look better:

image

 

Step 8 – Use slices for analysis.  This process is super simple – just click on a desired slice(s) to enact filter on rows of a table.

image

To clear the filter just click on a funnel picture with x across it:

image

As you do so, you will see the chart and table both updating with your filter values.  One thing I did notice at the end – Catergory is lon linked to internet sales, so category filter has no effect on data.  If you see similar behavior, your data has the same issue.  You can always manually build relationships in PowerPivot by click on Table tab in pivot and choosing Manage Relationships menu:

image

 

As you can see, using PowerPivot is extremely easy and the results are very powerful.  You can save your spreadsheet, open it later and refresh the data by clicking on a filter!  You also have an option to show or hide Gemini panels in Excel under PowerPivot menu.  In the same menu you also have an option to show or hide Gemini panels.

Thanks.

Extending Interfaces with Implementation

Today I was faced with an issue.  I had an interface based implementation of a specific functionality.  All classes that implemented this interface had different implementation of course.  What I had to add is ability to run certain checks on each implementation that would need to analyze the data defined in the interface and return a Boolean result of this check.

The problem was that the checks were all the same and I hated to add this check to the interface and write identical code in all implementations.  As everyone knows interfaces cannot contain implementation code though.  So, what should I do?

So, a particular .NET 3.5 feature came to my rescue.  I am referring to extension methods.  As you may or may not know extension methods are tied to a type.  Well, interface is a type too.  Here is some code to look at.

Here is the interface definition:

    public interface ISupportCustomAction

    {

        Action CustomAction { get; set; }

        void Execute();

    }

Here is my class definition that implements this interface

    public class CustomActionOne : ISupportCustomAction

    {

        #region ISupportCustomAction Members

        private Action action;

        public Action CustomAction

        {

            get

            {

                return action;

            }

            set

            {

                action = value;

            }

        }

 

        public void Execute()

        {

            // fill in the method

        }

 

 

        #endregion

    }

Finally, here is my extension method

    public static class ISupportCustomActionExtensions

    {

        public static bool Check(this ISupportCustomAction action)

        {

            if (action.CustomAction == null)

            {

                return false;

            }

            else

            {

                return true;

            }

        }

    }

Here is my test code to confirm that everything works

    class Program

    {

        static void Main(string[] args)

        {

            CustomActionOne action = new CustomActionOne();

            action.CustomAction = () => { Debug.WriteLine("Exectuted Action."); };

            Analize(action);

 

            action = new CustomActionOne();

            Analize(action);

            Console.ReadKey();

        }

 

        private static void Analize(ISupportCustomAction action)

        {

            if (action.Check())

            {

                Console.WriteLine("Can execute action");

            }

            else

            {

                Console.WriteLine("Cannot execute action");

            }

        }

    }

How useful this is?  Pretty useful in my case.  Saved me some typing and resulted in consistent coding.  My point is that is good to know what features .NET has and use them as a need arises.  As you can see I have a hybrid here of a base (abstract) class and an interface.  As a result, I am able to use features that belong to both concepts.

What does this code remind you of?  Can you say “Multiple Inheritance in C#?”  Well, not exactly, but pretty close.

 

Thanks.

Community Events

I often forget about different conferences I would like to keep an eye on, so I decided to make a list of them on my blog.

Silverlight 4 + COM + SQL Server = Cool!

Today is the day to talk about COM possibilities in Silverlight 4.  One would question the titles of my post.  COM and Cool in the same sentence?  Let me proof this title to you.

First, let me take a closer look at COM.  In order to access COM, you must install Silverlight application on a local machine.  The access to COM is not enabled when a Silverlight application is run in the browser.  So, first of all you have to enable this by checking “Enable running application out of browser” checkbox in project properties.  Second of all, you have to check “Require elevated trust…” checkbox in “Out-of-browser settings” area in project properties.  Now, you are ready to install you application and test COM support.  How about Word automation:

Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
var doc = word.Documents.Add();
var paragraph = doc.Paragraphs.Add();
paragraph.Range.Text = "Some text";

Now, let’s talk about database access.  Parts of System.Data.SqlClient namespace are not exposed to COM by default.  So, to enable database access we must write an assembly that is exposed to COM that wraps database access.  To do so, check the property “Register for COM Interop” in project properties for the .NET (NOT Silverlight) based project that will fire off database queries for us.  Once the assembly is built, I can just use RegAsm to register my DLL with COM on a machine.  Of course, this would be a prerequisite to use Silverlight application for local data access.  The other prerequisite is to have .NET Runtime installed on that machine as well.  I could write an install project of course to make this process easier.

The next step is to write a Silverlight assembly that would use COM Interop similar to the one above for Word to talk to my database access .NET based assembly.

dynamic sqlDB = ComAutomationFactory.CreateObject("COMSQLClient.COMSqlDatabase");

Now the most exciting part.  I created and published the project on CodePlex that does exactly what I just talked about.  Check out the project and let me know what you think.  You can download the source code and look into the implementation details.  Here is the link to it:

http://silverlight4sqllib.codeplex.com/

Thanks.

The MSDN Southern Fried Roadshow

Glen Gordon, our local evangelist is doing another road show.  Here are the event details.

Thursday, February 25, 2010 1:00 PM – Thursday, February 25, 2010 5:00 PM Eastern Time (US & Canada)
Welcome Time: 12:30 PM

Atlanta Marriot Alpharetta

5750 Windward Pkwy
Alpharetta Georgia 30005
United States

Language(s):
English.

Product(s):
Azure Services Platform, Microsoft technologies, Windows and Windows 7.

Audience(s):
Pro Dev/Programmer.

Presenter(s):
Glen Gordon, Joe Healy

Event Overview

MSDN Events presents: Take Your Applications Sky High with Cloud Computing and the Windows Azure Platform

Join your local MSDN Events team as we take a deep dive into cloud computing and the Windows Azure Platform. We’ll start with a developer-focused overview of this new platform and the cloud computing services that can be used either together or independently to build highly scalable applications. As the day unfolds, we’ll explore data storage, SQL Azure, and the basics of deployment with Windows Azure. Register today for these free, live sessions in your local area.

If you register and attend this event, you will be placed in a raffle to win a chance to bring home one (1) free copy of Windows 7 – you could be the lucky winner! Register today!

SESSION 1: Overview of Cloud Computing and Windows Azure

The Windows Azure platform is a set of high-performance cloud computing services that can be used together or independently and enable developers to leverage existing skills and familiar tools to develop cloud applications. In this session, we’ll provide a developer-focused overview of this new online service computing platform. We’ll explore the components, key features and real day-to-day benefits of Windows Azure.

Highlights include:

· What is cloud computing?

· Running web and web service applications in the cloud

· Using the Windows Azure and local developer cloud fabric

· Getting started – tools, SDKs and accounts

· Writing applications for Windows Azure

SESSION 2: Survey of Windows Azure Platform Storage Options

Durable data storage is a key component of any cloud computing offering. The Windows Azure Platform offers many options, which can be used alone or in combination. Windows Azure itself offers ready-to-use and lightweight storage in the form of tables, blobs, and queues. Another choice for storage is SQL Azure, a true relational database in the cloud. In this session, we’ll explore the highlights of these implementations and how to both create and use storage in each form. We’ll give you guidance on choosing the right forms of storage for your application scenarios.

Highlights include:

· Understanding table & blob storage

· Programming against table & blob storage

· Working with queue storage

· Managing credentials and connection strings

· Scaling and configuration

· Understanding SQL Azure databases versus local SQL Server databases

· SQL Azure firewall, logins and passwords

· Database creation, deployments and migrations

· Database management using SQL Management Studio

· Programming against SQL Azure databases

SESSION 3: Going Live with your Azure Solution

Windows Azure features a powerful, yet simple deployment model. By focusing on your application and abstracting away the infrastructure details, you can deploy almost any app with minimal fuss. In this session, we’ll walk you through the basics of Windows Azure deployment, including site monitoring, diagnostics and performance issues.

Highlights include:

· Start-to-Finish Visual Studio demonstration of a realistic XML data driven business web site from the desktop to the cloud.

· Windows Azure Deployments

· Start-to-Finish Visual Studio demonstration of a realistic SQL Server data driven business web site from the desktop to the cloud.

· Configuration of your application in the cloud

· Guidance and Suggestions to ensure your success

*Be sure to learn more about the TechNet event happening on the same day at the same location from 8:30am–12:00pm. If you are interested in attending, please register separately for that event here: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439495&Culture=en-US

Registration Options

Event ID:
1032439974

Here is the link to this event:

http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439974&Culture=en-US

Entity Framework 4.0 and Multiple Data Contexts

In the EF version 1.0, there was a problem when one would try to update multiple contexts as part of a single transaction.  For example, I can use Transaction Scope, the update one context, then second context.  Here is sample code to illustrate:

 

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using (RolodexEntities context = new RolodexEntities())
        {
            context.Connection.Open();

            Company company = new Company();
            company.CompanyName = "Test 1";
            company.DateAdded = DateTime.Today;
            context.AddToCompanies(company);
            context.SaveChanges();

            using (RolodexEntities context2 = new RolodexEntities(context.Connection as EntityConnection))
            {
                Company company2 = new Company();
                company2.CompanyName = "Test 1";
                company2.DateAdded = DateTime.Today;
                context2.AddToCompanies(company2);
                context2.SaveChanges();
            }
        }

        scope.Complete();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

This code in version 1.0 would throw an exception when second context’s constructor was called.  The exception was quite obscure and was referring to the fact that the connection was already open.  This was actually correct, but that was the whole reason I was passing in the connection.  I was trying to make sure that my transaction would not get promoted to Distributed Transactions Coordinator.  The transaction would always get promoted as soon as there are multiple SQL Server connections used within using scope/.end using scope code block.  So, in version 1.0 MSDTC would be required in the code above.

This issue still exists in EF 4.0.  You can vote to fix the issue here : https://connect.microsoft.com/data/feedback/details/533240/cannot-share-a-store-connection-between-multiple-contexts-in-order-to-avoid-dtc-promotion

Here is the code that confirms the problem:

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using (RolodexEntities context = new RolodexEntities())
        {
            context.Connection.Open();

            Company company = new Company();
            company.CompanyName = "Test 11";
            company.DateAdded = DateTime.Today;
            context.AddToCompanies(company);
            context.SaveChanges();

            RolodexEntities1 contextTemp = new RolodexEntities1();
            MetadataWorkspace space = (contextTemp.Connection as EntityConnection).GetMetadataWorkspace();
            EntityConnection connection = new EntityConnection(space, (context.Connection as EntityConnection).StoreConnection);

            using (RolodexEntities1 context2 = new RolodexEntities1(connection))
            {
                User user = new User();
                user.UserName = "test";
                user.Role = "User";
                context2.AddToUsers(user);
                context2.SaveChanges();
            }
        }

        scope.Complete();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Please feel free to ask any questions on this subject.

Silverlight, MVVM and Animations

Yesterday I was asked about a way to play animations in MVVM environment.

So, I gave this some thought today, and came up with a few ideas.

First, and the easiest way is to separate ViewModel from animation by attaching an animation to a behavior.  Here is how we would write the behavior:

public class MVVMSimpleAnimationBehavior : TargetedTriggerAction<UIElement>

{

    protected override void Invoke(object parameter)

    {

        RunAnimation();

    }

 

    public Storyboard AnimationStoryBoard

    {

        get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }

        set { SetValue(AnimationStoryBoardProperty, value); }

    }

 

    public static readonly DependencyProperty AnimationStoryBoardProperty =

        DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMSimpleAnimationBehavior), new PropertyMetadata(null));

 

 

    private void RunAnimation()

    {

        if (AnimationStoryBoard != null)

        {

            AnimationStoryBoard.Begin();

        }

    }

}

 

Pretty simple approach.  Here is how would use animation in the XAML:

<Button Content="Behavior Test" Grid.Column="1">

    <i:Interaction.Triggers>

        <i:EventTrigger EventName="Click">

            <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>

        </i:EventTrigger>

    </i:Interaction.Triggers>

</Button>

Now, I want to complicate the story a little bit.  I really want to trigger an animation in the UI via an event in my model.  I am going to start with a sample ViewModel.  I want to have an event there that I will later use as a trigger for my animation.  Here is what my ViewModel would look like:

public class SampleModel: INotifyPropertyChanged

{

 

    public event EventHandler StartAnimation;

 

    protected virtual void OnStartAnimation()

    {

        if (StartAnimation != null)

        {

            StartAnimation(this, EventArgs.Empty);

        }

    }

 

    public void RaiseEvent()

    {

        OnStartAnimation();

    }

 

    #region INotifyPropertyChanged Members

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    protected virtual void OnPropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    #endregion

}

My event is called StartAnimation.  Now it is time to develop a more complicate behavior to support my event driven animation from ViewModel.  I am going to actually combine new functionality with the simple behavior about and have multi-functional useful object.  Here is what the final product looks like:

using System;

using System.Windows.Interactivity;

using System.Windows;

using System.Windows.Media.Animation;

using System.ComponentModel;

using System.Reflection;

 

 

namespace SLMVVMAnimationBehavior

{

    public class MVVMAnimationBehavior : TargetedTriggerAction<UIElement>

    {

        private EventInfo info;

        protected override void Invoke(object parameter)

        {

            RunAnimation(this, EventArgs.Empty);

        }

 

        public Storyboard AnimationStoryBoard

        {

            get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }

            set { SetValue(AnimationStoryBoardProperty, value); }

        }

 

        public static readonly DependencyProperty AnimationStoryBoardProperty =

            DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMAnimationBehavior), new PropertyMetadata(null));

 

        public string EventName

        {

            get { return (string)GetValue(EventNameProperty); }

            set { SetValue(EventNameProperty, value); }

        }

 

        public static readonly DependencyProperty EventNameProperty =

            DependencyProperty.Register("EventName", typeof(string), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));

 

 

        public object Model

        {

            get { return GetValue(ModelProperty); }

            set { SetValue(ModelProperty, value); }

        }

 

        public static readonly DependencyProperty ModelProperty =

            DependencyProperty.Register("Model", typeof(object), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));

 

        private static void HandlModelChanged(object sender, DependencyPropertyChangedEventArgs e)

        {

            MVVMAnimationBehavior behavior = sender as MVVMAnimationBehavior;

            object model = behavior.Model;

            if (behavior.info != null)

            {

                behavior.info.RemoveEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));

            }

            if (model != null && !string.IsNullOrEmpty(behavior.EventName))

            {

                behavior.info = model.GetType().GetEvent(behavior.EventName);

                behavior.info.AddEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));

 

            }

        }

 

        private void RunAnimation(object sender, EventArgs e)

        {

            if (AnimationStoryBoard != null)

            {

                AnimationStoryBoard.Begin();

            }

        }

    }

}

 

 

As you can see, I added two mode dependency properties – one for event name that will trigger the animation, the other one for ViewModel ( I actually called it model).  Now the tricky part is to use a bit of reflection to attach an event handler to the event on my model.  This is done in HandlModelChanged routine that is called when Model or Event name is set.  I am getting an event, and attaching a handler to it.  The actual handler is located inside the behavior itself – RunAnimation method.  Here is what my fianl XAML looks like that is testing both animation approaches:

<UserControl x:Class="SLMVVMAnimationBehavior.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:local="clr-namespace:SLMVVMAnimationBehavior"

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <UserControl.Resources>

        <Storyboard x:Name="TestStoryboard">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(TextBlock.FontSize)">

                <EasingDoubleKeyFrame KeyTime="00:00:00.1000000" Value="24"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.2000000" Value="21.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.3000000" Value="18.667"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.4000000" Value="16"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="13.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.6000000" Value="16"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="18.667"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.8000000" Value="21.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.9000000" Value="24"/>

                <EasingDoubleKeyFrame KeyTime="00:00:01" Value="26.667"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

        <local:SampleModel x:Key="CurrentModel" />

        <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}" Model="{StaticResource CurrentModel}" x:Key="Animation" EventName="StartAnimation"/>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="#FFF3EEEE" DataContext="{Binding Source={StaticResource CurrentModel}}">

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto"/>

                <ColumnDefinition Width="Auto"/>

                <ColumnDefinition/>

            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>

                <RowDefinition Height="Auto"/>

                <RowDefinition/>

            </Grid.RowDefinitions>

            <Button x:Name="TestButton" Content="Click To Start Animation" d:LayoutOverrides="Height" HorizontalAlignment="Left" Click="TestButton_Click"/>

            <Button Content="Behavior Test" Grid.Column="1">

                <i:Interaction.Triggers>

                    <i:EventTrigger EventName="Click">

                        <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>

                    </i:EventTrigger>

                </i:Interaction.Triggers>

            </Button>

            <TextBlock x:Name="textBlock" Margin="0,0,0,6" Text="Sample Text" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667"/>

        </Grid>

 

    </Grid>

</UserControl>

 

To summarize, I illustrate a couple of approaches to trigger animations in MVVM environment.  Of course, there is always code-behind, but many developers frown at this approach..

Please let me know if you have any questions.

WCF RIA Services Validation

Today I am continuing exploring WCF RIA Services.  I am going to discuss validation in RIA Services.

Any business application needs to validate user input.  I am going to start with a simple case.  In my sample application a user can enter a company information.  I would like to setup RIA Services to force the user to enter a company name before he or she can save the company.  In order to do so I am going to use Data Annotations.  First of all, I need to add a reference to System.ComponentModel.DataAnnotations DLL to all my projects.  RIA Services project should already have the reference. 

Now I need to edit my metadata file that corresponds to my data model under .NET version of RIA Services.  In my case it is RolodexDomainService.metadata.cs file in SilverlightRIAServicesLibrary.Web project.  In that file I need to find Companies class, then location company name property, then decorate the property with required attribute.  At the same time we will also put a limit on how many characters a user can enter:

[Required]

[StringLength(30)]

public string CompanyName;

 

If we want to see the results of our changes, we can run the application, then clear company name for an existing comp-any, then tab out of company name field.  Here we get visual feedback that our input was not valid:

image

Now, let’s create custom validation.  Fir example, I am going to force the date added to be no less that 1/1/2000.  To do this I will write a custom validation class like so:

public static class ValidationHelper

{

    public static ValidationResult DateAddedCheck(DateTime date)

    {

        ValidationResult result;

        if (date > new DateTime(2000, 1, 1))

        {

            result = new ValidationResult("");

        }

        else

        {

            result = new ValidationResult("Date is not valid");

        }

 

        return result;

    }

}

Validation method that I wrote is a static member.  It follows a specific signature that RIA Services requires.  For example, it returns Validation Result that contains specific information that validation infrastructure of RIA Services can parse.  Overall code is fairly simple.

In order to make this class available on the Silverlight side, I must include my validation class into Silverlight version of RIA Services library – SilverlightRIAServicesLibrary project in my case.  In order not to duplicate the code, I will include the same class as a link.  I right-click on the project, choose add existing item, navigate to my class, then click on down arrow on Add button, and select Add As Link.  Now I have the same validation on both .NET and Silverlight side.  To confirm, I just build and run the application.  Here is what my DateAdded attributes look like:

[Required]

[CustomValidation(typeof(ValidationHelper), "DateAddedCheck", ErrorMessage = "Date is not valid")]

public DateTime DateAdded;

On important thing to mention that in  order to see validation error in UI, we need to update our Binding to look as following:

<TextBox x:Name="CompanyNameTextbox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" Margin="6,6,6,6" Text="{Binding Path=CompanyName, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}" VerticalAlignment="Center"/>

There is one important thing to notice.  If you look at Silverlight side generated code, you will notice that validation occurs before the property value is set.  As a result, you cannot rely on property value being set if a validation exception is thrown.

Now, let’s look at saving code that we had to modify in order to validate user input.  Here is what it looks like:

try

{

    Validator.ValidateObject(this.Model, new ValidationContext(this.Model, null, null), true);

    if (this.Model.HasChanges)

    {

        ShowPleaseWaitMessage();

        _context.SubmitChanges(HandleSave, null);

    }

}

catch (ValidationException ex)