Repeater Failure and Disappearance on Row 28

I was working on an ASP.net application (1.1) the other day, changing the UI display of a page. This page basically consisted of a Repeater being populated with data from the DB, and binding javascript actions and styling info to the different rows to be output (each overall it was producing a Table, and each item was a TableRow). Although the look-and-feel was going to be changing, as well as the manner in which the data was to be retrieved, the actual data set up and binding was to remain the same as it had been. Piece of cake, right?

The programming was straight-forward enough. When I first tested the feature on a few records, it worked fine. However, when I tested it on more records, it didn’t work. And when I say that it didn’t work, I am not saying that I got back some ugly .Net exception. I mean that the HTML output by the server was completely devoid of the Repeater element. It was as if it just did not exist. Somehow, when I tried the load the page with a large number of records,  some weired thing happened in IIS that just completely abandoned the rendering of the Repeater element without even providing an error message. Completely weird.

After a couple of hours of debugging, I was able to determine that the error was not related to any specific data item. Rather, it always happened when outputting the 28th DataItem in the Repeater. 27 worked fine. 28 killed it. Racking my brain (and Google), I couldn’t find any reason why this would be happening. This exact same repeater worked fine on other pages, on the live site. There was no reason I could think of why this type of failure would happen, and why it would happen here.

My coworker SeanS suggested that perhaps this was related to my dev environment, perhaps some faulty memory or something like that. There was nothing else to go on and this did explain what was going on (and I knew that the feature worked for <28 rows), so I proceeded with development. And lo and behold, when I uploaded my changes to the staging site yesterday, it worked with any number of rows without any hitch-up.

Moral of the story: weird things happen on web servers and on dev machines. Not every error that you get is related to code (especially if the error is reported by the absence of output rather than an exception). If something like this is happening to you (and it is not reproducible on other platforms), it may very well be environment-related. Test this out before wasting more time and energy trying to sort it out through the code.

Enumerating a Dictionary<> Object

In C# using .Net 2.0+, there is now built-in support for Generics collections using the System.Collections.Generic namespace. I use the List type most often, as a strongly-typed substitute for the ArrayList. Since it is strongly-typed, you now have design-time type-checking for enumerations like this (no casting necessary):

List<int> Foos = new List<int>();
foo.Add(new foo(1));
foo.Add(new foo(2));
foreach (foo f in Foos) {
  Console.PrintLine(f.ToString());
}

The second-most useful Generic (in my opinion) is Dictionary. This is a strongly-typed hashtable, where you can determine the types of both X (the Key) and Y (the Value). Like other Generic collections, the Dictionary object type is also Enumerable (meaning that you can use statements like foreach to automatically parse its contents in order). However, since there are two different types of value stored in a Generic Dictionary object, how do you call an strongly-typed enumeration statement like foreach? This is done by referencing each pair of values as a KeyValuePair object (which is another type of Generic supported by System.Collections.Generic”) and can be performed as follows (ref)

Dictionary<string, int> PhoneNumbers = new Dictionary<string, int>();
PhoneNumbers.Add("Jones, Jim", "800-555-2312");
PhoneNumbers.Add("Smith, Beth", "324-555-6742");
foreach(KeyValuePair<string, int> personNumber in PhoneNumbers) {
  Console.PrintLine(personNumber.Key + "\t" + personNumber.Value);
}

Declaring Custom Events in User Controls

I am constantly needing to search my code to find the exact syntax for how to do this, so for future reference (for myself and anyone else who finds this useful), to declare and call an event from a custom user control or inherited control:

public class CustomEventArgs : EventArgs {
  public CustomEventArgs(int propValue) {
    _propValue = propValue;
  }

  private int _propValue;
  public int PropValue {
    get { return _propValue; }
  }
}

public delegate void CustomEventHandler(object sender, CustomEventArgs e);
public event CustomEventHandler CustomEvent;

public void Function() {
  // Do Stuff
  if (CustomEvent != null) {
    CustomEventArgs e = new CustomEventArgs(x);
    CustomEvent(this, e);
  }
}

If you don’t need a CustomEventArgs class, just use the built-in EventArgs instead.

Capitalizing a string using C#

I was in need of a quick way to capitalize all of the words in a string (and though to check with Google before writing my own implementation). Here is what I found:

  1. This one is built-in to .Net, but can be slow at times (and some people do not like the way that it handles capitalizations of Unicode strings)
System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value);
  1. Based on Regular Expressions (2 examples found here)
  2. Some other home-baked implementations, mostly scanning through the string for whitespace, and capitalizing new words as they come up.

Am I missing anything?

Annoying Coding Practices

I am right now in the middle of transferring a piece of functionality from one project (ASP.net 1.1 web application) to a second project (Windows Forms desktop application). Although it is a significant feature, most of the work should be straight copy-paste. It is a large chunk of code written in C#, referencing a business object library shared between the two projects, a bunch of external dlls, etc.

Really, all that I should have to do is to customize the function for my projects codebase, migrate some of the ASP.net aspect to a WinForms environment, and hook it up to my UI. Yet, as I am going through this code, trying to make sense of what is going on, I find myself having to delete/modify/rewrite much more of the code than I should be doing. Although some of this is to be expected, much of it has to do with poor programming practices that if maintained lead to future difficulties with maintenance, poor readability, logic errors and bugs and are detrimental to debugging and testing. True, I have not found so many examples that are worthy of public exhibition, but I have received an education in how poor coding practices can effect a section of code long after the original programmer has completed his (or her) work.

A sampling of some of the things that are currently causing me grief:
Continue reading

WYSIWYG Editing of HTML in a Windows Forms Control

In a WinForms project that I am working on right now, I have text stored in HTML format in the database. I need a way for novice users to be able to edit this text using a WYSIWYG interface.

The most obvious choice for this in the Windows.Forms control library that is part of the .Net 2.0/3.0 framework is the RichTextBox control. This control gives you a textbox that has functionality similar to the WordPad application found in the Windows OS. It can display formatted pretty well. Aside from the fact that you have to handle all formatting of text in code, RichTextBox it has one major shortcomings: It can only input/output plain text or RTF encoded text. If I wanted to use a RichTextBox control to edit HTML, I would need some way to translate from the source HTML (stored in the DB) to RTF (to be displayed in the RichTextBox) and then back to HTML (to be stored again in the DB). Although I found some components from Sautin Software that seem to do the job, they cost money that I would rather not spend, and add a layer of complexity to my code library that I would rather avoid.

I found a couple of controls that extend the RichTextBox in order to allow input of HTML: An extended RichTextBox to save and load “HTML lite” files by Oscar Londoño (Code Project – For .Net 1.1/VS 2003) and RichTextBox that Displays XHTML by Eric Voreis. Both of these controls extend the RichTextBox control in the Windows.Forms library so that it can translate on the fly between RTF and HTML code (so you can input HTML code, see it displayed in the RTB and export HTML code). However, both are old and only support a small subset of HTML tags (although this can be extended in the source, it required knowledge of how RTF works). Also, since they use a RichTextBox control for editing and display, the display is similar but not identical to what you would get using a WebBrowser.

The next method that I found for providing this type of error is HTML Editor by Carl Nolan (Microsoft Consulting Services). This control (written in 2003 for .Net 1.1) modifies a WebBrowser control to allow inline editing and display of HTML. It is professionally written, provides support for many HTML tags and does just about everything that I need (and is free). The one problem is that it is pre-.Net 2.0. It uses a WebBrowser control from before this control was included as part of the Windows.Forms library in .Net 2.0 and thus has to reference Win32 calls and perform other types of acrobatics in order to get the control to function properly. This matters to me because it decreases portability of the control (using Mono, for instance), and makes it harder for me to customize and edit.

WebBrowser-based HTML Editor in action

The control that I am using in the end employs the same general idea used in HTML Editor, but takes advantage of new features (like the native WebBrowser class) provided by the .Net 2.0/3.0 framework and and Visual Studio 2005. A Windows Forms based text editor with HTML output by Kevin DeLafield uses a WebBrowser control with modified functionality to allow WYSIWYG display and editing of HTML text. It provides all of the functionality that I am looking for and allows for easy modifications and customizations in Visual Studio 2005. I recommend that anyone in need of similar functionality take a look at this control.