Mindscape WPF Elements

I stand by my racial slur.

The guys at Mindscape have released another WPF product call WPF Elements. This time it is a set of WPF controls aimed primarily at line of business apps: masked textboxes, numeric textboxes, date time pickers, a multi-column treeview, and more.

I have used a product of theirs call Lightspeed on a number of projects and Mindscape has always been really prompt when responding to queries. If you are developing business WPF applications then Elements is well worth checking out.

Json.NET 2.0 Beta 3 - Turkey Test Approved

I've just enrolled in a screenwriting class. I yearn to tell the story of an idealistic young Hindu, pushed too far by convenience store bandits. I call it 'Hands Off My Jerky, Turkey'. This post on handling different cultures in .NET really caught my imagination a couple of months back. Today I can proudly say that Json.NET passes the Turkey Test!

Aside from poultry, the main focus of this Json.NET release has been fixing all the little issues in the LINQ to JSON objects (JObject, JArray, JValue, etc). NCover has been a great help highlighting methods that didn't have any tests over the top of them. Test coverage has improved significantly in this release.

The JsonSerializer has also seen some changes. All reported bugs have been fixed and a couple of new features have been added. The most significant new feature is the JsonObjectAttribute. Placed on a class the JsonObjectAttribute lets you control whether properties are serialized by default (e.g. XmlSerializer behaviour) or whether you must explicitly include each property you want serialized with the JsonPropertyAttribute (e.g. WCF behaviour).

[JsonObject(MemberSerialization.OptIn)]
public class Person
{
  [JsonProperty]
  public string Name { get; set; }
 
  [JsonProperty]
  public DateTime BirthDate { get; set; }
 
  // not serialized
  public string Department { get; set; }
}

The default behaviour for classes without the attribute remains properties are serialized by default (opt-out).

Changes

  • New feature - Added JsonObjectAttribute with ability to opt-in or opt-out members by default.
  • New feature - Added Skip() method to JsonReader.
  • New feature - Added ObjectCreationHandling property to JsonSerializer.
  • Change - LOTS of little fixes and changes to the LINQ to JSON objects.
  • Change - CultureInfo is specified across Json.NET when converting objects to and from text.
  • Change - Improved behaviour of JsonReader.Depth property.
  • Change - GetSerializableMembers on JsonSerializer is now virtual.
  • Fix - Floating point numbers now use ToString("r") to avoid an overflow error when serializing and deserializing a boundary value.
  • Fix - JsonSerializer now correctly serializes and deserializes DBNull.
  • Fix - JsonSerializer no longer errors when skipping a multi-token JSON structure.
  • Fix - Clone a JToken if it already has a parent and is being added as a child to a new token

Json.NET CodePlex Project

Json.NET 2.0 Beta 3 Download - Json.NET source code and binaries

kick it on DotNetKicks.com

FormatWith 2.0 - String formatting with named variables

The problem with string formatting is that {0}, {1}, {2}, etc, aren't very descriptive. Figuring out what the numbers represent means either deducing their values from their usage context in the string or examining the arguments passed to String.Format. Things become more difficult when you are working with a format string stored in an external resource as the second option no longer available.

FormatWith 2.0

I have updated the original FormatWith with an overload that takes a single argument and allows the use of property names in the format string.

MembershipUser user = Membership.GetUser();
 
Status.Text = "{UserName} last logged in at {LastLoginDate}".FormatWith(user);

It also works with anonymous types:

"{CurrentTime} - {ProcessName}".FormatWith(new { CurrentTime = DateTime.Now, ProcessName = p.ProcessName });

And even allows for sub-properties and indexes:

var student = new
{
  Name = "John",
  Email = "john@roffle.edu",
  BirthDate = new DateTime(1983, 3, 20),
  Results = new[]
  {
    new { Name = "COMP101", Grade = 10 },
    new { Name = "ECON101", Grade = 9 }
  }
};
 
Console.WriteLine("Top result for {Name} was {Results[0].Name}".FormatWith(student));
// "Top result for John was COMP101"

There isn't much to the code itself. Most of the heavy lifting is done in a regular expression and the .NET DataBinder class.

To start with a regular expression picks all the {Property} blocks out of the string. The the property expression inside the brackets is then evaluated using the DataBinder class on the object argument to get the property value. That value is then put into a list of values and the {Property} block is replaced in the string with the index of the value in the list, e.g. {1}. Finally the rewritten string, which now looks like any other format string, and the list of evaluated values are passed to String.Format.

public static string FormatWith(this string format, object source)
{
  return FormatWith(format, null, source);
}
 
public static string FormatWith(this string format, IFormatProvider provider, object source)
{
  if (format == null)
    throw new ArgumentNullException("format");
 
  Regex r = new Regex(@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
    RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
 
  List<object> values = new List<object>();
  string rewrittenFormat = r.Replace(format, delegate(Match m)
  {
    Group startGroup = m.Groups["start"];
    Group propertyGroup = m.Groups["property"];
    Group formatGroup = m.Groups["format"];
    Group endGroup = m.Groups["end"];
 
    values.Add((propertyGroup.Value == "0")
      ? source
      : DataBinder.Eval(source, propertyGroup.Value));
 
    return new string('{', startGroup.Captures.Count) + (values.Count - 1) + formatGroup.Value
      + new string('}', endGroup.Captures.Count);
  });
 
  return string.Format(provider, rewrittenFormat, values.ToArray());
}

kick it on DotNetKicks.com

FormatWith - String.Format Extension Method

I have a love/hate relationship with String.Format.

On one hand it makes strings easier to read and they can easily be put in an external resource.

On the other hand every bloody time I want to use String.Format, I only realize when I am already halfway through writing the string. I find jumping back to the start to add String.Format is extremely annoying and that it breaks me out of my current train of thought.

FormatWith

FormatWith is an extension method that wraps String.Format. It is the first extension method I wrote and is probably the one I have used the most.

Logger.Write("CheckAccess result for {0} with privilege {1} is {2}.".FormatWith(userId, privilege, result));

An extension method with the same name as a static method on the class causes the C# compiler to get confused, which is the reason why I have called the method FormatWith rather than Format.

public static string FormatWith(this string format, params object[] args)
{
  if (format == null)
    throw new ArgumentNullException("format");
 
  return string.Format(format, args);
}
 
public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
{
  if (format == null)
    throw new ArgumentNullException("format");
 
  return string.Format(provider, format, args);
}

kick it on DotNetKicks.com

Update:

You may also be interested in FormatWith 2.0.