Running the Microsoft .NET Stack on a Fresh MacBook Pro

Well, after parting ways with Flightdocs, one of the first things I needed to do was get my own laptop and get back to work. The days of spending $2,500–3000 on a nice machine under the generosity of the business were over, and I settled for a slightly smaller, less powerful, but still pricey little MacBook Pro for around $1,800. I suppose there are people in this world that dread setting up a new computer, but for me, it’s one of the best feelings. A brief pause of tranquility and then the rush of excitement that comes with a fresh start and new possibilities.

Since 2005, I’ve worked with .NET, and though at times I’ve cursed Microsoft for so many things, I always come back to C#. Yes, I proudly proclaim myself a polyglot developer who loves new languages, but there is comfort and confidence in the familiar. So, with that in mind, let’s get setup to build enterprise-grade .NET software on our sleek little budget-friendly-not-so-friendly MacBook Pro!

Installation Disclaimer

Not all of the following installations are required, but these are my recommendations for getting setup to be able to cover a variety of common development tasks.

Node.js and NPM

Package managers are fantastic, it’s weird to think that many of us didn’t use them hardly at all even a couple of years ago. I tend to use Node.js for a variety of web development tasks, but even if you’re not going down that route, having NPM is a great way to pull down web-frontend libraries now that bower is deprecated. Head to https://nodejs.orgto download a fresh copy.

XCode

Why XCode when installing Visual Studio? First, Visual Studio for Mac uses many of the Xamarin components which tied in to the development tools for XCode, creating a dependency. Second, you might as well sharpen those mobile skills or at least have a sandbox-knowledge of Swift/Objective C if you are a developer and own a Mac.

Microsoft Visual Studio for Mac

Look at that, I finally got to the part where we install Visual Studio. Head over to https://www.visualstudio.com/vs/visual-studio-mac/and get the bits. There should be a Community Edition that you can start with before shelling out any money. Also, many developers may not realize, but Microsoft does now offer monthly MSDN subscriptions which includes licensing for Professional/Enterprise versions of Visual Studio. Of course, I’m in favor of not spending any money at all if possible.

If you’re not familiar with Visual Studio, it’s a fairly rich (bulky) IDE for development, but the Mac version is quite a bit lighter than it’s Windows counterpart. In my opinion, it’s not as powerful or stable on Mac, but has quite a bit of charm. Since we’re in the Visual Studio for Mac section of this post, let’s briefly talk about Visual Studio Code as well. I recommend also installing Visual Studio Code from https://code.visualstudio.comeven if you don’t write in C# or another similar Microsoft-dominated language. It’s a solid code editor that rivals Sublime, Atom, or Brackets. Visual Studio Code is lightweight, very stable, and extremely extensible. Also, I frequently write my complex API code in the full blown Visual Studio IDE while writing my web application code in Visual Studio Code. Personal preference, I’m sure but I don’t think I’m alone in this combination.

At this point, you’ve got most of what you need to develop .NET applications on a Mac. However, if you actually want to persist any data in your application, you’ll likely need to setup a database.

It is pretty amazing how database offerings have changed in the past five or so years. You’ve got so many options on Linux/Unix based operating systems such as Postgres, MySql, Mongo, and tons more. But, if you’ve been working in MSSQL for the past decade+, you may be blown away to know you can run MSSQL on your Mac as well! Now would be a good time to check outside your window and see if you actually spot pigs flying.

SQLite and MS SQL

SQLite DB is available to run locally on your machine and it’s straight forward. If you’re using Entity Framework, simply point your connection string to a local file and initialize the database. However, if you want an IDE for accessing the data I tried DB Browser for SQLiteand it worked well for me.

Now, onto the really fun stuff — MSSQL on your Mac. You’ll need to install Dockerand a specific image for SQL Server which you can pull using the following command:

docker pull microsoft/mssql-server-linux

Once you’ve got Docker up and running and pulled down this image, you will need to step through a bit of configuration. Microsoft did a nice job of documenting this in the following link: https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker. I’ll wait while you spend the next 15 minutes working it through.

… Intermission …

Done? Fantastic, at this point you should be able to debug a nice WebAPI through Visual Studio for Mac pointing to a full MSSQL database running on Docker, and call everything from your web application that you’re editing through the lightweight Visual Studio Code. Did a few of you cringe at how many Microsoft products you used? Don’t stress! In a few years, the young new developers will start telling all of their Ruby and Python friends about this hot new open source language called C#.

Happy coding my fellow evil-empire-turned-friendly-open-source-contributerfriends.

Fun and Struggles with MVC – No Parameterless Constructor Defined

It’s taking a little while, but I’m starting to understand the magic behind model binding in MVC. It’s fairly simply to try it out while watching videos and tutorials that are out there; but when I applied it to our enterprise application with a fairly large collection of domain models that already exist, I had less than ideal results.

Here’s the struggle I was having…

The Problem

I have an entity called a SalesRep which has several properties including a few complex object properties such as EmailAddress , PersonName (struct), and Address (street1, street2, city, state, etc.) as well as many primitives.

I had both GET and POST Create actions defined in the SalesRepController as follows:

/// <summary>
/// Add a new sales rep.
/// </summary&rt;
/// <returns&rt;</returns&rt;
public ActionResult Create()
{
   return View(new SalesRep());
}

/// <summary>
/// Save a new sales rep.
/// </summary>
/// <param name="salesRep"></param>
/// <returns>If successful, the SalesRep/List/ View.  If not successful, the current SalesRep/Create/ view.</returns>
[HttpPost]
public ActionResult Create(SalesRep salesRep)
{
   var logic = new SalesLogic();
   logic.SaveSalesRep(ref salesRep);

   return RedirectToAction("List");
}

However, when calling the Create action on the SalesRepController, I would get the following Parameterless constructor error and could never even enter into a breakpoint.

No Parameterless Constructor Defined for this object

The Solution

After spending quite a bit of time experimenting and searching the internet, I couldn’t readily resolve the issue. Feeling as though I was never going to grasp MVC, and cursing the videos that looked so ridiculously easy, I spun up a new trivial sandbox project. I created new simplistic models, new controllers, and everything worked perfectly. So what made my old enterprise entity classes different? The answer was… the constructors.

As you can see in the above error message it is properly reporting that it could not find a parameterless constructor for the object; but which object? I had been looking at the SalesRep object and even the View and Controllers, but what I should have been looking at was the complex properties within the SalesRep as MVC recursively reflected all of the properties and created them with a parameterless constructor. In my case, we had an EmailAddress which specifies a single constructor:

public EmailAddress(string value) {
   //our code
}

It was while MVC was auto-magically wiring up the form elements to the email address object that the action came tumbling down.

A Simple Recreation

I’ve recreated this scenario using a simpler class slightly modified from Scott Allen’s pluralsight demo’s.

Below is a screenshot of my newly created Movie class which contains three properties; Name, Year, and Studio. Name and Year are both primitives, while Studio references another entity.

Movie Class

Here is the Studio class with the pertinent name parameter constructor only. There is no parameterless constructor in this class and because we have specified a constructor the default is overridden.

Studio Class

When we now reference this property within the Create View to allow for model binding we will encounter the error.

Movie View

We can correct this by adding a parameterless constructor in the Studio class and all is well again.

Catching up to MVC

Contrary to my nature, I’ve been reluctant to adopt the “latest and greatest” from Microsoft for the past twelve months or so. A good deal of my tech lag time has been due to my primary position leading an Oracle Enterprise Business Suite (EBS) project which has put me in the world of red, not blue. It’s been the unfamiliar – Oracle DB, Jdeveloper, and putty – that I’ve been working in more than anything made in Redmond lately. However, there is an equally valid reason – I’ve lost a bit of my Microsoft faith over the countless hours of podcasts, reading articles, and attending events which had left me completely unsure what Microsoft was doing (and questioning whether Microsoft knew as well). For quite a while it felt as though everything Microsoft created was tossed into the eco-system somewhat half-baked and what received the most buzz stuck. Perhaps this is Microsoft adopting some of the open source mentality that has been so hard on Microsoft in the past; perhaps it was simply to create a competitive nature internally at Microsoft; but to some critics, and even a handful of die-hard developers like myself, it seemed scattered and without direction.

There’s a bit more of a problem that I now understand more fully than when I was younger; time is not an infinite resource. Before I would jump whole-heartedly into a new technology learning with vigorous disregard of whether that technology would rise to the top or fall by the wayside. The cost was minimal; it only meant time away from things I probably shouldn’t be doing anyway.

Now that I have a daughter (as well as another on the way) and other family demands, I have to choose very carefully what my training time can go to. Should the focus be MVC, WP7, Silverlight, BizTalk (or gasp, Oracle SOA Suite), Entity Framework, jQuery, HTML5/CSS3, Azure, Denali, Kinect SDK, or any of the now vast array of Microsoft offerings available to developers?

So, as I’ve found myself occupied in other technologies, I rode the fence to see what shook out. It looks like Microsoft is finding their groove again and it’s time to brush aside the fallout and introduce the winner(s).

Welcome MVC to My Toolbox

As most of you know, MVC as a pattern has been around for quite a while. It is this reason that I originally waited to see if Microsoft’s implementation would survive or if the community would look to past MVC frameworks and decide to go back to something from the open source community or an established Java MVC implementation that would be ported over.

Obviously, that does not appear to be the case and Microsoft’s MVC implementation has been a huge success.

So now it’s time to get to work. I’ll be periodically posting about my learning process with MVC if any other developers are interested. There is a huge list of resources now available for MVC and as I post (or you comment), I will try and steer developers to what I consider the most useful.

Disclaimer and decisions made about the example material

Please note that there is still a plethora of examples showing simple MVC apps which I am intentionally choosing to not use in these blog posts. I am starting with a quite large project to accurately compare MVC to “the real world of enterprise applications”. I’ve also decided to employ logic and models via a service layer instead of directly in the MVC project. P.S. – way to go MVC for allowing this, it should be played up more in examples!

Also, in case you didn’t pick up on this earlier, but this is a learning journey for me with MVC – I am by no means an expert… yet.

Without further ado, here are my notes from the first foray into MVC with an enterprise application.

Project Orange (the anti-apple)

It’s not important what this project is, but it is intended to have multiple tiers where the web tier will be MVC. Let’s look at the setup of the projects:

Project Orange Projects

BusinessDataLogic is a combined BLL and DAL using entity framework.
Models are the business entities and DTO’s.
Services are WCF services which wrap the business logic and expose DTO’s.
Utilities are just helper classes that are common throughout the tiers (extension methods, etc.)
Web is MVC.

MVC Presentation Tier

Let’s take a closer look at the web application and the asset structure:

Project Orange MVC

As you can see, I’ve added a service reference for my WCF Inventory service. I’ve also added an ItemController and a corresponding View directory for Item.

I’ve added one new method within the ItemController for searching:

//
// GET: /Item/Search/had

public ActionResult Search(string text)
{
   var client = new InventoryService.InventoryClient();
   var items = client.SearchItems(1, 1, text);
   return View(items);
}

I’ve created a Search view which was auto-scaffolded based on the strongly typed model. The scaffolding is a nice feature and I can see this being extensible in the future.

Two things that I did get tripped up on for just a short while which required some trial and error was that I needed to create a new routing rule in global.asax to handle my Search action url format:

//Search Item
routes.MapRoute(
   "SearchItem",
   "{controller}/{action}/{text}",
   new { controller = "Item", action = "Search", text = UrlParameter.Optional }
);

I also discovered that _Layout.cshtml is essentially the masterpage (called a layout in MVC terms) and is auto-loaded by default from _ViewStart.cshtml.

That’s actually not a bad start for just opening up a project template and getting going, the wizard-style adding of files was very intuitive. Now it’s on to the resources to start learning more.

What Resources I’m Using This Week

Pluralsight: I’m finishing up the free MVC video on ASP.net and like the quality so much I’ve requested for our entire team to purchase seats through work. The catalog is certainly Microsoft-based but also has some “fringe” technology courses as well.

I’m not paid for any recommendation or traffic to Pluralsight, I just like their material.

HTML5 by Bruce Lawson and Remy Sharp: In line with using MVC, I think this is also an appropriate time to embrace HTML5 (as the rest of the world has gone crazy over it) as some of the HTML generated appears to be doctype’d for HTML5 in MVC as well now.

I did enroll in Amazon’s referral program, so there is a slight compensation for purchasing the book after clicking the image below.

TFS Management with Team Foundation Sidekicks 2010

Recently, I’ve had a series of unfortunate events regarding my development environment. I’ve had some hard drive issues, some difficulties with a VM that I had been working on, and so it goes. All of these problems led to a rebuild recently and the spin up of a brand new development environment.

Unfortunately, rebuilding your trusty dev environment is never as quick and easy as you think it will be and I was left with a few files orphaned from TFS in the old Workspace. If you’re not familiar with this, Team Foundation Server (TFS), the “best-more-than-just-source-control” source control, is Microsoft’s top of the line source control and project/build management software for development environments. When working with TFS, you use Workspaces which map a local directory on your machine to a server source control directory. All check-ins/check-outs are controlled and attached to the activity in this Workspace. Because these Workspaces are machine specific, if you abruptly change computers, you will need to create a new Workspace, and though the same user account can be used to attach to TFS and create the Workspace, you can (if you’re not careful, like I was unfortunately) leave files checked out to yourself in a different Workspace. Since this Workspace is no longer active (computer may be replaced), the Workspace is left in limbo.

There are of course ways to clean this up natively with TFS; however they are command line only tools. Now all true geeks should be comfortable working in command line, but to be perfectly honest, this activity is so rarely executed that it is much, much, much easier to do with a graphic tool called Team Foundation Sidekicks 2010 instead of returning back to documentation or Bing (noticed how I didn’t say Google).

So, without any further ado, let’s run through the quick tutorial of installing and using Sidekicks.

Step 1: Know Where to Get It

Mosey on over to Attrice to download the appropriate version. For TFS 2010, you will want Team Foundation Sidekicks 2010, for prior versions of TFS; you will want Team Foundation Sidekicks.

I will be installing 2010 in the following screenshots.

TFS Sidekicks 2010 Download

Step 2: Install and Configure to Your TFS

Now that you’ve downloaded the application, go ahead and install. No instruction necessary here, just run the install package.

Once you are up and going, you will be asked to Connect to a Team Foundation Server. Enter your server information and a valid administrator privileged TFS user account and password.

TFS Sidekick 2010 Connect to TFS Configuration

Step 3: Using Sidekicks

Sidekicks has several areas of TFS you can administer. See the screenshot below to view the Workspace, Status, History, Label, Shelveset, Users View, and Code Review options. To clean up my orphaned Workspace guess which option I will be selecting?

TFS Sidekick 2010 Modules

Once in the Workspace Sidekick, you can filter to find the appropriate Workspace(s) to administer. I searched by username and found three (one is my active Workspace created on the rebuilt development environment, the other two were from old environments that I had never cleaned out). I selected the two obsolete Workspaces and clicked the red X delete icon; done deal, pretty straight forward. Below is a screenshot of the Workspace Sidekick and my remaining active Workspace.

TFS 2010 Workspace Sidekick

Reviving Dependency Walker

If you haven’t noticed, I am a big fan of reviving the fanfare of some of the older development tools that are out there. Of course, there are constantly new tools released to help developers work smarter, faster, and more effectively – but often with all of the excitement over these new tools we forget about old standbys.

Dependency Walker is a tool that when you need it, you really need it. The fact that it is a free, lightweight download which doesn’t require an install to run is just added bonus.

The DLL Problem

We use a third-party DLL in our primary project at work which interacts with Progress. The problem is on a fresh system install and run, you receive the following error:

Could not load file or assembly or one of its dependencies

The dreaded “Could not load file or assembly or one of its dependencies.” The key here is the dependencies portion. I know the Progress.ssl.dll exists and is in the right directory, it compiles correctly, but a dependency inside this DLL is affecting the runtime execution.

How do I know what the dependency is?

Dependency Walker to the Rescue

First, we need to download Dependency Walker – go here: http://dependencywalker.com

Download Dependency Walker

Pick the appropriate version for your OS and take in the great retro-vibe of the website; it shows a little age doesn’t it!

After the download, simply unzip it to any directory on your computer and run depends.exe. Next, open the DLL that you are struggling with (Progress.ssl.dll in my case).

Dependency Walker Inspect DLL

Notice, the popup message and the yellow question marks next to DLL’s which have potential problems. In this particular case, MSVCR71.DLL is the culprit and needed to be copied into a directory in system path.

Here is another screenshot of the error for the DLL’s:

Dependency Walker Error Dependencies

After you’ve attempted to resolve the issue (and this may be different each time based on the particular scenario), refresh Dependency Walker to see if the dependent DLL is corrected or simply try your .NET project again and see if it works properly. In my case, MSVCR71.DLL was all that was needed and we were back on track.

If you have other “tried and true” tools that you still use today, please add them to the comments so we can keep them alive and maybe help a developer out!

Tips For Working With Enums

If you use enums frequently throughout code, you may be interested in the following code snippets. The first, is a fairly common extension method I’ve seen for getting descriptions from enum values (this is not my code and unfortunately, I can only site Google as the source).

/// <summary>
/// A collection of extension methods for enums.
/// </summary>
/// <typeparam name="T"></typeparam>
internal static class Enum<T>
{
	/// <summary>
	/// An extension method for enums to get the textual description of a specified enum value.
	/// </summary>
	/// <param name="value"></param>
	/// <returns></returns>
	internal static string GetDescription(T value)
	{
		var da = (DescriptionAttribute[])(typeof(T).GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false));
		return da.Length > 0 ? da[0].Description : value.ToString();
	}

	/// <summary>
	/// An extension method for enums to get the enum by textual description.
	/// </summary>
	/// <param name="value"></param>
	/// <param name="description"></param>
	/// <returns></returns>
	internal static string GetEnumName(Type value, string description)
	{
		FieldInfo[] fis = value.GetFields();
		foreach (FieldInfo fi in fis)
		{
			DescriptionAttribute[] attributes =
			  (DescriptionAttribute[])fi.GetCustomAttributes
			  (typeof(DescriptionAttribute), false);
			if (attributes.Length > 0)
			{
				if (attributes[0].Description == description)
				{
					return fi.Name;
				}
			}
		}
		return description;
	}
}

Samples

Let’s begin by setting up a very basic enum called MyEnum. Don’t forget to add using System.ComponentModel; to your using statements.

public enum MyEnum
{
	[Description("Red")]
	Red = 1,

	[Description("Blue")]
	Blue = 2,

	[Description("Green")]
	Green = 3
}

For the examples, I have created a small console app with the following Main() method:

static void Main(string[] args)
{
	//Setup enum value
	var enumVal = MyEnum.Blue;

	//TODO: Get enum description

	//TODO: Get enum integer

	//TODO: Parse enum from string
}

Get Enum Description

Next, let’s demonstrate how to retrieve the string description associated with the enum value using our new enum extension method.

//Get enum description
Console.WriteLine("Test getting description text from enum");
string enumText = Enum.GetDescription(MyEnum.Blue);
Console.WriteLine(enumText);
Console.ReadKey();

By running the console application, you should get “Blue”.

Get Enum Integer

Next, let’s simply get the integer value associated with the blue enum.

//Get enum integer
Console.WriteLine("Test getting integer from enum");
int enumInt = (int)enumVal;
Console.WriteLine(enumInt);
Console.ReadKey();

After running the console for getting enum integer, you should get “2”.

Parse Enum from String

Finally, let’s get an enum value from a matching string representation. This is actually a parse of string to enum. As a sidenote, if anyone knows of a cleaner way to do this please leave a comment. I’ve never been happy with how wordy and casting this is.

//Parse enum from string
string enumString = "Red";
var enumFromString = (MyEnum)Enum.Parse(typeof(MyEnum), enumString);
Console.WriteLine(enumFromString);
Console.ReadKey();

PhotoMemory WP7 App

The Basic Outline of Functionality

  1. Choose the difficulty mode to play in.
  2. Clear default picture values used in development.
  3. Set the board up based on the difficulty mode.
  4. Get personal photos from the phone.
  5. Shuffle photos and select appropriate number based on difficulty mode.
  6. Create pairs and shuffle all cards/photos.
  7. Display unturned cards and any already matched photos.
  8. Choose card and determine matches.
  9. Track number of moves and time.
  10. Display winner once all cards are matched.

PhotoMemory WP7 App

The Game Board (XAML)

The game board is basically a grid with several cells to hold the gradient cards or overturned photos. At the bottom, I keep track of number of moves and time expired.

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <toolkit:WrapPanel Grid.Row="0" x:Name="LayoutPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <Image Source="Images/1.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/2.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/3.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/6.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/4.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/1.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/2.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/7.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/8.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/5.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/9.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/3.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/4.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/6.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/7.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/8.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/9.jpg" Width="150" Margin="5"></Image>
            <Image Source="Images/5.jpg" Width="150" Margin="5"></Image>
        </toolkit:WrapPanel>

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Text="Moves:"></TextBlock>
            <TextBlock x:Name="MovesLabel" Foreground="Yellow" Text="0" Margin="10,0,0,0"></TextBlock>
            <TextBlock Text="Time:" Margin="50,0,0,0"></TextBlock>
            <TextBlock x:Name="TimeLabel" Foreground="Yellow" Text="0 seconds" Margin="10,0,0,0"></TextBlock>
        </StackPanel>
    </Grid>

PhotoMemory WP7 App

Highlighting a Few Areas of Development

Get Photos

A large part of the charm in this simple application is that it uses your own photos as the cards to match. I had pictures of my daughter and some wildlife we had taken while on a hiking trip (as well as some stock images that came with Windows 7) in my phone when I developed this app. Below is code to retrieve the photos from your phone – stored in MediaLibrary.

private List GetPhotos()
        {
            //Get photos from phone
            List photos = new List();
            var library = new MediaLibrary();
            var pics = library.Pictures.ToArray();

            //Shuffle user pics
            pics.Shuffle();

            //Loop through photos and add to game collection
            foreach (var pic in pics)
            {
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(pic.GetThumbnail());
                photos.Add(bmp);
            }

            //Check if enough photos are available
            if (photos.Count < _tileCount / 2)
            {
                //Setting default images if user does not have enough pictures of their own
                photos.Add(new BitmapImage(new Uri("Images/1.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/2.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/3.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/4.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/5.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/6.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/7.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/8.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/9.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/10.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/11.jpg", UriKind.Relative)));
                photos.Add(new BitmapImage(new Uri("Images/12.jpg", UriKind.Relative)));

                //Shuffle newly added photos as well
                photos.Shuffle();
            }
            
            return photos;
        }

Display Cards

This is the initial generation of the cards (gradients) and their corresponding actions once a user clicks on them.

private void DisplayCards()
        {
            foreach (var card in _collection.Cards)
            {
                var rect = new System.Windows.Shapes.Rectangle()
                {
                    Fill = new LinearGradientBrush(new GradientStopCollection()
                        {
                            new GradientStop()
                            {
                                Color = "#FF003366".ToColor(),
                                Offset = 0                                
                            },
                            new GradientStop()
                            {
                                Color = "#FF208FFF".ToColor(),
                                Offset = 1
                            },
                        }, 45
                    )
                    {
                        MappingMode = BrushMappingMode.RelativeToBoundingBox
                    },
                    Height = _cardHeight,
                    Margin = new Thickness(_margin),
                    Name = string.Format("rect_{0}", card.ID),
                    Stroke = new SolidColorBrush(Colors.White),
                    StrokeThickness = 2,
                    Width = _cardWidth,
                    Visibility = System.Windows.Visibility.Visible
                };

                rect.MouseLeftButtonUp += new MouseButtonEventHandler(ChooseCard);
                LayoutPanel.Children.Add(rect);

                var img = new Image()
                {
                    Height = _cardHeight,
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
                    Margin = new Thickness(_margin),
                    Name = string.Format("card_{0}", card.ID),
                    Source = card.Bitmap,
                    Width = _cardWidth,
                    VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
                    Visibility = System.Windows.Visibility.Collapsed
                };
                
                LayoutPanel.Children.Add(img);
            }
        }

Play a SoundEffect

This code snippet is all over the place on the internet and WP7 forums, but I thought I would include it here for completeness. In PhotoMemory, I play sound effects both in match and non-match scenarios and at the end when all cards are matched for a fun little “triumph”.

//Play failure sound
                            var snd = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/failed.wav"));
                            snd.Play();

Navigate to Another Page

Again, another simple snippet but this simply shows a way to navigate to another page within WP7 Silverlight.

this.NavigationService.Navigate(new Uri("/Game.xaml?mode=" + mode, UriKind.Relative));

Create and Use a DispatchTimer

Timers are very important in game/mobile development and using a DispatchTimer appears to be the simplest way to do it. Here I create a timer, set some variables such as the duration and what eventhandler to call, and then start the timer. After the timer has expired, the event is raised and I reset the flipped cards.

DispatcherTimer _cardTimer;

//Need to pause for 1 second before flipping back
                            _cardTimer = new DispatcherTimer();
                            _cardTimer.Interval = TimeSpan.FromSeconds(1);
                            _cardTimer.Tick += new EventHandler(FinishStudyingCards);
                            _cardTimer.Start();

void FinishStudyingCards(object sender, EventArgs e)
        {
            //Stop timer
            _cardTimer.Stop();

            //Flip cards back down after finished viewing
            FlipCard(_firstCard, FlipDirection.Down);
            FlipCard(_secondCard, FlipDirection.Down);

            //Allow user to try again
            _firstCard = null;
            _secondCard = null;
            _lock = false;
        }

PhotoMemory WP7 App

Submission

I would like to have a link to the application on Zune, however, because of complications with Microsoft my submission is still pending after more than a month. You can bet I will be writing a post on the submission process as well. Good luck, and have fun developing WP7 apps of your own!