Thursday, July 1, 2010

Cannot Build Expression Blend 4 / Silverlight 4 Project in Visual Studio 2010

Just had this problem: Trying to build an Expression Blend 4 Silverlight 4 project in Visual Studio 2010 on a machine that does not have Expression Blend 4 installed on it threw these errors:

The property 'Triggers' does not exist on the type 'Grid' in the XML namespace 'http://schemas.microsoft.com/expression/2010/interactivity'.   
The tag 'EventTrigger' does not exist in XML namespace '
http://schemas.microsoft.com/expression/2010/interactivity'.   
The tag 'ControlStoryboardAction' does not exist in XML namespace '
http://schemas.microsoft.com/expression/2010/interactions'.   
The tag 'EventTrigger' does not exist in XML namespace '
http://schemas.microsoft.com/expression/2010/interactivity'.   
The tag 'ControlStoryboardAction' does not exist in XML namespace '
http://schemas.microsoft.com/expression/2010/interactions'.   

In order to fix this, I just had to install the Microsoft Expression Blend Software Development Kit (SDK) for Silverlight 4

Wednesday, June 30, 2010

Unable To Open Silverlight 4 Project In Visual Studio 2010

Just had this issue: Opening a project created on another machine threw an error in Visual Studio 2010. The output window contained this message:

The imported project "C:\Program Files (x86)\MSBuild\Microsoft\Silverlight\v4.0\Microsoft.Silverlight.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

The problem is that I didn’t have the Microsoft Silverlight 4 Tools for Visual Studio 2010 installed. This can be downloaded from here: http://www.microsoft.com/downloads/details.aspx?FamilyID=eff8a0da-0a4d-48e8-8366-6ddf2ecad801&displaylang=en

Friday, June 11, 2010

Unable to start debugging. The Silverlight managed debugging package isn’t installed.

Just had this problem – Installed Visual Studio 2010 (which installs Silverlight 4), then used Visual Studio 2008 to open a Silverlight 3 project, tried to debug it, and POW!

silverlight_managed_debugging_package_not_installed

I fixed it by installing the Silverlight Windows Developer Runtime, as linked to from http://www.silverlight.net/getstarted/

Tuesday, April 6, 2010

Error inserting DBNull.Value into varbinary column

I have just experienced this problem: When attempting to insert DBNull.Value into a varbinary column, upon executing the insert statement the following exceptions is thrown:

”Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.”

I found the solution here: http://forums.asp.net/t/1250380.aspx

Essentially, in this case I needed to insert System.Data.SqlTypes.SqlBinary.Null instead. This resolved my problem.

Thursday, April 1, 2010

Nice Curves! - Catmull–Rom spline in C#

Download sample code

Suppose you have a series of points that define a region.

points

When you “join-the-dots” you end up with something that looks quite “pointy”.

lines

What if you want your region to look a little curvier than this?

Splines are a great way of calculating extra points between these key points to allow you to create much more organic and natural looking regions.

In this example I used a Catmull-Rom Spline to create curves from a limited set of points. Catmull-Rom is a good spline algorithm to use if you need the line to pass through the points that you define, but appear as curved as possible. It is quite often used for calculating camera tracks from key frames in the field of computer graphics.

The Catmull-Rom requires 4 points, and it calculates the spline points between the 2nd and 3rd points.

catmullrom_spline

The algorithm uses the 1st and 4th points as targets for the smoothing of the curve.

Here is the code to generate a single spline point from the list of key points.


/// <summary>
/// Calculates interpolated point between two points using Catmull-Rom Spline/// </summary>
/// <remarks>
/// Points calculated exist on the spline between points two and three./// </remarks>
/// <param name="p0">First Point</param>
/// <param name="p1">Second Point</param>
/// <param name="p2">Third Point</param>
/// <param name="p3">Fourth Point</param>
/// <param name="t">
/// Normalised distance between second and third point /// where the spline point will be calculated/// </param>
/// <returns>
/// Calculated Spline Point/// </returns>static public PointF PointOnCurve(PointF p0, PointF p1, PointF p2, PointF p3, float t)
{
    PointF ret = new PointF();

    float t2 = t * t;
    float t3 = t2 * t;

    ret.X = 0.5f * ((2.0f * p1.X) +
    (-p0.X + p2.X) * t +
    (2.0f * p0.X - 5.0f * p1.X + 4 * p2.X - p3.X) * t2 +
    (-p0.X + 3.0f * p1.X - 3.0f * p2.X + p3.X) * t3);

    ret.Y = 0.5f * ((2.0f * p1.Y) +
    (-p0.Y + p2.Y) * t +
    (2.0f * p0.Y - 5.0f * p1.Y + 4 * p2.Y - p3.Y) * t2 +
    (-p0.Y + 3.0f * p1.Y - 3.0f * p2.Y + p3.Y) * t3);

    return ret;
}

In order to use this function you must pass in the four points that describe the spline. The spline point itself is only generated between points 2 and 3. The parameter t is the normalised distance between points 2 and 3 for which we are calculating the spline point. This means that this is the distance on the arc between the 2nd and 3rd point on a scale of 0 to 1 - 0 being point 2 and 1 being point 3. For instance, a value of 0.5 will be half-way between points 2 and 3, 0.25 a quarter of the way, etc.

Therefore, in order to calculate the arc between points 2 and 3 to a resolution of 10 points, we will have to call this method 9 times with values of t of 0.1, 0.2, 0.3, 0.4 etc.

As is discussed in this Stack Overflow article, a better explanation of the maths behind Catmull-Rom splines is available here: http://www.mvps.org/directx/articles/catmull/

I have produced a sample application that allows the user to click within the window to create key points, and then hit the “Calculate” button to generate the spline points, which is then rendered as a continuous curve, intersecting each point.


catmullrom


Here is the example solution on Github.

Wednesday, March 31, 2010

Reading Images From SQL Server using SqlDataReader.GetBytes

Searching around on the internet I found it difficult to find some example C#/.NET code on using SqlDataReader.GetBytes to read image data from a varbinary field in a SQL Server 2008 database. Eventually I found a solution that worked for me, so I thought I would share it with the world.

My solution returns an IEnumerable<T> and uses yield allowing the handling of very large datasets, as each avatar object is returned as the SqlDataReader reads each row, rather than reading in all the rows and processing them all into image data at once.

Anyway, here is the code:

/// <summary>
///
Get Enumerable List Of Avatar Images From User Table
/// </summary>
/// <param name="connectionString">
///
Connection String For Database
/// </param>
/// <returns>
///
Enumerable List Of UserAvatar type.
/// </returns>
IEnumerable<UserAvatar> GetAvatarImages(string connectionString)
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();

using (var command = connection.CreateCommand())
{
command.CommandText = @"SELECT [ID], [Avatar] FROM [User] WHERE [Avatar] IS NOT NULL";

using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
//create a memory stream in which to write the raw data
using (var ms = new MemoryStream())
{
var buffer = new byte[1024];

//this call (with a null buffer paramater)
//will tell us the size of the data in the field
var dataSize = reader.GetBytes(1, 0, null, 0, 0);
var dataRemaining = dataSize;
while (dataRemaining > 0)
{
var bytesToRead = (int)(buffer.Length < dataRemaining ? buffer.Length : dataRemaining);
//fill the buffer
reader.GetBytes(1, dataSize - dataRemaining, buffer, 0, bytesToRead);
//write the buffer to the MemoryStream
ms.Write(buffer, 0, bytesToRead);
dataRemaining -= bytesToRead;
}

//Move the position of the MemoryStream
//Back to the beginning
ms.Seek(0, SeekOrigin.Begin);

//create a temporary placeholder image
//from the MemoryStream data
using (var tempImage = Image.FromStream(ms))
{
yield return new UserAvatar
{
ID = reader.GetInt32(0),
//Copy the temporary image data
//to a new bitmap. Disposing of
//this new bitmap becomes the
//responsibilty of the caller.
Image = new Bitmap(tempImage)
};
}
}
}
}
}
}
}