Unit Testing Windows Phone Applications

Posted by & filed under .Net, CodeProject, Unit Testing, Visual Studio, Windows Phone.

Recently Microsoft released Update 2 for Visual Studio 2012. If you installed the Update 2, you will get a new project template, under Windows Phone, Windows Phone Unit Test App.

Windows Phone Unit Test App - Project Template

This will help you to create unit test project for Windows Phone 8 applications. Once you create the project, necessary references will be added to the project by Visual Studio.

Windows Phone Unit Test App - Project References

If you are familiar with MS Test, you don’t need to learn any new framework for testing phone apps.
The Windows Phone test framework is designed as an adapter on top of the extensible Visual Studio 2012 unit testing platform. So you can run the tests from VS 2012 IDE itself.

Running Windows Phone Unit Tests from VS 2012 IDE

You can run the tests from console also, using vstest.console.exe. You can also choose to export the results to Visual Studio Test Results File using /Logger:trx command line switch. This unit testing feature is supported in Express Edition also.

Happy Programming

How to use existing Database in Windows Phone

Posted by & filed under .Net, .Net 3.0 / 3.5, CodeProject, Windows Phone.

Normally in Windows Phone apps, we used to create Database in the Application Launch event, like the following

if (!dataContext.DatabaseExists())
{
	dataContext.CreateDatabase();
}

And if there is any master tables you can write code to insert after database creation, like this.

if (!dataContext.DatabaseExists())
{
    dataContext.CreateDatabase();
    dataContext.Categories.InsertAllOnSubmit(
        new[] { DefaultCategory });
    dataContext.SubmitChanges();
}

This approach is not feasible if you have lot of data, for example a Dictionary database. In such scenarios you can add the existing database to the project, and setting the Build Action to Content.

Properties Window - Build Action - Content

This will deploy the database file with your application onto the phone, but it will be placed in the same folder as all other static content for your application. Your application can only read from this folder.

You can communicate to existing database using following connection string.

private const string ConnectionString = 
"Data Source ='appdata:/Database/Dictionary.sdf';File Mode=read only;";

If you want to modify the database, you need to copy (duplicate) the database to the application isolated storage. Here is the code snippet which will help you to copy your database file to isolated storage.

const string DatabasePath = "Database";
const string Filename = @"Database/Dictionary.sdf";
using (var isolatedStorageFile = 
    IsolatedStorageFile.GetUserStoreForApplication())
{
    if (!isolatedStorageFile.DirectoryExists(DatabasePath))
    {
        isolatedStorageFile.CreateDirectory(DatabasePath);
    }

    if (isolatedStorageFile.FileExists(Filename))
    {
        return;
    }

    var resource = 
        Application.GetResourceStream(new Uri(Filename, UriKind.Relative));
    using (var file = isolatedStorageFile.CreateFile(Filename))
    {
        var length = resource.Stream.Length;
        var buffer = new byte[1024];
        var readCount = 0;
        using (var binaryReader = new BinaryReader(resource.Stream))
        {
            while (readCount < length)
            {
                int actual = binaryReader.Read(buffer, 0, buffer.Length);
                readCount += actual;
                file.Write(buffer, 0, actual);
            }
        }
    }
}

Happy Programming.

Retrieving the COM class factory for component failed due to the following error: 800702e4.

Posted by & filed under .Net, .Net 4.0, Office Interoperability, Visual Studio, Windows Forms.

While working on some outlook C# application I got a COM exception like this.

Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80080005.

Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 800702e4.

My code was simply straight forward, I was just creating the instance of the outlook application.

var oApp = new Outlook.Application();

And this code was used in a different application which works without any issue. Later I found the solution for the problem. The culprit was UAC. I was running the Visual Studio as Administrator. So the conclusion is, when automating an Office application from another application, both the application should be run in same privilege level. If you are running Visual Studio as Administrator, you should run the office application also in Administrator mode.

Happy Programming.

Assembly Binding Redirection in .Net

Posted by & filed under .Net, .Net 4.0, ASP.Net, Windows Forms.

Today I come across an application crash due to version mismatch. The application executable was compiled using version 1.0.x.x, and we were using 6.2.x.x. Due to this version mismatch application was crashing.

Could not load file or assembly - error

Unfortunately we don’t have the source code of this application with us. Later I got one solution using bindingRedirect. This configuration element will help you to redirect referenced assemblies from one version to another using the app.config file.

<?xml version="1.0"?>
<configuration>
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<dependentAssembly>
				<assemblyIdentity name="Microsoft.Ink" 
					publicKeyToken="31BF3856AD364E35" culture="neutral"/>
				<bindingRedirect oldVersion="0.0.0.0-6.1.0.0" 
					newVersion="6.1.0.0"/>
			</dependentAssembly>
		</assemblyBinding>
	</runtime>
</configuration>

We fixed the problem by creating an application.exe.config file with binding redirection inside it. By doing this you are instructing the application or DLL that during runtime, for a particular dependent assembly to use a particular version when an application and/or other assembly is looking for the older version.

You can find more details about binding redirection in MSDN.

How to apply border color for TableLayoutPanel

Posted by & filed under .Net, .Net 4.0, Windows Forms.

The TableLayoutPanel control arranges its contents in a grid. TableLayoutPanel doesn’t have border color property, but you can write custom code in CellPaint event to create border. Here is the code snippet which will help you to create border and apply color for TableLayoutPanel

var panel = sender as TableLayoutPanel;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
var rectangle = e.CellBounds;
using (var pen = new Pen(Color.Black, 1))
{
    pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
    
    if (e.Row == (panel.RowCount - 1))
    {
        rectangle.Height -= 1;
    }

    if (e.Column == (panel.ColumnCount - 1))
    {
        rectangle.Width -= 1;
    }

    e.Graphics.DrawRectangle(pen, rectangle);
}

Here is the screen shot of the Form in Design Time

Form in Design Time

And in Runtime

Form in Runtime

Happy Coding

How to send email messages with embedded images

Posted by & filed under .Net, ASP.Net, CodeProject, Windows Forms.

While creating email messages with HTML content, normally the images are displayed with IMG tag, where the SRC attribute pointing to an image, which is hosted in the web server. Most email clients will not display the images, which is downloading from the web. Instead of pointing to web URL, you can embed image in the mail message with the help of LinkedResource and AlternateView classes.

Here is the snippet, which embed an image to the email. The convention to access linked resource is cid:name of the linked resource, which is the value of IMG tag SRC attribute.

var logo = new LinkedResource(@"C:\logo.jpg");
logo.ContentId = Guid.NewGuid().ToString();
var body = 
    string.Format(@"<html><body><h1>Image</h1><img src=""cid:{0}"" /></body></html>", 
    logo.ContentId);
var view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
view.LinkedResources.Add(logo);
using (var message = new MailMessage(fromAddress, toAddress)
{
    Subject = subject,
    Body = body,
    IsBodyHtml = true
})
{
    message.AlternateViews.Add(view);
    smtp.Send(message);
}

Note: This method will increase the size of the email, as the images are embedded.