<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET Adventures</title>
        <link>http://geekswithblogs.net/willemf/category/3175.aspx</link>
        <description>.NET development experiences and other blood-letting stories</description>
        <language>en-ZA</language>
        <copyright>Willem Fourie</copyright>
        <managingEditor>willemf@bware.biz</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Command UI Updating Windows Forms in C#</title>
            <link>http://geekswithblogs.net/willemf/archive/2007/06/05/113005.aspx</link>
            <description>&lt;p align="justify"&gt;MFC provides a rather neat way of updating the state of window elements in an MFC &lt;font face="Courier New" color="#0000ff"&gt;CWnd&lt;/font&gt; (or derived) object during application idle-time. Typically, this is done by setting the element ID and member function in the &lt;font face="Courier New" color="#0000ff"&gt;ON_UPDATE_COMMAND_UI&lt;/font&gt; macro, and then declaring the function in the class header file:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    afx_msg &lt;font color="#0000ff"&gt;void&lt;/font&gt; OnUpdateMyCommand(CCmdUI* pCmdUI);&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;Then you implement the handler as follows: &lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;&lt;font color="#0000ff"&gt;
    void&lt;/font&gt; CMyClass::OnUpdateMyCommand(CCmdUI* pCmdUI)
    {
      &lt;font color="#0000ff"&gt;if&lt;/font&gt;(IsMyCommandAvailable())
        pCmdUI-&amp;gt;Enable(TRUE);
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;This provides a mechanism to update the state of the UI element by passing &lt;font face="Courier New" color="#0000ff"&gt;TRUE&lt;/font&gt; or &lt;font face="Courier New" color="#0000ff"&gt;FALSE&lt;/font&gt; to the &lt;font face="Courier New" color="#0000ff"&gt;Enable&lt;/font&gt; function. The effect is that a toolbar button and a menu item with the same element IDs can be simultaneously updated with one state management function. Similarly, command execution can be routed through a similar mechanism, so that clicking the menu or the corresponding tool button results in a single (and the same) function being executed. &lt;/p&gt;
&lt;p align="justify"&gt;In the standard .NET &lt;font face="Courier New" color="#0000ff"&gt;System.Windows.Forms&lt;/font&gt; world, this functionality is not available out the box. In essence, the menu and button elements are managed separately, and require separate handlers for execution (the &lt;font face="Courier New" color="#0000ff"&gt;Click&lt;/font&gt; event), and no '&lt;font face="Courier New" color="#0000ff"&gt;OnUpdate..&lt;/font&gt;' type handlers are defined. For moderately complex  forms, separate handlers result in many handler methods which become difficult to manage, particularly as the handlers are added to the ended of the code module in a non-structured way.&lt;/p&gt;
&lt;p align="justify"&gt;This problem can be answered in a few ways. The links below are useful resources, and provide very flexible but ultimately over-complex solutions and implementation-patterns for many applications:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;&lt;a target="_blank" href="http://www.codeproject.com/useritems/UISwitchboard.asp"&gt;Command switchboard for windows forms&lt;/a&gt;, and&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/msdnmag/issues/02/10/CommandManagement/default.aspx"&gt;Use Design Patterns to Simplify the Relationship Between Menus and Form Elements in .NET&lt;/a&gt;.&lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;The following approach provides a mechanism (read: &lt;font face="Courier New" color="#0000ff"&gt;class&lt;/font&gt;) to provide something similar to the command and update handlers in MFC. The &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; class implemented provides the code to link together a &lt;font face="Courier New" color="#0000ff"&gt;ToolStripMenuItem&lt;/font&gt; menu item for use on a &lt;font face="Courier New" color="#0000ff"&gt;MenuStrip&lt;/font&gt; object, with a &lt;font face="Courier New" color="#0000ff"&gt;ToolStripMenuItem&lt;/font&gt; popup menu item for use on a &lt;font face="Courier New" color="#0000ff"&gt;ContextMenuStrip&lt;/font&gt;, and with a &lt;font face="Courier New" color="#0000ff"&gt;ToolStripButton&lt;/font&gt; toolbar button on a &lt;font face="Courier New" color="#0000ff"&gt;ToolStrip&lt;/font&gt; object. Furthermore, instead of linking the UI elements together with macros and element IDs, this implementation relies on correctly named elements set at design-time, which are then reflected and resolved at runtime, and linked together for the lifetime of the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; class instantiated to manage these elements together.&lt;/p&gt;
&lt;p align="justify"&gt;A &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; object is instantiated and added to the static list of commands to be managed:&lt;/p&gt;
&lt;font color="#2b91af"&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Commands.Add(&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, "&lt;/font&gt;&lt;font face="Courier New" color="#800000"&gt;CommandA&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;"));&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/font&gt;
&lt;p align="justify"&gt;The &lt;font face="Courier New" color="#0000ff"&gt;this&lt;/font&gt; parameter is the command target, and is normally the &lt;font face="Courier New" color="#0000ff"&gt;Form&lt;/font&gt; object which contains the UI elements.&lt;/p&gt;
&lt;p align="justify"&gt;The &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; class expects the "&lt;font face="Courier New" color="#0000ff"&gt;CommandA&lt;/font&gt;" implementation to be defined in the form code in the format &lt;font face="Courier New" color="#0000ff"&gt;On{Command}&lt;/font&gt;:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; OnCommandA(object sender, &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; e)
    {
      &lt;font color="#008000"&gt;// Implementation of Command A.&lt;/font&gt;
      ...
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;Similarly, the "&lt;font face="Courier New" color="#0000ff"&gt;CommandA&lt;/font&gt;" UI update implementation is defined in the form code in the format &lt;font face="Courier New" color="#0000ff"&gt;On{Command}UpdateUI&lt;/font&gt;:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; OnCommandAUpdateUI(object sender, &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; e)
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; command = (&lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;)sender;
      &lt;font color="#0000ff"&gt;if&lt;/font&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;.UseDefaultUpdateUIMethod)
      {
        command.DefaultUpdateUI(&lt;font color="#0000ff"&gt;this&lt;/font&gt;.IsCommand_A_Available);
      }
      &lt;font color="#0000ff"&gt;else&lt;/font&gt;
      {
        command.Button.Enabled = &lt;font color="#0000ff"&gt;this&lt;/font&gt;.IsCommand_A_Available;
        command.MenuItem.Enabled = &lt;font color="#0000ff"&gt;this&lt;/font&gt;.IsCommand_A_Available;
        command.PopupMenuItem.Enabled = &lt;font color="#0000ff"&gt;this&lt;/font&gt;.IsCommand_A_Available;
      }
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;Both the &lt;font face="Courier New" color="#0000ff"&gt;UseDefaultUpdateUIMethod&lt;/font&gt; and &lt;font face="Courier New" color="#0000ff"&gt;IsCommand_A_Available&lt;/font&gt; properties are provided by the &lt;font face="Courier New" color="#0000ff"&gt;Form&lt;/font&gt; object and provide the state of the form elements. Obviously, the appropriate state properties or methods have to be provided by the application programmer in a real application. &lt;/p&gt;
&lt;p align="justify"&gt;The &lt;font face="Courier New" color="#0000ff"&gt;Command.DefaultUpdateUI&lt;/font&gt; method provides the same functionality as that coded in the &lt;font face="Courier New" color="#0000ff"&gt;else&lt;/font&gt; section. The method is presented as above only to illustrate the various properties of the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; object.&lt;/p&gt;
&lt;p align="justify"&gt;In order to create and hookup &lt;font face="Courier New" color="#0000ff"&gt;delegate&lt;/font&gt;'s for the button and menu &lt;font face="Courier New" color="#0000ff"&gt;Click&lt;/font&gt; events, as well as the &lt;font face="Courier New" color="#0000ff"&gt;Command UpdateEventHandler&lt;/font&gt; event, the Form class is reflected and the UI elements are found from their names:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;the &lt;font face="Courier New" color="#0000ff"&gt;ToolStripButton&lt;/font&gt; button is found by searching for the name &lt;font face="Courier New" color="#0000ff"&gt;{Command}Button&lt;/font&gt;. For the above example the actual name would be "&lt;font face="Courier New" color="#0000ff"&gt;CommandAButton&lt;/font&gt;",&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;the &lt;font face="Courier New" color="#0000ff"&gt;ToolStripMenuItem&lt;/font&gt; menu item is found from &lt;font face="Courier New" color="#0000ff"&gt;{Command}MenuItem&lt;/font&gt;, or "&lt;font face="Courier New" color="#0000ff"&gt;CommandAMenuItem&lt;/font&gt;" in the example, and&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;the &lt;font face="Courier New" color="#0000ff"&gt;ToolStripMenuItem&lt;/font&gt;  popup menu item is &lt;font face="Courier New" color="#0000ff"&gt;{Command}PopupMenuItem&lt;/font&gt;, or "&lt;font face="Courier New" color="#0000ff"&gt;CommandAPopupMenuItem&lt;/font&gt;" in the example.&lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;&lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; provides a method to find the UI button element:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;ToolStripButton&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; FindButton(&lt;font color="#0000ff"&gt;string&lt;/font&gt; buttonName)
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;FieldInfo&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; buttonInfo = Target.GetType().GetField(
        buttonName,
        &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.IgnoreCase 
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Instance
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.NonPublic
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Public);
      &lt;font color="#0000ff"&gt;if&lt;/font&gt; (buttonInfo != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
      {
        &lt;font color="#0000ff"&gt;return&lt;/font&gt; buttonInfo.GetValue(Target) as &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;ToolStripButton&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;;
      }
      &lt;font color="#0000ff"&gt;return&lt;/font&gt; &lt;font color="#0000ff"&gt;null&lt;/font&gt;;
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;where &lt;font face="Courier New" color="#0000ff"&gt;Target&lt;/font&gt; is the &lt;font face="Courier New" color="#0000ff"&gt;Form&lt;/font&gt; object used to construct the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; object. Similarly, the menu items can also be found.&lt;/p&gt;
&lt;p align="justify"&gt;Once the UI element objects are found, their event handler delegates can be set (or removed) by creating new delegate instances from the required method:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; CreateEventHandler(
      &lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;object&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; target,
      &lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;object&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; component,
      &lt;font color="#0000ff"&gt;string&lt;/font&gt; eventName,
      &lt;font color="#0000ff"&gt;string&lt;/font&gt; handlerName,
      &lt;font color="#0000ff"&gt;bool&lt;/font&gt; add)
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;MethodInfo&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; methodInfo = target.GetType().GetMethod(
        handlerName,
        &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.IgnoreCase
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Instance
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.NonPublic
        | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Public);
      &lt;font color="#0000ff"&gt;if&lt;/font&gt; (methodInfo != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
      {
        &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventInfo&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; eventInfo = component.GetType().GetEvent(
          eventName,
          &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.IgnoreCase
          | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Instance
          | &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;BindingFlags&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Public);
        &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Delegate&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; eventDelegate = &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Delegate&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.CreateDelegate(
          &lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;typeof&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;(&lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventHandler&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;), target, methodInfo);
        &lt;font color="#0000ff"&gt;if&lt;/font&gt; (add)
        {
          eventInfo.AddEventHandler(component, eventDelegate);
        }
        &lt;font color="#0000ff"&gt;else&lt;/font&gt;
        {
          eventInfo.RemoveEventHandler(component, eventDelegate);
        }
      }
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;Note that the methods to be used as handlers are required to have the same signature as that required by the &lt;font face="Courier New" color="#0000ff"&gt;EventHandler&lt;/font&gt;:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;&lt;font color="#0000ff"&gt;
    void&lt;/font&gt; MyEventHandler(&lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;object&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; sender, &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; e) { ... }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;Note also that the searches for variable fields, methods and events are conducted ignoring the case of the names, such that '&lt;font face="Courier New" color="#0000ff"&gt;myEventHandler&lt;/font&gt;' and '&lt;font face="Courier New" color="#0000ff"&gt;MyEventHandler&lt;/font&gt;' will both refer to the same construct.&lt;/p&gt;
&lt;p align="justify"&gt;&lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; provides a UI update method which will call the UI update handler if defined by the &lt;font face="Courier New" color="#0000ff"&gt;Form&lt;/font&gt; as per the requirement above:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;event&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventHandler&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; UpdateEventHandler;
    &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Update()
    {
      &lt;font color="#0000ff"&gt;if&lt;/font&gt; (UpdateEventHandler != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
      {
        UpdateEventHandler(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Empty);
      }
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Finally, all the Command's are updated as follows:&lt;/p&gt;
&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; UpdateCommands()
    {
      &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (&lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; command &lt;font color="#0000ff"&gt;in&lt;/font&gt; Commands)
      {
        command.Update();
      }
    }&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p align="justify"&gt;So,  you ask, how do I get this working in my application?&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;First, provide a reference to the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; class by adding the C# file to your &lt;font face="Courier New" color="#0000ff"&gt;Windows.Forms&lt;/font&gt; application project, or reference it as a class library.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;Add the required UI elements to the form and name them appropriately.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;Add the required implementation handler and UI update handler to the code and name them appropriately.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;In the Form constructor after the &lt;font face="Courier New" color="#0000ff"&gt;InitializeComponent&lt;/font&gt; method add the following line for each Command (in the example the command is named "&lt;font face="Courier New" color="#0000ff"&gt;CommandA&lt;/font&gt;": &lt;/p&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;
                &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Commands.Add(&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, "&lt;/font&gt;&lt;font face="Courier New" color="#800000"&gt;CommandA&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;"));&lt;/font&gt;&lt;/pre&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p&gt;Add an update method to the form which is called by the &lt;font face="Courier New" color="#0000ff"&gt;Application&lt;/font&gt; when it is idle. This method then updates all the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; object in use: &lt;/p&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;
                &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;
    &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; IdleUpdate()
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Command&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.UpdateCommands();
    }&lt;/font&gt;&lt;/pre&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/li&gt;
    &lt;li&gt;
    &lt;p align="justify"&gt;Replace the &lt;font face="Courier New" color="#0000ff"&gt;Program&lt;/font&gt; class in &lt;em&gt;Program.cs&lt;/em&gt; (.NET 2.0+), as follows: &lt;/p&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;
                &lt;div align="justify"&gt;
                &lt;pre&gt;&lt;font face="Courier New" color="#000000"&gt;  &lt;font color="#0000ff"&gt;
  static&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; Program
  {
&lt;/font&gt;&lt;font face="Courier New" color="#808080"&gt;    &lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;&lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/font&gt;
    &lt;font color="#008000"&gt;/// The main entry point for the application.&lt;/font&gt;
&lt;/font&gt;&lt;font face="Courier New" color="#808080"&gt;    &lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;&lt;font color="#808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/font&gt;
    [STAThread]
    &lt;font color="#008000"&gt;//static void Main()&lt;/font&gt;
    &lt;font color="#008000"&gt;//{&lt;/font&gt;
    &lt;font color="#008000"&gt;//    Application.EnableVisualStyles();&lt;/font&gt;
    &lt;font color="#008000"&gt;//    Application.SetCompatibleTextRenderingDefault(false);&lt;/font&gt;
    &lt;font color="#008000"&gt;//    Application.Run(new Form1());&lt;/font&gt;
    &lt;font color="#008000"&gt;//}&lt;/font&gt;
    &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Main()
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.ApplicationExit += &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventHandler&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;(Application_ApplicationExit);
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.EnableVisualStyles();
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.SetCompatibleTextRenderingDefault(&lt;font color="#0000ff"&gt;false&lt;/font&gt;);
      form1 = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Form1&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;();
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Idle += OnApplicationIdle;
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Run(form1);
    }
    &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Form1&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; form1;
    &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventHandler&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; OnApplicationIdle = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventHandler&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;(Application_Idle);
    &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Application_Idle(object sender, EventArgs e)
    {
      form1.IdleUpdate();
    }
    &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Application_ApplicationExit(&lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;object&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; sender, &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt; e)
    {
      &lt;/font&gt;&lt;font face="Courier New" color="#2b91af"&gt;Application&lt;/font&gt;&lt;font face="Courier New" color="#000000"&gt;.Idle -= OnApplicationIdle;
    }
  }&lt;/font&gt;&lt;/pre&gt;
                &lt;/div&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;p align="justify"&gt;The C# source-code for the &lt;font face="Courier New" color="#0000ff"&gt;Command&lt;/font&gt; class and a sample forms application is provided in a Visual Studio 2005 .NET 2.0 solution and can be downloaded from the link below:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://www.bware.biz/DotNet/Development/FormCommand/FormCommand.zip"&gt;FormCommand source code (.zip file)&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113005"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113005" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/113005.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2007/06/05/113005.aspx</guid>
            <pubDate>Tue, 05 Jun 2007 17:53:18 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/113005.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2007/06/05/113005.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/113005.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/113005.aspx</trackback:ping>
        </item>
        <item>
            <title>spy.doc 2007.1 XML-Schema Documenter released (Freeware)</title>
            <link>http://geekswithblogs.net/willemf/archive/2007/01/19/103963.aspx</link>
            <description>&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/spy.doc" target=_blank&gt;spy.doc Home Page&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.bware.biz/spy.doc/download.htm" target=_blank&gt;spy.doc Download Page&lt;/A&gt; - spy.doc is released under a Freeware license&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;spy.doc documents XML-schemas using the Altova® XMLSpy® XML-schema documentation format to produce Microsoft® HTML Help documentation (.chm) files that feature auto-generated Table-of-contents, Index, and full-text search. By providing suitably coded plugins, the documentation output can be greatly extended and enhanced.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Features&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Windows, Console and Launcher applications. 
&lt;LI&gt;Uses an XML-base project file (extension .spydoc) which can be easily edited to change application and generation settings. 
&lt;LI&gt;Generates complete XMLSPY® HTML documentation for XML-schemas in an HTML Help file format. 
&lt;LI&gt;Provides the same documentation settings for schema construct type, and details as provided by XMLSPY®, and also the means to order the documentation sections differently on the HTML page to the standard order provided by XMLSPY®. 
&lt;LI&gt;HTML Help file is automatically generated, with complete table-of-contents, HTML content page-title based indexing, and full-text search. 
&lt;LI&gt;HTML Help file is high performance, as each content page corresponds to a documentation section in the original XMLSPY® HTML documentation file. 
&lt;LI&gt;Page header and footer for documentation pages can be completely user-defined. 
&lt;LI&gt;The HTML page style is generated in a separate style-sheet (.css) file, allowing the styles to be easily edited in one place. 
&lt;LI&gt;A separate HTML page may be defined for the HTML Help file start-page and home-page. 
&lt;LI&gt;The HTML Help project file is totally user-defined with replacable parameters that are provided by the application. The HTML Help project file is input into the application as a template, from which the target .hhp file is generated which can be directly compiled. &lt;BR&gt;Automatically generates H2 and SandCastle document set name tags, which can be used for document set filtering in combined help documentation sets. 
&lt;LI&gt;Provides options to retain all intermediate and temporary files, and to generate only the HTML Help build files (.hhc, .hhk, .hhp) files, so that the .chm file can easily be rebuild without having to regenerate the entire documentation set. 
&lt;LI&gt;Provides for the application of user-coded plug-ins to enhance and extend the existing documentation. 
&lt;LI&gt;Can generate complete documentation for large schema-sets that cannot be generated directly in one iteration by XMLSPY®. 
&lt;LI&gt;No restriction on the size of the documentation, other than that imposed by the HTML Help service itself.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Function&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Motivation&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;As the use of XML as the protocol for information interfaces is becoming more common and accepted in the industry, two important facts are emerging:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The W3C consortium XML-schema or XSD-standard is the major standard for describing the structure and syntax of XML data. 
&lt;LI&gt;More than ever, these XML-schemas are becoming huge, complex and more resource-intensive, both in human- and computer- terms.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;An important part of managing and utilizing large schema sets is to provide comprehensive and easy-to-use documentation describing the schemas. Altova® XMLSpy® provides a handy capability to do this, in both a Microsoft® Word format and an HTML format. The advantage of the HTML documentation is that it can be easily published, as well as providing the following additional important advantages:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The documentation provides XML-schema structure description using diagrams. The diagram constructs used have become a de-facto industry standard in terms of schema documentation. The HTML page also provides hot-spots within the diagrams that provide easy navigation between schema documentation constructs. 
&lt;LI&gt;The documentation text is easy to understand and is comprehensive. 
&lt;LI&gt;'Type' and 'Used By' sections provide easy navigation around the documentation in terms of parent-child relationships. 
&lt;LI&gt;Most importantly, the documentation is generated automatically, with very little user intervention.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;However, when the schema(-sets) get moderately complex, the HTML documentation is inadequate, for the following reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The documentation takes the form of a single page, the size of which can easily be in excess of a few megabytes.&amp;nbsp; This results in a slower loading page in the browser, the page navigation performance of the loaded page is poor, and the user experience is substantially degraded. For very large schemas, the page is often unable to load and even causes the browser to throw an exception. 
&lt;LI&gt;The documentation has a very simple indexing section at the top of the page, which is not efficient. It has no real table-of-contents, keyword index, or full-text search, which becomes more important as the size of the documentation increases. 
&lt;LI&gt;For many large schema-sets, it is impossible to generate the complete documentation, as XMLSPY® throws a memory exception and hangs up.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;U&gt;How it works&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;The spy.doc application takes as input the HTML page generated by the XMLSpy® XML-schema 'Generate Documentation' command, and outputs a fully-featured compiled HTML Help (.chm) file. spy.doc functionality includes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;utilizing the XMLSPY® documentation 'standard' completely; 
&lt;LI&gt;automatically executes XMLSPY® via the XMLSPYLIB automation interface and generates documentation according to user-presets; 
&lt;LI&gt;splits the generated single HTML documentation page into separate HTML pages; 
&lt;LI&gt;builds an HTML Help table-of-contents (.hhc), and index (.hhk) file automatically from the schema construct type and construct name that it derives the contents of each page; 
&lt;LI&gt;rebuilds the HTML image hot-spot and text hyperlinks automatically to retain the original XMLSPY® navigation capabilities; 
&lt;LI&gt;uses a user-specified HTML Help project template (with replacable parameters), to automatically generate the target HTML Help project file (.hhp) which can directly compiled; 
&lt;LI&gt;automatically executes the Microsoft® HTML Help Compiler (hhc.exe) to build the final .chm help file; 
&lt;LI&gt;provides multiple XMLSPY® documentation sessions, if required, each session generating a section of the documentation. The documentation page is then split as before, then merged on a per-page basis to provide complete documentation HTML pages. These pages are then placed individually in the HTML Help file as before. Using this technique, it is possible to generate the complete documentation for large schema-sets successfully, when a single pass generation would cause XMLSPY® to fail as indicated above; 
&lt;LI&gt;allows further enhancement to the generated documentation via user-coded plug-in assemblies.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The resulting HTML Help file is fully-featured, easy to navigate, and provides great performance.&lt;BR&gt;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103963"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103963" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/103963.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2007/01/19/103963.aspx</guid>
            <pubDate>Fri, 19 Jan 2007 14:25:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/103963.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2007/01/19/103963.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/103963.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/103963.aspx</trackback:ping>
        </item>
        <item>
            <title>An ultra-simple appSettings class for .NET 2.0+</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/11/13/96943.aspx</link>
            <description>&lt;p&gt;The .NET 2.0 &lt;font face="Courier New" color="#0000ff" size="2"&gt;System.Configuration.dll&lt;/font&gt; provides a much more sophisticated (and complex) set of classes that access and modify application &lt;font face="Courier New" color="#0000ff" size="2"&gt;.config&lt;/font&gt; files, than compared to the functionality in .NET 1.x.&lt;/p&gt;
&lt;p&gt;However, most often, the requirement is still to provide simple access to and from the key-value pairs in the &lt;font face="Courier New" color="#0000ff" size="2"&gt;appSettings&lt;/font&gt; section as before.&lt;/p&gt;
&lt;p&gt;This post establishes a very simple abstract base-class that provides a simple binding to the &lt;font face="Courier New" color="#0000ff" size="2"&gt;appSettings&lt;/font&gt; section that requires no code to be written in the sub-class. It provides a &lt;font face="Courier New" color="#0000ff" size="2"&gt;Load&lt;/font&gt; method that is called in the  instance constructor. The &lt;font face="Courier New" color="#0000ff" size="2"&gt;Load&lt;/font&gt; method uses reflection to determine the public properties of the derived class. For each of these properties, the key-value instance in the &lt;font face="Courier New" color="#0000ff" size="2"&gt;appSettings&lt;/font&gt; is accessed, the value is read and converted from a string to the required property type, and the property value updated. There are two restrictions to this action:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The correct value type must be able to be instanced by the &lt;font face="Courier New" color="#0000ff" size="2"&gt;System.Convert.ChangeType&lt;/font&gt; method and converted from a &lt;font face="Courier New" color="#0000ff" size="2"&gt;System.String&lt;/font&gt;, so the type should be a simple (primitive) type such as a &lt;font face="Courier New" color="#0000ff" size="2"&gt;string&lt;/font&gt; or &lt;font face="Courier New" color="#0000ff" size="2"&gt;int&lt;/font&gt;, etc. &lt;/li&gt;
    &lt;li&gt;The property should be a simple value type which is not an array. The &lt;font face="Courier New" color="#0000ff" size="2"&gt;Load&lt;/font&gt; method checks for this using the &lt;font face="Courier New" color="#0000ff" size="2"&gt;System.Type.IsArray&lt;/font&gt; property, and ignores the property if the value is true. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, it can be argued that if the application setting value does not adhere to those restrictions, it should not be stored in the &lt;font face="Courier New" color="#0000ff" size="2"&gt;appSettings&lt;/font&gt; section in the first place.&lt;/p&gt;
&lt;p&gt;In the instance destructor, the &lt;font face="Courier New" color="#0000ff" size="2"&gt;Save&lt;/font&gt; method is called. Again using reflection, for each public property which is not an array, the key-value of the &lt;font face="Courier New" color="#0000ff" size="2"&gt;appSettings&lt;/font&gt; section is accessed and updated with the current value of the property. Note that the value is changed to a &lt;font face="Courier New" color="#0000ff" size="2"&gt;System.String&lt;/font&gt;, which is in keeping with the restrictions mentioned above. Once the settings are updated, they are saved back to the &lt;font face="Courier New" color="#0000ff" size="2"&gt;.config&lt;/font&gt; file and then reloaded, to ensure correct updating subsequently.&lt;/p&gt;
&lt;p&gt;Note that the &lt;font face="Courier New" color="#0000ff" size="2"&gt;Load&lt;/font&gt; and &lt;font face="Courier New" color="#0000ff" size="2"&gt;Save&lt;/font&gt; methods are &lt;font face="Courier New" color="#0000ff" size="2"&gt;public&lt;/font&gt; so they can be called from external code at any time. They are also &lt;font face="Courier New" color="#0000ff" size="2"&gt;virtual&lt;/font&gt; so that they can be overridden by the derived class if required.&lt;/p&gt;
&lt;p&gt;The C# code for the base-class is shown in Listing 1 below:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table cellpadding="16" bgcolor="#dddddd" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;Listing 1: Application Settings Base Class&lt;/font&gt;&lt;/strong&gt;&lt;/pre&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000" size="2"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; abstract &lt;font color="#0000ff"&gt;class&lt;/font&gt; AppSettings
{
  &lt;font color="#008000"&gt;// Load the settings.&lt;/font&gt;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; virtual &lt;font color="#0000ff"&gt;void&lt;/font&gt; Load()
  {
    PropertyInfo[] properties = GetType().GetProperties();
    &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (PropertyInfo property &lt;font color="#0000ff"&gt;in&lt;/font&gt; properties)
    {
      &lt;font color="#0000ff"&gt;if&lt;/font&gt; (!property.PropertyType.IsArray)
      {
        &lt;font color="#0000ff"&gt;string&lt;/font&gt; appValue = ConfigurationManager.AppSettings[property.Name];
        &lt;font color="#0000ff"&gt;if&lt;/font&gt; (appValue != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
        {
          &lt;font color="#0000ff"&gt;try&lt;/font&gt;
          {
            &lt;font color="#008000"&gt;// Attempt to change the type from System.String to&lt;/font&gt;
            &lt;font color="#008000"&gt;// the property type, and set the property value.&lt;/font&gt;
            property.SetValue(
              &lt;font color="#0000ff"&gt;this&lt;/font&gt;,
              Convert.ChangeType(appValue, property.PropertyType),
              &lt;font color="#0000ff"&gt;null&lt;/font&gt;);
          }
          &lt;font color="#0000ff"&gt;catch&lt;/font&gt; {/*ignore*/}
        }
      }
    }
  }
  &lt;font color="#008000"&gt;// Save the settings.&lt;/font&gt;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; virtual &lt;font color="#0000ff"&gt;void&lt;/font&gt; Save()
  {
    &lt;font color="#008000"&gt;// Get the configuration file.&lt;/font&gt;
    System.Configuration.Configuration configuration =
      ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    &lt;font color="#008000"&gt;// Get the public properties of the class.&lt;/font&gt;
    PropertyInfo[] properties = GetType().GetProperties();
    &lt;font color="#008000"&gt;// Save each property setting.&lt;/font&gt;
    &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (PropertyInfo property &lt;font color="#0000ff"&gt;in&lt;/font&gt; properties)
    {
      &lt;font color="#008000"&gt;// Save if not an array type.&lt;/font&gt;
      &lt;font color="#0000ff"&gt;if&lt;/font&gt; (!property.PropertyType.IsArray)
      {
        &lt;font color="#008000"&gt;// Remove the setting if it exists.&lt;/font&gt;
        &lt;font color="#0000ff"&gt;if&lt;/font&gt; (configuration.AppSettings.Settings[property.Name] != &lt;font color="#0000ff"&gt;null&lt;/font&gt;)
        {
          configuration.AppSettings.Settings.Remove(property.Name);
        }
        &lt;font color="#008000"&gt;// Add the setting.&lt;/font&gt;
        configuration.AppSettings.Settings.Add(
          property.Name,
          property.GetValue(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;font color="#0000ff"&gt;null&lt;/font&gt;).ToString());
      }
    }
    &lt;font color="#008000"&gt;// Save the configuration settings.&lt;/font&gt;
    configuration.Save(ConfigurationSaveMode.Modified);
    &lt;font color="#008000"&gt;// Force a reload of the whole section.&lt;/font&gt;
    ConfigurationManager.RefreshSection("appSettings");
  }
  &lt;font color="#0000ff"&gt;protected&lt;/font&gt; AppSettings()
  {
    &lt;font color="#008000"&gt;// Load the settings when class instance is constructed.&lt;/font&gt;
    Load();
  }
  ~AppSettings()
  {
    &lt;font color="#008000"&gt;// Save settings when instance is destroyed.&lt;/font&gt;
    Save();
  }
}&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So how do you use it?&lt;/p&gt;
&lt;p&gt;In Listing 2 is a test settings class. Note that the only requirement to get it all the work is to add the class inheritance reference. Now if your application creates an instance of the derived settings class, the &lt;font face="Courier New" color="#0000ff" size="2"&gt;.config&lt;/font&gt; file settings are loaded, if available. By simply destructing the instance (by normally letting it run out of scope), the settings are automatically saved for the derived class &lt;font face="Courier New" color="#0000ff" size="2"&gt;public&lt;/font&gt; properties. This also keeps working, whether you add or remove &lt;font face="Courier New" color="#0000ff" size="2"&gt;public&lt;/font&gt; properties to the derived class.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table cellpadding="16" bgcolor="#dddddd" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;Listing 2: A test sub-class which is instantiable in an application.      &lt;/font&gt;&lt;/strong&gt;&lt;/pre&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000" size="2"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; Settings : AppSettings
{
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; double doubleValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; double DoubleValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; doubleValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { doubleValue = value; }
  }
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; decimal decimalValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; decimal DecimalValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; decimalValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { decimalValue = value; }
  }
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;bool&lt;/font&gt; boolValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;bool&lt;/font&gt; BoolValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; boolValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { boolValue = value; }
  }
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; intValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;int&lt;/font&gt; IntValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; intValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { intValue = value; }
  }
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;string&lt;/font&gt; stringValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;string&lt;/font&gt; StringValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; stringValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { stringValue = value; }
  }
  &lt;font color="#0000ff"&gt;private&lt;/font&gt; DateTime dateTimeValue;
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; DateTime DateTimeValue
  {
    &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; dateTimeValue; }
    &lt;font color="#0000ff"&gt;set&lt;/font&gt; { dateTimeValue = value; }
  }
  &lt;font color="#0000ff"&gt;public&lt;/font&gt; Settings() { }
}&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Here is what the &lt;font face="Courier New" color="#0000ff" size="2"&gt;.config&lt;/font&gt; file looks like for this example:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table cellpadding="16" bgcolor="#dddddd" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;pre&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;Listing 3: The .config file showing the settings stored as keys.          &lt;/font&gt;&lt;/strong&gt;&lt;/pre&gt;
            &lt;pre&gt;&lt;font face="Courier New" color="#000000" size="2"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;?xml&lt;/font&gt; version="1.0" encoding="utf-8"?&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;
&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;configuration&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;
    &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;appSettings&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="DoubleValue" value="3.141592654" &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="DecimalValue" value="-100.01" &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="BoolValue" value="True" &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="IntValue" value="1024" &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="StringValue" value="The quick brown fox jumped over
           the lazy dog." &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
        &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;add&lt;/font&gt; key="DateTimeValue" value="2006/11/13 12:34:56 AM" &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;
    &lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;appSettings&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;
&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;configuration&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can download the AppSettings class and a sample application from the link below:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://www.bware.biz/DotNet/Development/AppSettings/AppSettings.zip"&gt;Download AppSettings.zip&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=96943"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=96943" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/96943.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/11/13/96943.aspx</guid>
            <pubDate>Mon, 13 Nov 2006 17:26:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/96943.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/11/13/96943.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/96943.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/96943.aspx</trackback:ping>
        </item>
        <item>
            <title>Playing with the .NET 2.0 XmlSchemaSet class</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/09/14/91135.aspx</link>
            <description>&lt;P&gt;As an ongoing part of maintaining our &lt;STRONG&gt;Code&lt;FONT color=#ff0000&gt;XS&lt;/FONT&gt;&lt;/STRONG&gt; code-generation tool (read about it here: &lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Development/CodeXS/Article/Article_web.htm" target=_blank&gt;CodeXS article&lt;/A&gt;), we are continually looking for ways to improve the consistency, reliability and performance of the &lt;STRONG&gt;Code&lt;FONT color=#ff0000&gt;XS&lt;/FONT&gt;&lt;/STRONG&gt; tool.&lt;/P&gt;
&lt;P&gt;Enter the &lt;FONT face="Courier New" color=#0000ff size=2&gt;System.Xml.Schema.XmlSchemaSet&lt;/FONT&gt; class. Unfortunately, it is available only in .NET 2.0+. Unlike the .NET 1.x &lt;FONT face="Courier New" color=#0000ff size=2&gt;XmlSchemas&lt;/FONT&gt; class, this class provides what seems to be a one-shop-stop means of reading, compiling and using a target-schema that utilizes a complex multi-namespace, multi-include/import schema set. Merely by setting up the correct URL resolver, the target-schema can simply be &lt;FONT face="Courier New" color=#0000ff size=2&gt;Add&lt;/FONT&gt;'ed to the &lt;FONT face="Courier New" color=#0000ff size=2&gt;XmlSchemaSet&lt;/FONT&gt; and all the import'ed/include'ed schemas are automatically added during the execution of that method. The &lt;FONT face="Courier New" color=#0000ff size=2&gt;XmlSchemaSet&lt;/FONT&gt; object can then be &lt;FONT face="Courier New" color=#0000ff size=2&gt;Compile&lt;/FONT&gt;'d, and the various properties of the class can be used to extract the complex types, elements etc. of the entire schema set as if it is one large &lt;FONT face="Courier New" color=#0000ff size=2&gt;XmlSchema&lt;/FONT&gt;.&lt;/P&gt;
&lt;P&gt;One caveat though: it seems as if there are schema sets that have bi-directional schema import constructs. In these cases the same schema may be added more than once to the schema set, resulting in validation errors when the &lt;FONT face="Courier New" color=#0000ff size=2&gt;XmlSchemaSet&lt;/FONT&gt; object is &lt;FONT face="Courier New" color=#0000ff size=2&gt;Compile&lt;/FONT&gt;'d. These typically result in a &lt;EM&gt;'The {object}{namespace} has already been declared.&lt;/EM&gt;' error. An example of this schema can be found here: &lt;A href="http://it.ojp.gov/jxdm/3.0.3/jxdm.xsd" target=_blank&gt;Global Justice XML Version 3.0.3 Schema&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;One way around this problem is shown in the code-excerpt below, and currently works correctly for all the schemas we are using.&lt;/P&gt;
&lt;P&gt;
&lt;TABLE cellPadding=16 bgColor=#dddddd border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;PRE&gt;&lt;FONT face="Courier New" color=#000000 size=2&gt;&lt;STRONG&gt;Read and compile a complex XML schema set&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT face="Courier New" color=black size=2&gt;&lt;FONT color=green&gt;// Set the current working directory for file-based Uri's.&lt;/FONT&gt;
FileInfo fileInfo = &lt;FONT color=blue&gt;new&lt;/FONT&gt; FileInfo(schemaFilePath);
Directory.SetCurrentDirectory(fileInfo.DirectoryName);
XmlSchemaSet xmlSchemaSet;
&lt;FONT color=green&gt;// Open the target schema file as a stream.&lt;/FONT&gt;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; (StreamReader reader = &lt;FONT color=blue&gt;new&lt;/FONT&gt; StreamReader(schemaFilePath))
{
  &lt;FONT color=green&gt;// XmlSchemaSet is only .NET 2.0+.&lt;/FONT&gt;
  xmlSchemaSet = &lt;FONT color=blue&gt;new&lt;/FONT&gt; XmlSchemaSet();
  xmlSchemaSet.ValidationEventHandler += ValidationErrorHandler;
  xmlSchemaSet.XmlResolver = &lt;FONT color=blue&gt;new&lt;/FONT&gt; XmlUrlResolver();
  XmlSchema xmlSchema = XmlSchema.Read(reader, ValidationErrorHandler);
  &lt;FONT color=green&gt;// Adding a target schema here will automatically resolve all&lt;/FONT&gt;
  &lt;FONT color=green&gt;// include/import'ed schemas - these will reside together with the&lt;/FONT&gt;
  &lt;FONT color=green&gt;// target schema in the XmlSchemaSet.Schemas() collection of &lt;/FONT&gt;
  &lt;FONT color=green&gt;// XmlSchema objects.&lt;/FONT&gt;
  xmlSchemaSet.Add(xmlSchema);
  &lt;FONT color=green&gt;// Check for uniqueness - schemas may be added twice if there&lt;/FONT&gt;
  &lt;FONT color=green&gt;// are bi-directional imports.&lt;/FONT&gt;
  &lt;FONT color=green&gt;// Using an ArrayList lets use indexing for accessing the schemas.&lt;/FONT&gt;
  ArrayList schemaList = &lt;FONT color=blue&gt;new&lt;/FONT&gt; ArrayList(xmlSchemaSet.Schemas());
  &lt;FONT color=green&gt;// ArrayList holding the duplicate schemas.&lt;/FONT&gt;
  ArrayList duplicateSchemaList = &lt;FONT color=blue&gt;new&lt;/FONT&gt; ArrayList();
  &lt;FONT color=blue&gt;for&lt;/FONT&gt; (&lt;FONT color=blue&gt;int&lt;/FONT&gt; i = 0; i &amp;lt; schemaList.Count; i++)
  {
    &lt;FONT color=green&gt;// It seems that if the SourceUri property is unresolved &lt;/FONT&gt;
    &lt;FONT color=green&gt;// (=string.Empty), then the schema has already been added.&lt;/FONT&gt;
    &lt;FONT color=blue&gt;if&lt;/FONT&gt; (((XmlSchema)schemaList[i]).SourceUri == &lt;FONT color=blue&gt;string&lt;/FONT&gt;.Empty)
    {
      duplicateSchemaList.Add((XmlSchema)schemaList[i]);
    }
    &lt;FONT color=blue&gt;else&lt;/FONT&gt;
    {
      &lt;FONT color=green&gt;// Exhaustively test for duplicate schemas by means of the&lt;/FONT&gt;
      &lt;FONT color=green&gt;// SourceUri property.&lt;/FONT&gt;
      &lt;FONT color=blue&gt;for&lt;/FONT&gt; (&lt;FONT color=blue&gt;int&lt;/FONT&gt; j = i + 1; j &amp;lt; schemaList.Count; j++)
      {
        &lt;FONT color=blue&gt;if&lt;/FONT&gt; (((XmlSchema)schemaList[i]).SourceUri ==
            ((XmlSchema)schemaList[j]).SourceUri)
        {
          duplicateSchemaList.Add((XmlSchema)schemaList[j]);
        }
      }
    }
  }
  &lt;FONT color=green&gt;// Remove the duplicate schemas from the set.&lt;/FONT&gt;
  &lt;FONT color=blue&gt;foreach&lt;/FONT&gt; (XmlSchema schema &lt;FONT color=blue&gt;in&lt;/FONT&gt; duplicateSchemaList)
  {
    xmlSchemaSet.Remove(schema);
  }
  &lt;FONT color=green&gt;// Compile the whole schema set.&lt;/FONT&gt;
  xmlSchemaSet.Compile();
  reader.Close();
}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;The &lt;STRONG&gt;Code&lt;FONT color=#ff0000&gt;XS&lt;/FONT&gt;&lt;/STRONG&gt; tool is available here:&lt;/P&gt;
&lt;P&gt;You can download the source-code by re/registering here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/Registration/RegisterInput.aspx" target=_blank&gt;&lt;FONT color=#000080&gt;Download source-code&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can check the latest update information here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/Features.aspx" target=_blank&gt;&lt;FONT color=#000080&gt;Features and updates&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can run the CodeXS online tool here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx" target=_blank&gt;&lt;FONT color=#000080&gt;CodeXS online&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=91135"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=91135" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/91135.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/09/14/91135.aspx</guid>
            <pubDate>Thu, 14 Sep 2006 12:42:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/91135.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/09/14/91135.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/91135.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/91135.aspx</trackback:ping>
        </item>
        <item>
            <title>Generate Code-DOMs directly from C# or VB.NET</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/07/24/86075.aspx</link>
            <description>&lt;P&gt;If you write applications in .NET that generate .NET language source-code as output, and the output language should be selectable (typically C# or VB.NET), then you will probably end up generating the output from a &lt;FONT face="Courier New" color=#0000ff&gt;System.CodeDom&lt;/FONT&gt; graph. Once you have the CodeDOM the actual code generation support in .NET is easy, clean and produces reasonable code. So what's the catch? Well, consider at least the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Building CodeDOMs programmatically is a real pain - the .NET API's are convoluted, difficult to understand, error-prone and you often require many lines of code to generate one line of code in the CodeDOM. (&lt;I&gt;Reminds me of the days I used to program in assembler..&lt;/I&gt;). For this reason, many people have gone to great pains to abstract the CodeDOM API's into more meaningful, much easier to use, and generally more efficient class libraries. I reference a few of these from &lt;A href="http://www.codeproject.com/" target=_blank&gt;CodeProject&lt;/A&gt; below:&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.codeproject.com/csharp/refly.asp" target=_blank&gt;Refly, makes the CodeDom'er life easier&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.codeproject.com/useritems/CodeDomExpEval.asp" target=_blank&gt;An Expression Parser for CodeDom&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL&gt;
&lt;LI&gt;Some of the constructs that you prefer to code yourself just cannot be reproduced in a CodeDOM, and require that you be a lot more creative and defensive in your approach when programmatically building CodeDOMs.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Another approach is to find or build a &lt;FONT face="Courier New" color=#0000ff&gt;System.CodeDom.Compiler.ICodeParser&lt;/FONT&gt; implementation for the input.NET language you are generating&amp;nbsp;CodeDOMs from.&amp;nbsp;This allows you to write code in that .NET language, which is then parsed to produce a &lt;FONT face="Courier New" color=#0000ff&gt;System.CodeDom.CodeCompileUnit&lt;/FONT&gt; (CodeDOM). Once you have the CodeDOM it is trivial to generate the code (see the &lt;FONT face="Courier New" color=#0000ff&gt;CodeGeneration.GenerateCode&lt;/FONT&gt; method below). But again, there is no free-lunch - many &lt;FONT face="Courier New" color=#0000ff&gt;ICodeParser&lt;/FONT&gt; implementations exist, but all of them (in my experience) are trivial solutions, mainly geared to generating code for class-interfaces or web-service interfaces.&lt;/P&gt;
&lt;P&gt;Enter &lt;A href="http://www.icsharpcode.net/" target=_blank&gt;IC#Code&lt;/A&gt; and their &lt;A href="http://www.icsharpcode.net/OpenSource/SD/Default.aspx" target=_blank&gt;#Develop&lt;/A&gt; (SharpDevelop) product.&lt;/P&gt;
&lt;P&gt;As part of this product, they ship an assembly - &lt;I&gt;ICSharpCode.NRefactory.dll&lt;/I&gt;&amp;nbsp; (and you can build the source code) which provides a fairly comprehensive &lt;FONT face="Courier New" color=#0000ff&gt;ICodeParser&lt;/FONT&gt; implementation. Using the &lt;FONT face="Courier New" color=#0000ff&gt;CodeDOMVisitor&lt;/FONT&gt; '&lt;I&gt;visitor&lt;/I&gt;' object, it is easy to generate source-code from a CodeDOM created by parsing source-code, as demonstrated in the code below. Note, though, that as before your input source-code will have to be very standard (no funny stuff), and there are some quirks with the &lt;FONT face="Courier New" color=#0000ff&gt;CodeDOMVisitor&lt;/FONT&gt; object (which includes some issues with class constructor generation, and some of the looping constructs). In general the results are pleasing, and I look forward to future updates to this assembly. Interestingly, they also provide other '&lt;I&gt;visit-ations&lt;/I&gt;', including a working C#-to-VB.NET converter.&lt;/P&gt;
&lt;P&gt;The code below was written for VS2005/.NET 2.0 and uses the &lt;A href="http://www.icsharpcode.net/OpenSource/SD/Default.aspx" target=_blank&gt;#Develop&lt;/A&gt; 2.0.0.1462RC2 version source-code and DLL's. You will need to add a reference in your project to the &lt;EM&gt;ICSharpCode.NRefactory.dll&lt;/EM&gt;&amp;nbsp;assembly to get your project to build.&lt;/P&gt;
&lt;TABLE cellPadding=16 bgColor=#dddddd border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;PRE&gt;&lt;B&gt;&lt;FONT face=Verdana size=2&gt;CodeGenerator Classes for .NET 2.0&lt;/FONT&gt;&lt;/B&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT face="Courier New" color=black size=2&gt;&lt;FONT color=blue&gt;using&lt;/FONT&gt; System;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; System.CodeDom;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; System.CodeDom.Compiler;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; System.Collections.Generic;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; System.Text;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; System.IO;
&lt;FONT color=blue&gt;using&lt;/FONT&gt; ICSharpCode.NRefactory.Parser;
&lt;FONT color=blue&gt;namespace&lt;/FONT&gt; CodeGeneration
{
  &lt;FONT color=blue&gt;public&lt;/FONT&gt; &lt;FONT color=blue&gt;class&lt;/FONT&gt; CodeGenerator
  {
    &lt;FONT color=blue&gt;private&lt;/FONT&gt; ICodeParser parser;
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; ICodeParser Parser
    {
      &lt;FONT color=blue&gt;get&lt;/FONT&gt; { &lt;FONT color=blue&gt;return&lt;/FONT&gt; parser; }
      &lt;FONT color=blue&gt;set&lt;/FONT&gt; { parser = value; }
    }
    &lt;FONT color=blue&gt;private&lt;/FONT&gt; CodeDomProvider provider;
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; CodeDomProvider Provider
    {
      &lt;FONT color=blue&gt;get&lt;/FONT&gt; { &lt;FONT color=blue&gt;return&lt;/FONT&gt; provider; }
      &lt;FONT color=blue&gt;set&lt;/FONT&gt; { provider = value; }
    }
    &lt;FONT color=blue&gt;private&lt;/FONT&gt; CodeGeneratorOptions options;
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; CodeGeneratorOptions Options
    {
      &lt;FONT color=blue&gt;get&lt;/FONT&gt; { &lt;FONT color=blue&gt;return&lt;/FONT&gt; options; }
      &lt;FONT color=blue&gt;set&lt;/FONT&gt; { options = value; }
    }
    &lt;FONT color=blue&gt;protected&lt;/FONT&gt; virtual CodeGeneratorOptions 
      GetDefaultOptions()
    {
      CodeGeneratorOptions options = 
        &lt;FONT color=blue&gt;new&lt;/FONT&gt; CodeGeneratorOptions();
      options.BracingStyle = "C";
      options.BlankLinesBetweenMembers = &lt;FONT color=blue&gt;false&lt;/FONT&gt;;
      options.IndentString = "\t";
      &lt;FONT color=blue&gt;return&lt;/FONT&gt; options;
    }
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; virtual &lt;FONT color=blue&gt;void&lt;/FONT&gt; GenerateCode(TextReader reader, 
      TextWriter writer)
    {
      CodeCompileUnit codeCompileUnit = Parser.Parse(reader);
      Provider.GenerateCodeFromCompileUnit(codeCompileUnit, writer, Options);
      reader.Close();
      &lt;FONT color=green&gt;// Important to flush the output stream.&lt;/FONT&gt;
      writer.Flush();
      writer.Close();
    }
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; CodeGenerator(ICodeParser parser, 
      CodeDomProvider provider)
    {
      Options = GetDefaultOptions();
      Parser = parser;
      Provider = provider;
    }
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; CodeGenerator(ICodeParser parser, 
      CodeDomProvider provider,
      CodeGeneratorOptions options)
    {
      Options = options;
      Parser = parser;
      Provider = provider;
    }
  }
  &lt;FONT color=blue&gt;public&lt;/FONT&gt; &lt;FONT color=blue&gt;class&lt;/FONT&gt; Parser : ICodeParser
  {
    #region ICodeParser Members
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; CodeCompileUnit Parse(TextReader codeStream)
    {
      &lt;FONT color=green&gt;// Set the parser for the correct language.&lt;/FONT&gt;
      IParser parser = ParserFactory.CreateParser(Language,
        codeStream);
      parser.Parse();
      &lt;FONT color=green&gt;// Use a CodeDom visitor to gen. a CodeCompileUnit.&lt;/FONT&gt;
      CodeDOMVisitor visit = &lt;FONT color=blue&gt;new&lt;/FONT&gt; CodeDOMVisitor();
      CodeNamespace globalNamespace =  (CodeNamespace)
        visit.Visit(parser.CompilationUnit, &lt;FONT color=blue&gt;null&lt;/FONT&gt;);
      &lt;FONT color=green&gt;// Mostly, you need to remove the "Global"&lt;/FONT&gt;
      &lt;FONT color=green&gt;// code namespace from the compile unit.&lt;/FONT&gt;
      visit.codeCompileUnit.Namespaces.Remove(globalNamespace);
      &lt;FONT color=blue&gt;return&lt;/FONT&gt; visit.codeCompileUnit;
    }
    #endregion
    &lt;FONT color=blue&gt;private&lt;/FONT&gt; SupportedLanguage language = SupportedLanguage.CSharp;
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; SupportedLanguage Language
    {
      &lt;FONT color=blue&gt;get&lt;/FONT&gt; { &lt;FONT color=blue&gt;return&lt;/FONT&gt; language; }
      &lt;FONT color=blue&gt;set&lt;/FONT&gt; { language = value; }
    }
    &lt;FONT color=blue&gt;public&lt;/FONT&gt; Parser(SupportedLanguage language)
    {
      Language = language;
    }
  }
}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=86075"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=86075" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/86075.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/07/24/86075.aspx</guid>
            <pubDate>Mon, 24 Jul 2006 13:55:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/86075.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/07/24/86075.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/86075.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/86075.aspx</trackback:ping>
        </item>
        <item>
            <title>CodeXS Version 0.57b - 13 Jul 2006 released</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/07/13/84978.aspx</link>
            <description>&lt;P&gt;CodeXS Version 0.57b was released on 13 July 2006.&lt;/P&gt;
&lt;P&gt;You can download the source-code by re/registering here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/Registration/RegisterInput.aspx" target=_blank&gt;Download source-code&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can check the latest update information here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/Features.aspx" target=_blank&gt;Features and updates&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can run the CodeXS online tool here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx" target=_blank&gt;CodeXS online&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Version 0.57&amp;#223; - 13 Jul 2006&lt;/STRONG&gt; &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Currently still provides complete support for VS2005/.NET 2.0, and VS2003/.NET 1.1. 
&lt;LI&gt;Collection class bug-fixes&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;The following bugs-fixes are implemented:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Names for schema complex types an elements with multiple occurrences can now include the phrase 'Collection'. 
&lt;LI&gt;Return types and parameters for the standard collection methods and properties now use the correct collection element type. 
&lt;LI&gt;The &lt;FONT color=darkblue&gt;ToArray&lt;/FONT&gt; and &lt;FONT color=darkblue&gt;FromArray&lt;/FONT&gt; corrected for double-index ragged array return and parameter types, respectively. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Note: CodeXS supports ragged array serialization with a maximum array rank of 2. &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Override modifier on sub-classed virtual methods and properties &lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;A more general solution has been provided to correct the error where a &lt;FONT color=darkblue&gt;virtual&lt;/FONT&gt; attribute is declared that should be an &lt;FONT color=darkblue&gt;override&lt;/FONT&gt; attribute.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Type instantiation support&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Type instantiation (vs. primitive non-instantable types) checking is enhanced. This should reduce the occurrence of the (usually recoverable) exception: "&lt;FONT color=darkblue&gt;Cannot determine type &amp;lt;type&amp;gt;'&lt;TYPE&gt;'. Type assumed instantiable.&lt;/FONT&gt;".&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Additional documentation support&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Documentation utility methods have been added to allow for more extensive and easier documentation of the generated code.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;&lt;FONT color=darkblue&gt;ISchemaObjectReader&lt;/FONT&gt; interface removed&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;This interface has been removed for the following reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI dir=ltr&gt;The &lt;FONT color=darkblue&gt;ICodeModifer&lt;/FONT&gt; interface provides the correct entry points for code modifer enhancements requiring direct reading from the XML schemas. 
&lt;LI dir=ltr&gt;The &lt;FONT color=darkblue&gt;ICodeModifer&lt;/FONT&gt; interface now supports the .NET 2.0 &lt;FONT color=darkblue&gt;SchemaImporterExtension&lt;/FONT&gt; class implementation in the &lt;FONT color=darkblue&gt;ICodeModifier&lt;/FONT&gt; interface. 
&lt;LI dir=ltr&gt;The &lt;FONT color=darkblue&gt;ICodeModifer&lt;/FONT&gt; interface supports initialization, which can be used as an entry point to pre-read schemas.&lt;/LI&gt;&lt;/UL&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Logging support for ICodeModifier implementers&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Logging using the CodeXS logging implementation can be used directly from an &lt;FONT color=darkblue&gt;ICodeModifier&lt;/FONT&gt; implementor in an external assembly.&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Missing declarations and definitions in the code&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;A bug-fix was implemented to avoid this error, and appears to be working as expected. &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Assembly and file version control&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Assembly and file version numbers now correspond with the public release version numbers.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;XML schema documentation add-in&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;An ICodeModifier implementation add-in has been provided which reads schema &lt;FONT color=darkblue&gt;&amp;lt;xs:documentation/&amp;gt;&lt;/FONT&gt; &lt;?xml:namespace prefix = xs /&gt;&lt;xs:documentation&gt;&lt;/xs:documentation&gt;tags and injects the documentation into the generated code documentation comments.&lt;/P&gt;
&lt;P&gt;This add-in is implemented by reading the XML schema(s) for the generated code files, and matching schema-types to generated code types. This add-in is implemented to read and modify the CodeDOM's after the other code-generators have executed and therefore post-processes the CodeDOM. It has been implemented to work for both .NET 2.0, and .NET 1.1.&lt;/P&gt;
&lt;P&gt;For .NET 2.0, the CXSC application commandline is:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT color=darkblue&gt;cxsc {..} -m="CodeXS.Schema.StandardCodeModifier.dll","SchemaDocumentation.dll"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;For .NET 1.1, the CXSC application commadline is:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT color=darkblue&gt;cxsc {..} -m="CodeXS.Schema.StandardCodeModifier.Net1_1.dll","SchemaDocumentation.Net1_1.dll"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;STRONG&gt;NOTE:&lt;/STRONG&gt; The CodeXS online tool does not utilize this add-in.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN-RIGHT: 0px"&gt;.NET 2.0 SchemaImporterExtension class&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;For .NET 2.0, the abstract class &lt;FONT color=darkblue&gt;System.Xml.Serialization.Advanced.SchemaImporterExtension&lt;/FONT&gt; has been provided for sub-classing. A sub-classed instance receives call-backs via the sub-class implemented &lt;FONT color=darkblue&gt;ImportSchemaType&lt;/FONT&gt; methods, and provides a context for the CodeDOM type/member and the &lt;FONT color=darkblue&gt;System.Xml.Schema.XmlSchemaObject&lt;/FONT&gt; that is used for the CodeDOM construct. This allows a code-modifier to modify the CodeDOM while it is being constructed by the code generator. In general, this provides a much safer and simpler way to relate the XML schema objects to their CodeDOM counterparts.&lt;/P&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;CodeXS provides complete support for writing &lt;FONT color=darkblue&gt;SchemaImporterExtension&lt;/FONT&gt; implementers. &lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=84978"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=84978" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/84978.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/07/13/84978.aspx</guid>
            <pubDate>Thu, 13 Jul 2006 12:08:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/84978.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/07/13/84978.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/84978.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/84978.aspx</trackback:ping>
        </item>
        <item>
            <title>CodeXS Version 0.56b - 19 Jun 2006 released</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/06/21/82545.aspx</link>
            <description>&lt;P&gt;CodeXS Version 0.56b was released on 19 June 2006.&lt;/P&gt;
&lt;P&gt;You can download the source-code by re/registering here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/Registration/RegisterInput.aspx" target=_blank&gt;Download source-code&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can check the latest update information here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/Features.aspx" target=_blank&gt;Features and updates&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can run the CodeXS online tool here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx" target=_blank&gt;CodeXS online&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Changes in Version 0.56&amp;#223; -&amp;nbsp;19 Jun 2006&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Currently still provides complete support for VS2005/.NET 2.0, and VS2003/.NET 1.1. 
&lt;LI&gt;Updated collection object generated code&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;Updated the collection object generated code: &lt;/P&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;
&lt;DIV&gt;Re-implemented the &lt;FONT color=darkblue&gt;FromArray&lt;/FONT&gt; method with less error prone code.&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV&gt;Re-implemented the &lt;FONT color=darkblue&gt;ToArray&lt;/FONT&gt; method with less error prone code.&lt;/DIV&gt;
&lt;LI&gt;Corrected the return value for the &lt;FONT color=darkblue&gt;Add&lt;/FONT&gt; method. Now returns &lt;FONT color=darkblue&gt;int&lt;/FONT&gt; instead of &lt;FONT color=darkblue&gt;void&lt;/FONT&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;My thanks to Dave Waterworth for this fix - Willem Fourie&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL&gt;
&lt;LI&gt;New field names&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;This version uses a different scheme when renaming class field members. This resulted from various XML schemas using elements with the name '&lt;FONT color=darkblue&gt;id&lt;/FONT&gt;' and '&lt;FONT color=darkblue&gt;Id&lt;/FONT&gt;', respectively. In prior versions this resulted in the same field name '&lt;FONT color=darkblue&gt;__Id&lt;/FONT&gt;'. In this version they are distinct: '&lt;FONT color=darkblue&gt;__id&lt;/FONT&gt;' and '&lt;FONT color=darkblue&gt;__Id&lt;/FONT&gt;', respectively.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;Export code exception fix&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;During the import/export of the &lt;FONT color=darkblue&gt;XmlTypeMapping&lt;/FONT&gt; objects, the import/export sequence is now done via an explicit array list object. This avoids the exception: &lt;FONT color=darkblue&gt;'collection changed during iteration&lt;/FONT&gt;&lt;FONT color=#990066&gt;'.&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL dir=ltr&gt;
&lt;LI&gt;
&lt;DIV&gt;Handling of XSD elements and XSD types with the same name&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;In prior versions, this caused a code generation exception. However, often XML schemas are defining elements with the same name as their type names.&amp;nbsp;For those cases, the single class generated is correct, as it represents completely both the element and the type. For this reason, the prior exception has been changed to provide a warning message in the &lt;FONT color=darkblue&gt;CodeXS.log&lt;/FONT&gt; file, and generation continues.&lt;/P&gt;
&lt;P&gt;It is strongly recommended that these warning messages are noted, as they do provide notification of potential de-/-serialization problems when the generated code is used.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL&gt;
&lt;LI dir=ltr&gt;&lt;FONT color=#00008b&gt;XmlChoiceIdentifierAttribute&lt;/FONT&gt;&lt;FONT color=#990066&gt; &lt;/FONT&gt;&lt;FONT color=#000000&gt;handling&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;This attribute was not handled correctly in prior versions, resulting in de-/-serialization exceptions. This is now working and relies on the following changes in this version:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The class properties intended for de-/-serialization now&amp;nbsp;set/get the original field types: In prior versions, if the property set/get type was an &lt;FONT color=darkblue&gt;ObjectCollection&lt;/FONT&gt;, it now sets/gets an &lt;FONT color=darkblue&gt;object[]&lt;/FONT&gt; array object, which is the original type generated in the CodeDOM. The underlying field is still an &lt;FONT color=darkblue&gt;ObjectCollection&lt;/FONT&gt; type, and the collection &lt;FONT color=darkblue&gt;ToArray&lt;/FONT&gt; and &lt;FONT color=darkblue&gt;FromArray&lt;/FONT&gt; methods are used to get/set (respectively) the field correctly.&amp;nbsp;Using the original scalar types for de-/-serialization avoids the exception: '&lt;FONT color=darkblue&gt;ItemsElementName should be of type &lt;TYPE&gt;[]&lt;/FONT&gt;'. 
&lt;LI&gt;To support XML schemas that include an &lt;FONT color=darkblue&gt;xs:any&lt;/FONT&gt; element as part of the enumeration choice types, all &lt;FONT color=darkblue&gt;XmlAnyElementAttribute&lt;/FONT&gt; attributes for a member that also has an &lt;FONT color=darkblue&gt;XmlChoiceIndentiferAttribute&lt;/FONT&gt; attribute are removed. 
&lt;LI&gt;To support XML schemas that include an &lt;FONT color=darkblue&gt;xs:any&lt;/FONT&gt; element as part of the enumeration choice types, all &lt;FONT color=darkblue&gt;System.Xml.Serialization.XmlEnumAttribute("##any:")&lt;/FONT&gt; attributes are removed from the choice identifier enumerated type members. 
&lt;LI&gt;The attribute name is changed from '&lt;FONT color=darkblue&gt;ItemsElementName'&lt;/FONT&gt; to '&lt;FONT color=darkblue&gt;_ItemsElementName&lt;/FONT&gt;&lt;FONT color=darkblue&gt;'&lt;/FONT&gt;, and the normal property generation correctly generates the &lt;FONT color=darkblue&gt;_ItemsElementName &lt;/FONT&gt;array set/get property, using the &lt;FONT color=darkblue&gt;FromArray&lt;/FONT&gt; and &lt;FONT color=darkblue&gt;ToArray&lt;/FONT&gt; methods of the referenced collection class.&lt;/LI&gt;&lt;/UL&gt;&lt;/BLOCKQUOTE&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82545"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82545" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/82545.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/06/21/82545.aspx</guid>
            <pubDate>Wed, 21 Jun 2006 12:40:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/82545.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/06/21/82545.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/82545.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/82545.aspx</trackback:ping>
        </item>
        <item>
            <title>RSS 2.0 de-/-serialization (revisited)</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/06/19/82330.aspx</link>
            <description>&lt;P&gt;A while ago I posted this post on my blog:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://geekswithblogs.net/willemf/archive/2005/10/30/58562.aspx" target=_blank&gt;Reading RSS 2.0 feeds using the .NET XmlSerializer class&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Since that post, our &lt;A href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx" target=_blank&gt;&lt;STRONG&gt;&lt;FONT color=#000000&gt;Code&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;XS&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; code-generator tool has been updated. With the latest update of the tool due out this week, the code-generator correctly generates the de-/-serialization code to read and write RSS 2.0 feeds. It is now fairly simple to also create RSS feeds, as feed item objects can be easily created and added to the items collection, instead of trying to manipulate arrays.&lt;/P&gt;
&lt;P&gt;A simple example that uses the updated code can be downloaded here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.bware.biz/DotNet/Development/RSS/RSS._2_0.Serialization.zip"&gt;RSS._2_0.Serialization.zip&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The code language is C# and the solution and project files are for VS2003/.NET 1.1, but should migrate easily to VS2005/.NET 2.0.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82330"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82330" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/82330.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/06/19/82330.aspx</guid>
            <pubDate>Mon, 19 Jun 2006 18:20:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/82330.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/06/19/82330.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/82330.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/82330.aspx</trackback:ping>
        </item>
        <item>
            <title>VS2003/5 Enhancement Tip: Navigate directly to File Explorer</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/05/30/80063.aspx</link>
            <description>&lt;P&gt;Maybe this is the external tool that MS forgot to build into VS...?&lt;/P&gt;
&lt;P&gt;I often find that I need to open a File Explorer window in the folder that contains the file highlighted in the VS Solution Explorer. Manual navigation can be frustrating, and time-consuming.&lt;/P&gt;
&lt;P&gt;The easy solution is to define an external tool in the VS IDE as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Click the &lt;EM&gt;Tools/External Tools...&lt;/EM&gt; menu item. 
&lt;LI&gt;In the &lt;EM&gt;External Tools&lt;/EM&gt; Dialog, click the &lt;EM&gt;Add&lt;/EM&gt; button. 
&lt;LI&gt;In the &lt;EM&gt;Title&lt;/EM&gt; text box add: &lt;FONT face="Courier New" color=#ff0000&gt;Explorer&lt;/FONT&gt;, 
&lt;LI&gt;In the &lt;EM&gt;Command&lt;/EM&gt; text box add: &lt;FONT face="Courier New" color=#ff0000&gt;explorer.exe&lt;/FONT&gt;, 
&lt;LI&gt;In the &lt;EM&gt;Arguments&lt;/EM&gt; text box add: &lt;FONT face="Courier New" color=#ff0000&gt;/select,"$(ItemPath)"&lt;/FONT&gt;&lt;FONT color=#000000&gt;,&lt;/FONT&gt; 
&lt;LI&gt;In the &lt;EM&gt;Initial Directory&lt;/EM&gt; text box add: &lt;FONT face="Courier New" color=#ff0000&gt;$(ItemDir)&lt;/FONT&gt;. 
&lt;LI&gt;Click &lt;EM&gt;Ok&lt;/EM&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Now when you have a file highlighted in the solution window, click the &lt;EM&gt;Tools/Explorer&lt;/EM&gt; menu item in the VS IDE, and File Explorer opens up into the appropriate folder with the highlighted file in the VS Solution window selected in File Explorer.&lt;/P&gt;
&lt;P&gt;Works for VS2003, and VS2005.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=80063"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=80063" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/80063.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/05/30/80063.aspx</guid>
            <pubDate>Tue, 30 May 2006 12:02:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/80063.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/05/30/80063.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/80063.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/80063.aspx</trackback:ping>
        </item>
        <item>
            <title>x.doc - A code documentation manager addin for VS2005</title>
            <link>http://geekswithblogs.net/willemf/archive/2006/05/17/78717.aspx</link>
            <description>&lt;UL&gt;
&lt;LI&gt;&lt;A target=_blank href="http://www.codeproject.com/useritems/xdoc.asp"&gt;Article, add-in installer and source-code at Code Project&lt;/A&gt; 
&lt;LI&gt;&lt;A target=_blank href="http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Development/xdoc/Article/article.htm"&gt;Article, add-in installer and latest source-code at Businessware&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;x.doc&lt;/STRONG&gt; is a Visual Studio (VS) 2005 add-in that provides a means to manage and visualize source-code comment documentation interactively in the IDE. A screen-shot is shown below: &lt;/P&gt;
&lt;P&gt;&lt;IMG height=600 src="/images/geekswithblogs_net/willemf/4546/o_Figure1.gif" width=800&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Features&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;x.doc&lt;/STRONG&gt; provides two windows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;Visualizer&lt;/STRONG&gt; window which is the window that provides the rendered XML documentation text using a defined set of XSL templates and a CSS. This window is interactively updated as the caret is moved in a code-editor window. If the documentation is not well-formed XML or an error occurs in the rendering, an error is displayed in this window. If the caret is not positioned in a documentation block, the message "No documentation" is displayed. This window is implemented to work as a standard 'Tool Window' in the IDE, and can be floated, docked etc. like any other tool window. 
&lt;LI&gt;The &lt;STRONG&gt;Output&lt;/STRONG&gt; window which is similar to the IDE build window in that it displays the error with the appropriate source-code file path and line and character position offsets. Double-clicking the error line in this window will move the caret to the referenced editor window and offset in the code at which the error has occurred. It shares the standard output window and its content is displayed by selecting the x.doc menu-item in the 'Show output from:' selector.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;x.doc&lt;/STRONG&gt; provides a menu tool-strip above the Visualizer window, and is described below as they are ordered on the tool-strip (from left-to-right):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Prior Documentation Item&lt;/STRONG&gt;: This button command moves the caret to the prior documentation block in the code editor window and selects the block as shown in the diagram above. 
&lt;LI&gt;&lt;STRONG&gt;Next Documentation Item&lt;/STRONG&gt;: This command moves the caret to the next documentation block. 
&lt;LI&gt;&lt;STRONG&gt;Collapse All Documentation&lt;/STRONG&gt;: This command traverses the entire code document and outlines the documentation blocks. Each documentation block is shown only by three ellipses ('...') and is an effective way to quickly hide all the documentation. 
&lt;LI&gt;&lt;STRONG&gt;Import Documentation Item&lt;/STRONG&gt;: This button command imports the documentation from an external file and embeds it as a documentation block in the source-code. This will only happen if the caret is positioned over a single-line documentation block containing a well-formed &lt;INCLUDE&gt;tag that points to a valid external documentation file with a name attribute that can be resolved to a documentation item in the external file. 
&lt;LI&gt;&lt;STRONG&gt;Export Documentation Item&lt;/STRONG&gt;: This command reverses the action of the 'Import Documentation Item' above. The documentation block is exported to the external documentation file and a suitably formed &lt;INCLUDE&gt;tag is substituted in its place. (See The Code section for constraints on the use of this tag). Note that badly-formed XML is exported "as-is", so it is best to check the Output window for errors before exporting the documentation block. 
&lt;LI&gt;&lt;STRONG&gt;Import All Documentation&lt;/STRONG&gt;: This command works the same as the "Import Documentation Item" above, except that it traverses the entire source-code file and imports all documentation. 
&lt;LI&gt;&lt;STRONG&gt;Export All Documentation&lt;/STRONG&gt;: This command exports all documentation to the external documentation file, reversing the action executed by 'Import All Documentation' above. 
&lt;LI&gt;&lt;STRONG&gt;Documentation Display Style Selector&lt;/STRONG&gt;: This selection list will accommodate any number of XSL/CSS templates which are imported from external .xsl and .css files when the add-in is first loaded. The XSL/CSS files x.doc.xsl and x.doc.css are included with the x.doc add-in installer and provides a pseudo-MSDN documentation look-and-feel. Obviously, these files can be modified or more style files added, which can then be individually selected, causing the documentation to be immediately re-rendered using the selected style. It is also possible to extend the VS IDE documentation tags and provide customized documentation functionality. &lt;A target=_blank href="http://ndoc.sourceforge.net/"&gt;NDoc&lt;/A&gt; already does this to provide the various standards of documentation-styles, including their MSDN style, which is exactly like the Microsoft H1 and H2 Help.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;x.doc&lt;/STRONG&gt; is completely &lt;A target=_blank href="http://ndoc.sourceforge.net/"&gt;NDoc&lt;/A&gt; compatible, in that the XML files that are generated by VS when you compile with the /doc:file option can be used as-is with NDoc. This applies whether the documentation is read directly from the source-code, or from an external file.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=78717"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=78717" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/willemf/aggbug/78717.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Willem Fourie</dc:creator>
            <guid>http://geekswithblogs.net/willemf/archive/2006/05/17/78717.aspx</guid>
            <pubDate>Wed, 17 May 2006 23:09:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/willemf/comments/78717.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/willemf/archive/2006/05/17/78717.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/willemf/comments/commentRss/78717.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/willemf/services/trackbacks/78717.aspx</trackback:ping>
        </item>
    </channel>
</rss>