Always Get Better

Archive for the ‘C#’ Category

Display Class Objects in CheckedListBox

Sunday, March 28th, 2010

If you want to use anything more complex than a list of strings in a ListBox, you’re in luck because the control accepts all types of objects.

Custom Objects (Blog Posts) Displayed in a CheckListBox

Custom Objects (Blog Posts) Displayed in a CheckListBox

In this case, I want to display a list of posts found in a blog. Blog is a class which contains Posts, an array of Post classes. To start, I created the CheckedListBox in the form designer, and I add the posts to it like this:

clbPages.Items.AddRange(_blog.Posts);

If I do nothing else, the ListBox will call the Post’s ToString() method and will display as:

Post
Post
Post
Post

We have two options for displaying this correctly:

1. Override the ToString() method. I don’t recommend doing this because ToString() is much more appropriately used in a debugging context.

2. Add a string converter: This will automatically convert each post object to a usable string when called by an object like a ListBox. ListBox uses Convert.ToString() – this uses that converter more appropriately. ToString() should only be used as a fallback.

<pre>
// Use System for the Type object
using System;
// Use ComponentModel for the TypeConvert base class
using System.ComponentModel;

namespace SiteAssistant.Blog
{
    /// <summary>
    /// Converts a post into a list-friendly string, for checkbox lists
    /// </summary>
    class PostConverter : TypeConverter
    {
        /// <summary>
        /// Indicates whether the Post can be converted to a destination type
        /// </summary>
        /// <remarks>
        /// We only support conversions to STRING at present
        /// </remarks>
        /// <param name="context"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context,
            Type destinationType)
        {
            if (destinationType == typeof(string))
                return true;
            else
                return base.CanConvertTo(context, destinationType);
        }

        /// <summary>
        /// Converts the post to the destination type. If the destination
        /// type is not supported, the base Conversion is applied.
        /// </summary>
        /// <remarks>
        /// We only support converting posts to strings at present.
        /// </remarks>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context,
            System.Globalization.CultureInfo culture, object value,
            Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                string text = "";
                Post p = value as Post;
                // Ensure that the Post is not null, avoid errors
                if (null != p)
                {
                    text = p.Title;
                }
                return text;
            }
            else
            {
                return base.ConvertTo(context, culture, value, destinationType);
            }
        }
    }
}
</pre>

The code we write in .NET is like the meat inside a sandwich. The framework is the bread that wraps around our logic and keeps our application together. Our new Posts string converter will be called by the application without us needing to override the Convert function.

It doesn’t happen by magic of course. The final change we have to make is to add information about our conversion function to the posts class:

<pre>
    [System.ComponentModel.TypeConverter(typeof(PostConverter))]
    public class Post
    {
        // Rest of the code goes here
    }
</pre>

That’s all there is to it! Now we can pass a list of Posts to the CheckedListBox and manipulate each item directly. In this application, I will be using this technique to provide the Post object to the text editor with a double-click.

C#: using Statement

Thursday, May 14th, 2009

One of my absolute favourite statements in C# is the using statement (not to be confused with the using directive, which is what we use to import libraries like System.Web into our projects).

using forces us as programmers to be honest about releasing memory to the CLR. Whenever we use an unmanaged resource like an SQL connection or file IO handler, the garbage collector will eventually eliminate any open streams or connections associated with that resource. However, “eventually” doesn’t cut it when we’re dealing with SQL connections on a production server – we need to make sure the connections are released no later than when we’re done with them.

If you come from the C++ world, you’re probably (hopefully) used to calling delete to deallocate any memory you reserved. You also know that forgetting the delete (or delete [] on arrays) results in a memory leak. You might think of Dispose() as C#’s implementation of the delete statement.


using ( SqlCommand cmd = new SqlCommand( sqlStatement, sqlConnection ) )
{
// Do something
}

using acts as a try…catch…finally block, so if your code fails your object will still be disposed. The using statement keeps everything wrapped into a neat little package so you don’t forget to keep your local variables in scope.

Like I said, this is one of my favourite features in .NET (lock { } is similarly beautiful). You can use the same construct in VB as well.

Implementing Lazy Load Using a Proxy Class

Saturday, February 28th, 2009

Lazy load is a design pattern wherein an object is not instantiated until the last possible minute. This is very handy when working with lists of items whose contents are expensive to retrieve from the data store.

There are typically three ways of implementing lazy load:
1. Lazy Initialization – The object is set to null and checked/loaded when data is needed
2. Proxy – A proxy class for the object is created using the same interface as the original class; whenever a property is called, the proxy creates the object and returns the correct data
3. Ghost – The class loads only a partial set of its information until more is needed

Example Situation

In my example situation, we handling a catalogue of artists owned by a fictional record label. For each artist, we will store a name, musical genre, web site address, and number of albums.

UML for Artist Class

UML for Artist Class

Let’s pretend we have thousands of artists on our roster, and we need to print a catalogue containing all of their information. Rather than loading all of that data into memory right away and having to wait until that process is done before we can begin printing, it makes more sense to get a list of how many artists will be printed (so our software knows how many pages to print) but to only load the actual information when we are ready to print it.

The solution is to create an ArtistProxy class. ArtistProxy has an _artist variable who is set to null when it is initialized. Whenever we try to access the artist’s name, web site, etc from ArtistProxy, the class creates an Artist (only if not already done) and returns the property from _artist.

Our print function is never aware of ArtistProxy – as far as it is concerned it only ever deals with Artist. We accomplish this by creating an interface – IArtist – which acts as a contract for both ArtistProxy and Artist. If we add more properties to Artist later on, IArtist will keep us honest by forcing us to also update ArtistProxy.

Artist, ArtistProxy, and IArtist UML Diagram

Artist, ArtistProxy, and IArtist UML Diagram

Now that we understand how our classes relate to each other, it’s time to use them in code:

[source:csharp]
// Our printArtists() function looks something like this.
// Notice how we are unaware whether the artist is
// an actual object, or a whether it is a proxy.
public function printArtists( IArtist [] artistList )
{
foreach ( IArtist artist in artistList )
{
printOneArtist( artist );
}
}

// Implementation of the IArtist interface
public interface IArtist
{
string Name { get; set; }
string Genre { get; set; }
string Website { get; set; }
int getNumberOfAlbums();
}

// Implementation of Artist class
public class Artist : IArtist
{
private int _id;
private string _name;
private string _genre;
private string _website;

public Artist( id )
{
_id = id;
}

public string Name
{
get { return _name; }
set { _name = value; }
}

public string Genre
{
get { return _genre; }
set { _genre = value; }
}

public string Website
{
get { return _website; }
set { _website = value; }
}

public int getNumberOfAlbums()
{
return fictionalDataConnection->getNumberOfAlbums( _id );
}
}

// Implementation of ArtistProxy class
public class ArtistProxy : IArtist
{
private Artist _artist;
private int _id;

public ArtistProxy( id )
{
_artist = null;
_id = id;
}

public string Name
{
get
{
if ( null == _artist ) _artist = new Artist( _id );
return _artist.Name;
}
set
{
if ( null == _artist ) _artist = new Artist( _id );
_artist.Name = value;
}
}

public string Genre
{
get
{
if ( null == _artist ) _artist = new Artist( _id );
return _artist.Genre;
}
set
{
if ( null == _artist ) _artist = new Artist( _id );
_artist.Genre = value;
}
}

public string Website
{
get
{
if ( null == _artist ) _artist = new Artist( _id );
return _artist.Website;
}
set
{
if ( null == _artist ) _artist = new Artist( _id );
_artist.Website = value;
}
}

public int getNumberOfAlbums()
{
if ( null == _artist ) _artist = new Artist( _id );
return _artist.getNumberOfAlbums();
}
}
[/source]

Of course for the sake of convenience a few things are missing from my example:
1. An actual data source
2. Delegates (presumably one would include a ‘LoadArtist’ delegate so the proxy will be able to pass the actual loading of its artist to the data layer)

CommandEventHandler Event Won’t Fire for Button in ASP.NET Custom Control

Wednesday, September 24th, 2008

Problem: I created a custom control with a dynamic button and attached an event handler to that button.  When I run the control, clicking the button causes a postback but the event is not fired.

Solution: Changed the class inheritance from WebControl to CompositeControl.  Re-compiled and it worked like a charm.

Replacing / Adding Line Breaks in GridView Text

Tuesday, May 27th, 2008

The GridView is a powerful control for quickly and easily displaying tables of data. However, a raw dump of information is not always good – when displayed by a web browser, normal line breaks are simply rendered as spaces.

For long blocks of text, it may be desirable to have your GridView insert HTML line breaks into your data. This can be accomplished either programatically or declaratively.

Programatically

As a programmer, my first instinct is to try to solve the problem using code behind. I add a RowDataBound event handler to my GridView and create the command this way:

protected void gvMessageList_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridViewRow row = e.Row;
if (e.Row.RowType == DataControlRowType.DataRow)
{
row.Cells[2].Text = row.Cells[2].Text.Replace("\n", "<br />");
}
}

Although it works, it has several drawbacks:

  • This solution uses a magic number to cause the compiler to replace the third column in the row.  If the structure of the GridView were to change, this function may break
  • This solution requires the developer to be aware of the final layout of the GridView and to make the connection between the control’s declaration and its logical code.

Use The Design

By far, the better solution is to simply declare the formatting changes in the same place as the GridView.  Using a Template field, I can add line breaks to my message by adding this:

<%# Eval(“Message”).ToString().Replace(“\n”, “<br />”) %>

More Information

This solution assumes the contents of “Message” are not null.  For more information about this technique (including how to deal with null values), I recommend the ASP.NET message boards: http://forums.asp.net/p/1027728/1403884.aspx

C#: Using Suffixes to Declare Data Literals

Thursday, May 1st, 2008

This isn’t new, but handy to have.  In order to tell the compiler which data type we’re using, we use suffix notation as follows:

  • Unsigned integer, U: e.g. 34506U
  • Long integer (signed), L: e.g. 5297532L
  • Unsigned long integer, UL: e.g. 30958UL
  • Float, F: e.g. 13.6F
  • Double, D: e.g. 14.3D
  • Decimal, M: e.g. 19.95M

C#: Finding the Number of Days Between Two DateTime Items

Tuesday, April 29th, 2008

One very common requirement is for the number of days elapsed since a particular Date and Time. In C# this can be accomplished through the use of the TimeSpan class.

The easiest way to create a TimeSpan is like this:

[source:c#]
TimeSpan tsMySpan = DateTime.Now.Subtract( dtCompareTime );

// The number of days elapsed can be accessed like this:
// tsMySpan.Days
[/source]