<$BlogRSDURL$>
My Blog Links
Site Links
Currently Reading
Blogroll
Archives
Tools
  • This page is powered by Blogger. Isn't yours?
  • Weblog Commenting and Trackback by HaloScan.com
  • 2RSS.com :: RSS directory
  • Listed on BlogShares
  • Blog Directory, Find A Blog, Submit A Blog, Search For The Best Blogs

Tuesday, August 31, 2004

.NET: More on Configuration Handlers 

After my last post on configuration, I looked into other configuration handlers and found Craig's - last config section handler you'll ever need. This is a cool handler because it maps a config section to a class in your assembly. When that section handler is parsed, your class is called to handle it. Therefore, you can create a strongly-typed class to handle reading and writing of the config section, and then use that class to access the config data at runtime.

Along with this post, I found another one by Phil Haack that extends Craig's handler (I guess it wasn't really the last one :) to provide the ability to listen to changes in the config entries, so that your class gets updated and your application can do something in response.

Both are very good examples of creating config section handlers. When I worked on some WinForms projects in the past, rather than using section handlers, I've used just a custom xml file to serialize my Config class into, but is in no way tied to config sections. I might post that as a simpler alternative for folks that don't want to deal with config handlers but do want to save application settings...


Monday, August 30, 2004

MISC: Finally on Gmail 

Thanks to Greg Duncan, I finally got an invitation for a Gmail account after several close calls. Google must be giving them out like candy these days, because after Greg's, I got two other invitations from other people.

And, it looks like Google wants me to hand some out, too. I have 2 Gmail invites for the first two people to leave comments on this post.

Friday, August 27, 2004

.NET: Creating Outlook Appointments in ASP.NET 

I don't usually post much on ASP.NET related topics. It's not something I work with very often, so I leave that for others to discuss. But, this topic was so cool, it even got my attention.

Eric Wise posted two articles on how to create outlook appointments from an ASP.NET page. With this code, you can create a webpage that will put any appointment you want onto the user's Outlook calendar. Pretty darn cool...

HowTo: Create an Outlook Appointment Item in ASP .NET
HowTo: Create an outlook appointment in ASP .NET Part II


Thursday, August 26, 2004

.NET: Custom Configuration Handler 

Here's a good description on how to create and use a custom configuration handler from within your Windows Form application. You can use this to save application settings data that's specific to your application, but do it in the same .config file that the .NET Framework uses to save it's settings information.

This post shows how to persist name value pairs and dictionaries, but you can also do other classes as well.

[via Kirk Allen Evans]

Saturday, August 21, 2004

BOOK: The Rule of Four 

The Rule of Four started off as a good book. I enjoyed the character development of Tom and Paul, the main protangonists in the novel. But, the authors left the other two friends more a background characters until the end - which was weird because they had important roles in the completion of the quest.

Tom and Paul's attempts to solve the riddles of the Hypnerotomachia were really interesting, and the way the authors showed the development of their relationship worked really well. You were always pulling for these to guys throughout the entire book. Plus there were the adults that were "helping" Paul in his search. They turned out to be using Paul in different ways. One trying to steal the secrets for himself and the other living vicariously through Paul as he gets closer to the answers he could never find.

Tom's struggle to pull away from the temptation of the book which consumed his father's life as well was gripping. The theme of trying to avoid repeating your father's mistakes and doing better resonated pretty well throughout the book. Including at the end, when Tom realized that by not following his passion for the book (the way his father had), he wasn't living his life to the fullest.

Spoilers:
I didn't really enjoy the ending though. With Paul's supposed death in the burning house, I felt like the secret would die with him. The book's secrets live on to tempt another generation. But, the final chapter reveals that Paul survived and moved to Italy to find the treasure trove laid out in the book. But, the authors don't explain why Paul let everyone believe he was dead for over 5 years. And, the whole disintegration of the four friends' relationships wasn't fully explained either. It left me wondering why Gil stopped talking to Charlie after his accident, why Gil went away never to be heard from again, etc.

Overall, it was a decent book. The start and build up in the book were good. The ending was mediocre.

Friday, August 20, 2004

.NET: Documentor Tool 

Tools are great. They remove some of the coding monotony we have to deal with on a daily basis, so I always like to forward on new tools (well new to me anyway). Alan Dean talked about Lutz Roeder's Documentor. It lets you preview what your XML comment will look like, once it's compiled, from the markup that you put in code.

I've used Lutz's other tool, .NET Reflector, but hadn't seen this one before. Looks very interesting, I can't wait to give it a try.

Tuesday, August 17, 2004

.NET: Best Kept Secrets in .NET 

Christopher Bowen posted a great list of tips and tricks for .NET and the VS IDE that you may not have seen. Go check it out -- there's some interesting stuff there.

Saturday, August 14, 2004

MISC: Ever Wonder What It Felt Like to be an Olympian? 

Well, Scott Goldblatt, a swimmer on the US 4x200m relay has set up a blog, a journal, and photo albums of his experience traveling to Greece, training, and hopefully what the competition means to him (and the rest of the US Swim team).

Although the journal doesn't have an RSS feed, I thought it was the most interesting section of the site, so I'll have to come back and check on his progress (even if it doesn't come up in my news aggregator).

Do you know of any other Olympic athletes that are blogging?

.NET: Programming Myths 

Here's an entertaining list of superstitions .NET developers sometimes have. Jim Arnold did a great job putting the list together. It's quite funny...

Tuesday, August 10, 2004

.NET: XML Serialization Base Class 

Working on WinForms applications, I've written several projects that persist information out to a file. I have found that using XML serialization to save and load the file is an easy way of mapping a class to an XML document.

Serialization in the .NET Framework is very powerful and really pretty easy to implement. Although multiple serializers are available, like XML, binary, text, etc, I've used the XML method most often. Therefore, I created a base class called XmlPersistedClass that I use in projects that want to read and write XML files. The class implements Save and Load methods which encapsulate all of the code required to interact with serializers, readers, and writers.

Here's what it looks like:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace MyClassLibrary
{
/// <summary>
/// XmlPersistedClass allows derieved classes to provide Save/Load functionality
/// to and from xml files. The methods are generic and can be overridden or
/// overloaded to provide type specific versions.
/// </summary>
[Serializable]
public abstract class XmlPersistedClass
{
/// <summary>
/// Default constructor -- required for serialization.
/// </summary>
public XmlPersistedClass()
{
}

/// <summary>
/// Saves this class to xml at the specified filename.
/// </summary>
/// <param name="pathFilename">Filename by which to save the class.</param>
/// <param name="classType">The type of the class to save.</param>
virtual public void Save(string pathFilename, Type classType)
{
// make sure the string and type are valid.
if (pathFilename == null || classType == null)
throw new ArgumentNullException();
if (pathFilename.Length < 1)
throw new ArgumentException();

// Create an instance of the XmlSerializer class; specify the type of object to serialize.
XmlSerializer serializer = new XmlSerializer(classType);
TextWriter writer
= new StreamWriter(pathFilename);

// Serialize this object, and close the TextWriter.
serializer.Serialize(writer, this);
writer.Close();
}

/// <summary>
/// Loads a class from xml at the specified filename.
/// </summary>
/// <param name="pathFilename">Filename from which to load the class</param>
/// <param name="classType">The expected type of the class to load.</param>
/// <returns>Returns the class with data loaded from the file.</returns>
static public object Load(string pathFilename, Type classType)
{
// make sure the string and type are valid.
if (pathFilename == null || classType == null)
throw new ArgumentNullException();
if (pathFilename.Length < 1)
throw new ArgumentException();

FileStream stream
= null;
try
{
// Create an instance of the XmlSerializer class;
specify the type of object to be deserialized.

XmlSerializer serializer = new XmlSerializer(classType);

// A FileStream is needed to read the XML document.
stream = new FileStream(pathFilename, FileMode.Open);
// Use the Deserialize method to restore the object's state with data from the XML document.
object objLoaded = serializer.Deserialize(stream);
stream.Close();
return objLoaded;
}
catch (FileNotFoundException)
{
// do nothing, but return null...
return null;
}
finally
{
if (stream != null)
{
stream.Close();
}
}
}
}
}


As you can see this is an abstract class, so that to use it you must derive your own class from it. The Save method instantiates an XmlSerializer with the specified class type, then uses a TextWriter to serialize this class into. The Load method also uses an XmlSerializer and then a TextReader to create an instance of the class from what has been saved in the file.

The following is an example of creating a derived class:
/// <summary>
/// Class that derives from XmlPersistedClass and adds properties to be
/// persisted. Then adds type-specific Load and Save methods.
/// </summary>
public class MyTestClass : XmlPersistedClass
{
// private members
private int number = 0;
private ArrayList list = new ArrayList();

// public properties
[XmlAttribute] public int Number
{
get { return number; }
set { number = value; }
}

[XmlArray]
public ArrayList List
{
get { return list; }
set { list = value; }
}
/// <summary>
/// Default constructor - required for serialization.
/// </summary>
public MyTestClass()
{
}

/// <summary>
/// Saves this class to the specified file.
/// </summary>
/// <param name="fileName">Full path to file.</param>
public virtual void Save(string fileName)
{
base.Save(fileName, typeof(MyTestClass));
}

/// <summary>
/// Loads a new instance of this class from the specified file.
/// </summary>
/// <param name="fileName">Full path to file.</param>
public static MyTestClass Load(string fileName)
{
return (MyTestClass)XmlPersistedClass.Load(fileName, typeof(MyTestClass));
}
}

In the code above, you'll notice that the [Serializable] attribute needs to be on the class, each property needs to have an XML serialization attribute as well, and you need a public default constructor for the class. If you don't specify an attribute for your property, then it defaults to [XmlElement]. However, [XmlAttribute], [XmlArray], and [XmlIgnore] are also very useful. Finally, XML serialization only persists property or data members that are public and have getters and setters. If your property doesn't follow these guidelines, then it won't be saved.

Usually, I overload the Save and Load methods to be type-specific rather than requiring types to be passed into those methods. Finally, this is a good example of methods that could really benefit from the Generics functionality coming out in Visual Studio 2005 -- at some point, I'll update the class to take advantage of that.

Monday, August 09, 2004

.NET: System Tray Applications 

Here's a quick tidbit from Matt Hawley. If you're writing a Windows app that minimizes to the system tray, he describes how to make that work so that users can't Alt+Tab to it.

Friday, August 06, 2004

MISC: Edit in Notepad Command 

Roland Weigelt recently posted a useful little registry file that lets you add an 'Edit in Notepad' menu item to the Windows Explorer right-click menu. This is a useful tool for being able to get a simple editor on any file on your hard-drive. Also, it shows how you could do this for other editors as well.

Thursday, August 05, 2004

MISC: Some Words Always Look Misspelled 

Is it just me or are there words that always look misspelled regards if they're correct or not? I was just writing something with the word inch in it. No matter how much I looked at it, the word just looked wrong.

Hmm... Maybe it IS just me.

Wednesday, August 04, 2004

BOOK: Wiki on Books and Authors 

I love reading and am a big fan of novels, so I was excited when a happened upon this wiki by chance: Bookshelved Wiki. This wiki allows users to search for book titles and authors and find what other readers think about that particular book or author. Anyone is allowed to update the wiki with their own comments.

There are lots of interesting comments on there about books of every type. And, if one doesn't exist, you can just create your own page for it. It also appears to allow user to create their own reading list, but I haven't had a chance to look into creating one of my own yet.

Tuesday, August 03, 2004

.NET: Loading Resource Strings in a ClassLibrary 

I just started working on a class library and one of the first things that came up was using a string resource from that assembly rather than a hard-coded string. It's always a good idea to start new projects with localization in mind, that way you don't have to go back and retroactively do it. To that end, I developed a little helper class that lets you find the resources in a class library.

using System;
using System.Resources;
using System.Globalization;

namespace MyClassLibrary
{
/// <summary>
/// Manages localized string resources for the DesignSurface.
/// </summary>
internal sealed class ResourceStringManager
{
/// <summary>
/// Constructor - for the singleton pattern it's made private.
/// </summary>
private ResourceStringManager()
{
}

static ResourceManager instance = null;

/// <summary>
/// Singleton ResourceManager for the class library assembly.
/// </summary>
internal static ResourceManager Instance
{
get
{
if (instance == null)
{
lock (typeof(ResourceStringManager))
{
if (instance == null)
{
instance = new ResourceManager("MyClassLibrary.Strings",
typeof(ResourceStringManager).Assembly);
}
}
}

return instance;
}
}

/// <summary>
/// Convenience method for retrieving a string from the Resource Manager
/// without having to specify the CultureInfo.
/// </summary>
/// <param name="id">String id to retrieve.</param>
/// <returns>String in resource.</returns>
internal static string GetString(string id)
{
return Instance.GetString(id, CultureInfo.CurrentUICulture);
}
}
}

The code is pretty straight-forward. It creates an instance of a ResourceManager based on the name of the .resource section in the assembly and the type of this class, which it uses to locate the assembly. Although this particular class is focused on retrieving strings from the resource file, you can actually retrieve any type of resource: strings, icons, bitmaps, etc. The other interesting attribute of this class is that it's implemented as a Singleton pattern.

You can use this class by calling:
string displayText = ResourceStringManager.Instance.GetString("MyResourceString"); 


You need to be sure that you've added a Strings.resx file to your project, added a resource string with the specified name ("MyResourceString"), and that you've done a full rebuild on the class library project. The full rebuild is sometimes needed because I've run into a couple of instances when just doing a build doesn't build in the resource file, if the project had been previously built without any resources in it.

I have used similar resource classes in the past, but since I just ran into this requirement again, I thought it would be a good topic to blog about.

Monday, August 02, 2004

BOOK: Eragon 

Eragon was based on an interesting premise -- a boy discovers a dragon's egg and when it hatches, he becomes a mythical dragon rider. Something that hasn't happened in hundreds of years. It's a typical Tolkien-esque fantasy novel where the journey from home to some distant land takes up the majority of the story and leads to most of the action in the book. The races are the standard fare - humans, elves, dwarves, and dragons. And, the book revolves mainly around the essence of the relationship between dragons and their human riders.

It was generally a good book and a light read, but there's nothing new or distinct in the novel. However, it was written by Christopher Paolini when he was in his teens, and it's much better than anything I could have ever dreamed up and delivered while I was in high school. And, I'm sure that each book in the series will become progressively better as his imagination and writing ability grow.