Tag: C#

  • Design patterns

    An excellent reference for gang of four design patterns: http://www.dofactory.com/Patterns/Patterns.aspx

  • HTML Table to ASP.NET Table

    To convert an HTML table (from a string) to an ASP.NET table:

    Start with an HTML table:

    <table style="width: 100%;">
    <tr>
    <td colspan="2">
    <fieldset title="Policy Information">
    <legend><b>Policy Information</b></legend>
    <table style="width: 100%;">
    <tr>
    <td width="140">Policy Number:</td>
    <td width="150">$$Policy Number$$</td>
    </tr>
    </table>
    </fieldset>
    </td>
    </tr>
    </table>
    

    Create a Helper class:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Xml;
    using System.Web.UI.WebControls;
    using System.Web.UI;
    using System.Drawing;&amp;lt;/pre&amp;gt;
    namespace Whatever
     {
     public static class TableHelper
     {
     public static Table m_table = new Table();
    
    public static Table CreateASPTableFromXML(XmlNode node)
     {
     Table table;
     /// fetch the root table node, this will iteratively fetch the rest.
     table = GetTableFromNode(node);
    
    return table;
     }
    
    static Table GetTableFromNode(XmlNode node)
     {
     Table table = new Table();
     table.BorderStyle = BorderStyle.Solid;
     table.BorderColor = Color.Black;
     table.BorderWidth = Unit.Pixel(1);
    
    /// create the table
     if (node.Name.ToLower() != "table")
     {
     throw new Exception(string.Format("'table' element expected, {0} found.", node.Name));
     }
    
    /// apply the attributes
     ApplyAttributesToControl
    
    (node.Attributes, ref table);// From this table element find all the child rows
     foreach (XmlNode rowNode in node.ChildNodes)
     {
     table.Rows.Add(GetRowFromNode(rowNode));
     }
    
    //TableRow row = new TableRow();
     //TableCell cell = new TableCell() { Text = "here" };
     //row.Cells.Add(cell);
    
    //table.Rows.Add(row);
    
    return table;
     }
    
    static TableRow GetRowFromNode(XmlNode node)
     {
     /// create the tableRow
     TableRow tableRow = new TableRow();
    
    if (node.Name.ToLower() != "tr")
     {
     throw new Exception(string.Format("'tr' element expected, {0} found.", node.Name));
     }
    
    /// apply the attributes
     ApplyAttributesToControl(node.Attributes, ref tableRow);
    
    // From this table row element find all the child cells
     foreach (XmlNode cellNode in node.ChildNodes)
     {
     tableRow.Cells.Add(GetCellFromNode(cellNode));
     }
    
    return tableRow;
    
    }
    
    /// Process each cell and look for content.
     static TableCell GetCellFromNode(XmlNode node)
     {
     /// create the tableRow
     TableCell tableCell = new TableCell();
    
    if (node.Name.ToLower() != "td")
     {
     throw new Exception(string.Format("'td' element expected, {0} found.", node.Name));
     }
    
    /// apply the attributes
     ApplyAttributesToControl(node.Attributes, ref tableCell);
    
    /// From this table row element find all the child objects
     /// these might be tables, text or html objects
     if (node.HasChildNodes)
     {
    
    foreach (XmlNode childNode in node.ChildNodes)
     {
     /// this might be an HTML object or another table... or both... (gulp)
     if (childNode.NodeType == XmlNodeType.Element)
     {
     if (childNode.Name.ToLower() == "table")
     {
     tableCell.Controls.Add(GetTableFromNode(childNode));
     }
    
    if (childNode.Name.ToLower() == "fieldset")
     {
     tableCell.Controls.Add(GetPanelFromNode(childNode));
     }
     }
     else if (childNode.NodeType == XmlNodeType.Text)
     {
     tableCell.Text = childNode.InnerText;
     }
     }
     }
    
    return tableCell;
    
    }
    
    /// Process each cell and look for content.
     static Panel GetPanelFromNode(XmlNode node)
     {
     /// create the tableRow
     Panel panel = new Panel();
    
    if (node.Name.ToLower() != "fieldset")
     {
     throw new Exception(string.Format("'fieldset' element expected, {0} found.", node.Name));
     }
    
    /// apply the attributes
     ApplyAttributesToControl(node.Attributes, ref panel);
    
    /// From this panel element find all the child objects
     /// one of which will be a legend tag
     /// then it might be HTML elements, tables or text
     if (node.HasChildNodes)
     {
     /// the legend node will be applied as a panel GroupingText property
    
    foreach (XmlNode childNode in node.ChildNodes)
     {
     /// this might be an HTML object or another table... or both... (gulp)
     if (childNode.Name.ToLower() == "legend")
     {
     panel.GroupingText = childNode.InnerText;
     }
    
    if (childNode.Name.ToLower() == "table")
     {
     panel.Controls.Add(GetTableFromNode(childNode));
     }
     }
     }
     else if (node.InnerText != string.Empty)
     {
     panel.Controls.Add(new Literal() { Text = node.InnerXml});
     }
    
    return panel;
    
    }
    
    ///
    
     /// Add attributes to any web control
     ///
    
    /// Reference to the control to which the attributes are being added
     /// The attributes being added
     static void ApplyAttributesToControl( XmlAttributeCollection attribs, ref T ctrl)
     where T : WebControl
     {
     foreach (XmlAttribute attrib in attribs)
     {
     ctrl.Attributes.Add(attrib.Name, attrib.Value);
     }
     }
    
    }
     }
    
    

    Open the HTML file, and pass the root node to the helper class:

    Table table;
    
    /// check if a template exists for this request form...
     /// TODO: Update this to use the request form name, not the ID.
     string TemplatePath = Server.MapPath(string.Format("~/Private/RequestFormTemplates/{0}.xml", _selectedRequestId));
     if (File.Exists(TemplatePath))
     {
     System.IO.StreamReader myFile = new System.IO.StreamReader(TemplatePath);
     string myString = myFile.ReadToEnd();
     myFile.Close();
     myFile.Dispose();
    
    FileStream fs = new FileStream(TemplatePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
     XmlDocument xmldoc = new XmlDocument();
     xmldoc.Load(fs);
    
    table = TableHelper.CreateASPTableFromXML(xmldoc.DocumentElement);
    
    }
    

    The helper class needs to be fleshed out some more, to provide support for other elements and valid HTML, but it’s almost there.

    If there is an easier way, let me know!

  • C# Reading content from text files

    This is something I do frequently, and I always forget the streaming syntax, so here it is. There are couple of ways to do this. Firstly, from an application:

    1. From the properties panel, set the Build Action as Resource and the Copy to Output Directory as Copy Always
    2. From code this can then be accessed with:
    public class ListOfStrings: List
    {
    //@ctor
    public ListOfStrings()
    {
    string line;

    StreamResourceInfo sri = App.GetResourceStream(new Uri("Namespace;component/filename.txt", UriKind.Relative));
    using (TextReader tr = new StreamReader(sri.Stream))
    {
    while ((line = tr.ReadLine()) != null)
    {
    Add(tr.ReadLine());
    }
    }
    }
    }

    NOTE: Namespace;component/filename.txt: the Namespace and filename have to be replaced. Leave in the component syntax

    In a class library, it is slightly different.

    1. From the properties panel, set the Build Action as Embedded Resource
    2. From code this can then be accessed with:

    public class ListOfStrings: List
    {
    //@ctor
    public ListOfStrings()
    {
    string line;

    Assembly assembly = Assembly.GetExecutingAssembly();
    Stream stream = assembly.GetManifestResourceStream("Namespace.ResourceFolder.Filename.txt");

    using (TextReader tr = new StreamReader(stream))
    {
    while ((line = tr.ReadLine()) != null)
    {
    Add(tr.ReadLine());
    }
    }
    }
    }

     
    NOTE: Namespace.ResourceFolder. has to be replaced with a suitable value.

    Obviously, both examples return at list of string objects, one object per line.

  • C# Event Delegates

    Using the “+=” notation when creating delegate event is a really fast
    way of coding but there is a caveat if the delegate is declared in the
    wrong place. for example declaring the handler inline, in a method:

    private void btn_Click(object sender, System.Windows.RoutedEventArgs e)
    {
    EventBus.Event+= new EventHandler(EventBus_Event);
    //….do code here
    }

    When the btn_Click method is fired, an event handler is added to the
    EventBus.Event event. The clue (and problem) here is the worded
    “added”. If the btn_Click method is fired again, another identical
    handler is added, so now you have two. These will continue processing
    requests asyncronously, and continue to fire off your additional
    logic.. oh dear!

    To resolve this, simply abstrac the Event Delegation away from the UI
    method calls, unless they are being specifically created and removed
    for specific scenarios. I now add mine during class initialisation for
    generic events:

    private void EventBusDelegateEventHandlers()
    {
    //event handlers, these delegate control from the EventBus events.
    EventBus.Event1+= new EventHandler(EventBus_Event1);
    EventBus.Event2+= new EventHandler(EventBus_Event2);
    EventBus.Event3+= new EventHandler(EventBus_Event3);
    EventBus.Event4+= new EventHandler(EventBus_Event4);
    }

    I’m also using a centralised EventBus class that allows me to call and
    handle events across classes.