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);
}

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?

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.

Cannot Access a Disposed Object

In a Windows Forms application that I am working on, I had the following scenario: while the main form (Main.cs) is loading, I prompt the user to prove their credentials. If they are unable to do so, the form is closed (using this.close) and application execution is halted.

The problem is, when I first tried this, I an exception was thrown in Program.cs on the following line:

Application.Run(new Main());

The exception was of type System.ObjectDisposedException, and the accompanying message was “Cannot access a disposed object”.

What happened? According to the official documentation, the method System.Windows.Forms.Application.Run(Form) has the following purpose: “Begins running a standard application message loop on the current thread, and makes the specified form visible.” When this line of code is called, it first instantiates a new instance of the given Windows.Form implementation (in my case, Main.cs) and after it is instantiated, sets the Form.Visible parameter to true, thereby showing the form. In my case, during the instantiation of the form, the Close() method on the form was called, which disposes the Forms object. So when Program.cs attempts to set Main.Visible = true, Main is already disposed and the above error is thrown.

What is the workaround? I can think of two ways off the top of my head (the first one is the one that I ultimately used). Can you think of any others?

  1. Substitute the line in Program.cs with the following. Here the Main class is instantiated first, and only if it is still in existence and not disposed will Application.Run be called. Thus, if Main is closed during instantiation, Application.Run will never be called and the application will close on its own.
Main main = new Main();
if (main != null && !main.IsDisposed) {
  Application.Run(main);
}
  1. Do not call the user authentication code during the instantiation of the main Form of the application. Instead, call it in some event (like Activate) that is tied directly to the creation of the Form, but is not part of the initial instantiation code. In this case the class will instantiate, Application.Run will execute, and only after will the user authentication (and possible subsequent disposal of the form and exit from the application) take place.

.Net Encryption Simplified

Most of the projects that I work on require encryption of some form. Usually Symmetric (the kind where you can use the same password to both encrypt and decrypt), but sometimes asymmetric as well (where you encrypt with one password and decrypt with another). the .Net Framework has rich support for many different types of encryption algorithms, of varying methods and strengths, giving tons of options over how to run an exact implementation. However, one look at the System.Security.Cryptography namespace in the framework can end up leaving the novice user scratching his or her head over how exactly to proceed. Even individual implementation examples found on MSDN regarding individual algorithms are complicated pieces of code. Despite the wealth of code relating to this topic in the Framework, there is no one method (as far as I know) where you can simply put in data and a key, and receive encrypted text in response.
Continue reading

Porting .Net Assemblies to Mono using MoMA

For those who have not heard about it, Mono is a platform designed to allow porting of .Net-based applications to nearly every computing platform available (including Linux and Mac). It is open-source (sponsored by Novell) and is an essential tool for any developer who wishes to run .Net code on a non-Windows OS.

I am right now in the middle of a Desktop project being written with VS.net 2005, C# and Windows Forms technology. The powers-that-be (ie: the clients) have inquired to the feasibility of potentially porting over the code to Mac or Linux. My answer has been that if it is possible, we will have to use Mono to do it, but I cannot say anything more about its compatibility until more of the programming work is completed.

The process of porting over a completed .Net Assembly to Mono just got a bit easier. A tool called MoMA (Mono Migration Analyzer) has been released (written by Jonathan Pobst) that will do the following: given any .Net assembly (.dll or .exe file) it will go through the file and report back any potential issues that may arise using the assembly with Mono (most likely a .Net 2.0 feature that has not yet been implemented, or a calls to Win32 APIs that are not documented in the .Net API). Definitely a very helpful tool in debugging a .Net aseembly that refuses to compile in Mono.

Miguel de Icaza gives a more thorough step-by-step guide and review of his experiences using MoMA (though it doesn’t seem to be too complicated).