FridayThe13th the Best JSON Parser for Silverlight and C#/.NET

Up until a couple of months ago I was writing most of my code using WPF. Recently, a project came up where Silverlight made more sense to use. I’d thought that wouldn’t be a problem since I’d just use JavaScriptSerializer [wrote about it here] like I did for my WPF project.

Uh oh. It turns out that Silverlight doesn’t have JavaScriptSerializer. Never fear! DataContractJsonSerializer is here! Or so I thought.

It turns out that if you want to use DataContractJsonSerializer you must actually create POCOs to backup this “data contract.” I didn’t want to do that.

I wanted to turn this…

{
	"some_number": 108.541,
	"date_time": "2011-04-13T15:34:09Z",
	"serial_number": "SN1234"
	"more_data": {
		"field1": 1.0
		"field2": "hello"
	}
}

into..

using System.Web.Script.Serialization;

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<dynamic>(jsonText);

Console.WriteLine(dict["some_number"]); //outputs 108.541
Console.WriteLine(dict["more_data"]["field2"]); //outputs hello

So I set out to write my own JSON parser. I call it FridayThe13th… how fitting huh? Now, using either Silverlight or .NET 4.0, you can parse the previous JSON into the following:

using FridayThe13th;

var jsonText = File.ReadAllText("mydata.json");

var jsp = new JsonParser(){CamelizeProperties = true};
dynamic json = jsp.Parse(jsonText);

Console.WriteLine(json.SomeNumber); //outputs 108.541
Console.WriteLine(json.MoreData.Field2); //outputs hello

Since I work with a lot of Ruby on Rails backends, I want to add a property “CamelizeProperties” to turn “some_number” into “SomeNumber”… it’s more .NET like.

Try it! You can find it on Github. Oh yeah… it’s also faster than that other .NET JSON library that everyone uses.

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

If you made it this far, read my blog on software entrepreneurship and follow me on Twitter: @jprichardson.

-JP

WPF Application Wide Exception Handling

What do you do if you want to catch all unhandled exceptions in an application?

In App.xaml:

<Application x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DispatcherUnhandledException="UnhandledException"
>

Add “DispatcherUnhandledException” to App.xaml. Then in your App.xaml.cs file:

private void UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
	var time = DateTime.Now;
	File.AppendAllText(@"C:\exps.csv", string.Format("{0},{1}", time, e.Exception.Message));
	File.AppendAllText(@"C:\sts.txt", time + ":\n" + e.Exception.StackTrace + "\n");
	e.Handled = false; //we want the user to experience the crash
}

That’s it. So now if the app crashes on your users, you don’t have to ask your users what steps they did to cause the crash. You can just look at the logs!

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter @jprichardson or read my blog on software entrepreneurship.

-JP

Forcing Single Instance for WPF Apps

Sometimes you may not want to allow multiple instances for your WPF apps. You can use a Mutex to accomplish this. Credit goes to this StackOverflow question: “What is the correct way to create a single instance application?” for mashing these ideas together.

public partial class App : Application
{
	[DllImport("user32.dll")]
	private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
	private const int SW_MAXIMIZE = 3;
	private const int SW_SHOWNORMAL = 1;

	private static Mutex singleInstanceMutex = new Mutex(true, "AnyUniqueStringToYourApp");

	protected override void OnStartup(StartupEventArgs e) {
		base.OnStartup(e);
		if (singleInstanceMutex.WaitOne(TimeSpan.Zero, true))
			Program.OnStartup();
		else {
			var procs = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
			foreach (var p in procs.Where(p => p.MainWindowHandle != IntPtr.Zero)) {
				ShowWindow(p.MainWindowHandle, SW_MAXIMIZE);
					Application.Current.Shutdown();
					return;
				}
			}	
		}
	}
}

The basic idea is that the startup code checks the mutex and maximizes the application if the app isn’t already open. You can view the MSDN docs for ShowWindow and pass any of the associated constants to alter the behavior of the window if it is already running.

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Read my blog on entrepreneurship and follow me on Twitter.

-JP

Including More than One ResourceDictionary in Your Xaml

I have one giant Xaml ResourceDictionary that’s becoming unwieldy to manage. The solution is simple. Use MergedDictionaries.

Snippet:

<Window.Resources>
	<ResourceDictionary>
		<ResourceDictionary.MergedDictionaries>
			<ResourceDictionary Source="FileResources1.xaml" />
			<ResourceDictionary Source="FileResources2.xaml" />
		</ResourceDictionary.MergedDictionaries>
	</ResourceDictionary>
</Window.Resources>

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter @jprichardson and read my blog on entrepreneurship.

-JP

StoryBoard: Animations in WPF

I recently discovered how to do animations in WPF. It’s super simple! So what if you want to create a mouse over animation on a StackPanel? You use the StoryBoard XAML element.
Snippet:

 <Storyboard x:Key="mouseFadeIn">
    <DoubleAnimation  
	Duration="0:0:5"  
	Storyboard.TargetName="myStackPanel"  
	Storyboard.TargetProperty="(UIElement.Opacity)"
	From="0.25"
	To="1.0"/>
</StoryBoard>

This will cause a the Opacity of the element to change from 0.25 to 1.0 over a period of 5 seconds. Note: this should be put in the “Resources” tag. So, if it’s a Window it would be “Window.Resources” or if it’s a UserControl it would be “UserControl.Resources”…
Snippet:

<UserControl.Resources>
  <StoryBoard key="blah">...

So how do we get this to trigger on a mouse over? By using Triggers of course!
Snippet:

<UserControl.Triggers>
	<EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="myStackPanel">
		<BeginStoryboard Storyboard="{StaticResource mouseFadeIn}" />
	</EventTrigger>
</UserControl.Triggers>

If you want to create a Fade Out effect, just use the “Mouse.MouseLeave” event and reverse the animation. You can even have multiple animations in a StoryBoard. They can run simultaneously or sequentially. If you have multiple animations in a StoryBoard and you want them to run sequentially, you need to add a “BeginTime” attribute. This ensures that the animation is executed after the previous animation(s).

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter: @jprichardson

-JP

Follow

Get every new post delivered to your Inbox.