Using KnockoutJS with SignalR in ASP.NET MVC

KnockoutJS is a MVVM implementation for JavaScript written by Steve Sanderson, in my opinion the author of the best ASP.NET MVC textbooks available. Simply put it lets you bind a JavaScript object model to your HTML UI using a Read more

A MongoDB Tutorial using C# and ASP.NET MVC

In this post I'm going to create a simple ASP.NET MVC website for a simple blog that uses MongoDB and the offical 10gen C# driver. MongoDB is no NOSQL database that stores information as Binary JSON (BSON) in documents. I Read more

Linq To SQL Tutorial

Check out some of my other Linq to SQL posts: EntityBase Inheritance Modifiers with SQLMetal Linq to SQL with WCF Services Linq to SQL Framework (Repository/Business wrapper) ObjectDataSource binding with server side paging and sorting Load Options Generic Framework using reflection This is a basic tutorial for Read more

Enum description using reflection and extension methods

Posted on by Joe in C# | Leave a comment

I don’t take credit for this as it was written by another developer on the the project, but I thought it was good and worth writing about.

On the current project I’m working on we use a lot of enumerations for statuses which are shown in drop-down lists and grids. It can get a bit ugly from a UI perspective when simply using the ToString method as enumeration values cannot have spaces and are usually shortened for ease of use when coding.

One way to overcome this is to add a description attribute to each enumeration value and write an extension method that uses reflection to obtain the value in the description attribute.

The description attribute is part of the System.ComponentModel namespace so we need to import this.  The attribute value can then be set on each enumeration value:

public enum Status : int
{
    [Description("Application pending")]
    Pending = 0,
    [Description("Application received")]
    Received = 1,
    [Description("Application processing in progress")]
    Processing = 2,
    [Description("Application processed")]
    Processed = 3
}

The next step is to create the extension method.  Extension methods were introduced in  C# 3 and allow you to easily add new methods to existing types.  Scott Guthrie has a good blog post on them here.  Extensions methods need to be static, and contained in a static class.  In the method signature the ‘this’ keyword is used to indicate which type the extension method is for.  Below is the extension method that will get the description attribute for an enumeration using reflection.

public static string Description(this Enum enumeration)
{
    string value = enumeration.ToString();
    Type type = enumeration.GetType();
    //Use reflection to try and get the description attribute for the enumeration
    DescriptionAttribute[] descAttribute = (DescriptionAttribute[])type.GetField(value).GetCustomAttributes(typeof(DescriptionAttribute), false);
    return descAttribute.Length > 0 ? descAttribute[0].Description : value;
}

Any enumeration will now have a method called Description that will try to return the value of the description attribute, and if the attribute is not present return the result of calling ToString.  For example:

Console.WriteLine(Status.Processing.Description());

 
Will display:

exmethod1

As the extension method is for Enum, and not just the Status enumeration I created, we could do this:

Array values = Enum.GetValues(typeof(Status));
foreach (Enum e in values)
    Console.WriteLine("{0} - {1}", e, e.Description());

The result here would be:

exmethod2

There are lots of uses for extension methods which are used extensively with Linq, but I particularly like this idea to provide a more readable value for an enumeration.

Simple double click in Silverlight

Posted on by Joe in Silverlight | Leave a comment

I needed to pick up on a double click on an image in Silverlight but there is no event to handle this. It can be done quite easily using a DispatchTimer.  I am doing this for an image but you should be able to do it for any UIElement.

First I have imported the System.Windows.Theading namespace where the DispatchTimer lives.  In the constructor of the User Control containing the image I have instantiated the Timer and set its interval to 200 milliseconds, this is the amount of time allowed between clicks for it to be considered a double click.  I have also added a listener to the Tick event of the Timer which fires with each iteration.

 
using System.Windows.Threading;

public partial class Image : UserControl
{
    DispatcherTimer _timer;

    public Image()
    {
        InitializeComponent();

        _timer = new DispatcherTimer();
        _timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
        _timer.Tick += new EventHandler(_timer_Tick);
    }
}

My event handler for the Image’s MouseLeftButtonDown will check if the Timer has already been started, and if so we know this is a double click, if not we start the timer.  The first time the event is raised the timer won’t be started, but the second time, on the second click it will be so this is our double click.

private void imgImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (_timer.IsEnabled)
    {
        MessageBox.Show("Double Click");
    }
        else
    {
        _timer.Start();
    }
}

Finally I handle the Tick event of the Timer, and simply stop the timer so that after 200 milliseconds the timer is no longer active, and any subsequent clicks are not counted as the second click of a double click.

void _timer_Tick(object sender, EventArgs e)
{
    _timer.Stop();
}

This is a fairly basic and not very reusable but does the job for what I need.  You could also use the GetPosition property of MouseButtonEventArgs to make sure that the mouse hasn’t moved between clicks.

Setting the SelectedItem in a Silverlight TreeView

Posted on by Joe in Silverlight | 1 Comment

I wanted to select a specific item in my Silverlight TreeView programatically.  Looking at the TreeView.SelectedItem property the setter is not public so it cannot be done this way.

If you are simply adding TreeViewItems to the TreeView you can cast the item you want to select in the Items collection to a TreeViewItem and set the IsSelected property to true. The following example will grab the first item and set it to selected.

TreeViewItem item = tvDirectories.Items[0] as TreeViewItem;
item.IsSelected = true;

If you are binding a list of business objects to the TreeView this will not work as the Items collection will be a list of your object.  In this scenario you can use the ItemContainerGenerator property of the TreeView to get the underlying TreeViewItem.  In this example I have a collection of Gallery objects bound to my TreeView and am using the ContainerFromIndex method to get the TreeViewItem at position 0.

TreeViewItem item = tvDirectories.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;
item.IsSelected = true;

The ItemContainerGenerator class also has a ContainerFromItem method that will get the TreeViewItem by passing it an instance of the business object you want to select.

Gallery gallery = GetGallery(); //Some method that gets the object you want to select in the TreeView
TreeViewItem item = tvDirectories.ItemContainerGenerator.ContainerFromItem(gallery) as TreeViewItem;
item.IsSelected = true;

In my application I want to select the TreeViewItem based on the ServerPath of the Gallery object so I’m using some of the nifty Linq extension methods (Cast and Single) to get my business object.

public void SelectGallery(string serverPath)
{
    Gallery gallery = tvDirectories.Items.Cast<gallery>().Single(x => x.ServerPath.Equals(serverPath));
           
    if (gallery != null)
    {
        TreeViewItem item = tvDirectories.ItemContainerGenerator.ContainerFromItem(gallery) as TreeViewItem;
        item.IsSelected = true;
    }
}

Disable enter submitting form with JavaScript

Posted on by Joe in JavaScript | Leave a comment

On a project I was working on I was asked to disable the enter key submitting the form.  Usually it would be better just to ensure that hitting enter performed the correct action but if you do want to disable this you can do so with JavaScript.

I created a JavaScript function called disableEnterSubmit which takes in the event as a parameter as shown below.

function disableEnterSubmit(e)
{
    if (e.keyCode)
       return (e.keyCode != 13); //IE
    else
        return (e.which != 13); //FireFox
}

The event has different properties for the code of the pressed key for Internet Explorer and FireFox. In Internet Explorer we use e.keyCode and for FireFox it’s e.which.  The function simply returns false if the key is enter (key code 13).

I then just need to set the onkeydown event in the body tag of my HTML to call the method.

<body onkeydown="return disableEnterSubmit(event)">

Xbox 360 – Project Natal – No controller gaming?

Posted on by Joe in Xbox 360 | Leave a comment

Microsoft have announced Project Natal for Xbox 360.  It boasts controller-less gaming with face and voice recognition.  Obviously influenced by the Wii, the concept video does look interesting.  As a fan of the Skate and Skate 2 games the use of full motion body capture could be cool when it comes to skateboarding games, or it could be a complete flop. Will have to wait and see…

Alert, confirm and input message boxes in Silverlight

Posted on by Joe in Silverlight | Leave a comment

To use alert, confirm and input message boxes in Silverlight you need to import the following namespace.

using System.Windows.Browser;

You can then show an alert box by doing…

HtmlPage.Window.Alert("This is an alert")

Or a confirm dialog by doing…

if (HtmlPage.Window.Confirm("Are you sure you want to do something?"))
{
    //Do something
}

Or an input prompt by doing…

string name = HtmlPage.Window.Prompt("What is your name?");

Passing a byte array to a WCF method from Silverlight – The remote server returned an error: NotFound

Posted on by Joe in Silverlight | 8 Comments

My Silverlight application calls a method to get an image from the server as a byte array. When adding my Service Reference the ServiceReferences.ClientConfig automatically generated the binding’s MaxBufferSize and MaxRecievedMessageSize as 2147483647 which is a lot bigger than I want to I changed them to 5242880 (5MB).  When the application calls the service to bring down an image these values are used to limit the size of the response message.

I also set the MaxBufferSize and MaxRecievedMessageSize to 5242880 in the web.config file of the web application hosting my service.  At this point when I call the method in my service to upload an image passing a byte array I get a The remote server returned an error: NotFound error message, which really isn’t very helpful.

In this instance the problem is that the maximum array length for the XML reader has been exceeded. This can be fixed by expanding the binding section to insert a readerQuotas section and increase the maxArrayLength.

<services>
    <service behaviorConfiguration="GalleryServiceBehavior" name="GalleryService.GalleryService">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpLargeMessage" contract="GalleryService.IGalleryService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
</services>

<bindings>
    <basicHttpBinding>
        <binding name="basicHttpLargeMessage" maxReceivedMessageSize="5242880" maxBufferSize="5242880">
            <readerQuotas maxArrayLength="5242880" />
        </binding>
    </basicHttpBinding>
</bindings>

I can now upload and download files up to 5MB through my service.

Set Silverlight Image Source from byte array

Posted on by Joe in Silverlight | 12 Comments

I’ve been playing around with Silverlight and WCF services and I came across the need to set the Source of an Image control in Silverlight from a byte array. I have a service method which returns an image from the server as a byte array which I want to show in the Silverlight application.

My service method is simple and looks like this:

using System.IO;

public byte[] GetImage(string serverPath)
{
    return File.ReadAllBytes(serverPath);
}

In the Silverlight application I create a MemoryStream from the byte array, then a BitmapImage from the MemoryStream and set the image source to the BitmapImage.


using System.IO;
using System.Windows.Media.Imaging;

void proxy_GetImageCompleted(object sender, GetImageCompletedEventArgs e)
{
    MemoryStream stream = new MemoryStream(e.Result);
    BitmapImage b = new BitmapImage();
    b.SetSource(stream);
    imgImage.Source = b;
}

proxy_GetImageCompleted is the event handler for when my asynchronous call to GetImage completes, where e.Result is the byte array.

Wrapped Listbox items in Silverlight and WPF

Posted on by Joe in Silverlight, WCF | Leave a comment

I wanted to display a list of image thumbnails similar to how Windows Explorer does it so they are displayed horizontally and wrap onto the next line. The ListBox allows you to choose a template for the panel used to display items. The following XAML uses the WrapPanel for the ItemsPanelTemplate and gives the functionality I wanted.

<listBox x:Name="ImageList" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <listBox.ItemTemplate>
        <dataTemplate>
            <usrcntrl:Image ImageName="{Binding Name}" ServerPath="{Binding ServerPath}" />
        </dataTemplate>
    </listBox.ItemTemplate>
    <listBox.ItemsPanel>
        <itemsPanelTemplate>
            <controls:WrapPanel />
        </itemsPanelTemplate>
    </listBox.ItemsPanel>
</listBox>

I have also disabled the horizontal scroll bar so the images wrap to the next line.

Visual Studio closing when trying to choose items for the toolbox

Posted on by Joe in Visual Studio 2008 | Leave a comment

The other day I was trying to add new items to my toolbox in Visual Studio 2008 and each time Visual Studio would close itself without reason. I tried the Reset Toolbox option which didn’t solve the problem.

I then tried running Visual Studio in safe mode by choosing run from the start menu and typing ‘devenv /safemode’. In safe mode I was able to get the Choose Items dialog so I just flicked through all the tabs to make sure it was working. I then closed Visual Studio and loaded it normally and everything worked as expected.

Not sure why it happened but this seemed to fix it :)