Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight 2, Html DOM Interoperability ( 2 )
Mike Taulty's Blog

Mike's Badges

Follow on Twitter
View mike's profile on slideshare
Add to Technorati Favorites
CW Blog Awards

Following on from this post, I changed the library code that I was using a little to make the job of creating HTML ( specifically in my case a table ) in Silverlight 2 easier again.

If I want to get hold of a div called myDiv and create a table within it then I can do ( as an example );

      HtmlElement el = HtmlPage.Document.GetElementById("myDiv");

      el.Add(
        new HElement(HElementType.table,
          new HElement(HElementType.tbody,
            new HElement(HElementType.tr,
              HElement.Replicate(HElementType.th, "Number", "Squared", "Cubed")),
            from i in Enumerable.Range(1, 10)
            select new HElement(HElementType.tr,
              HElement.Replicate(HElementType.td, i.ToString(), (i * i).ToString(), (i * i * i).ToString()),
              new HElement(HElementType.td,
                new HElement(HElementType.input,
                  new HAttribute(HAttributeType.type, "button"),
                  new HAttribute(HAttributeType.value, "click"),
                  new HEventHandler(HEventType.onclick,
                    (s, a) => MessageBox.Show(string.Format("You click on row number {0}", i)))))))));

I changed the supporting classes around a little - here they are;

public enum HElementType
{
  html,
  body,
  table,
  tbody,
  tr,
  td,
  th,
  input
  // etc...
}

public enum HEventType
{
  onclick
  // etc...
}

public enum HStyleType
{
  width,
  height
  // etc...
}

public enum HAttributeType
{
  type,
  value,
  innerText
  // etc...
}

internal static class Utility
{
  internal static string EnumToString<T>(object enumValue)
  {
    return (Enum.GetName(typeof(T), enumValue));
  }
}

public static class HtmlElementExtensions
{
  public static void Add(this HtmlElement parent, IEnumerable<HElement> elements)
  {
    foreach (HElement item in elements)
    {
      parent.AppendChild(item);
    }
  }
  public static void Add(this HtmlElement parent, params HElement[] elements)
  {
    foreach (HElement item in elements)
    {
      parent.AppendChild(item);
    }
  }
}
public class HAttribute
{
  public HAttribute(HAttributeType type, string value)
  {
    this.Type = type;
    this.Value = value;
  }
  public HAttributeType Type { get; set; }
  public string Value { get; set; }
}
public class HStyleAttribute
{
  public HStyleAttribute(HStyleType type, string value)
  {
    this.Type = type;
    this.Value = value;
  }
  public HStyleType Type { get; set; }
  public string Value { get; set; }
}
public class HEventHandler
{
  public HEventHandler(HEventType eventType, EventHandler<HtmlEventArgs> handler)
  {
    this.Type = eventType;
    this.Handler = handler;
  }
  public HEventType Type { get; set; }
  public EventHandler<HtmlEventArgs> Handler { get; set; }
}
public class HElement
{
  public static implicit operator HtmlElement(HElement el)
  {
    return (el.element);
  }
  public HElement(HElementType elementType, params object[] items)
  {
    element = HtmlPage.Document.CreateElement(Utility.EnumToString<HElementType>(elementType));
    AddItems(items);
  }
  public HElement(HElementType elementType, string value) : 
    this(elementType, new HAttribute(HAttributeType.innerText, value))
  {
  }
  public static IEnumerable<HElement> Replicate<T>(HElementType elementType,
    T parameter, params Func<T, string>[] actions)
  {
    foreach (Func<T, string> action in actions)
    {
      yield return new HElement(elementType, action(parameter));
    }
  }
  public static IEnumerable<HElement> Replicate(HElementType elementType,
    params string[] contents)
  {
    foreach (string content in contents)
    {
      yield return new HElement(elementType, content);
    }
  }
  void AddItems(object[] items)
  {
    foreach (object o in items)
    {
      if (o.GetType() == typeof(HElement))
      {
        AddSubElement((HElement)o);
      }
      else if (o.GetType() == typeof(HAttribute))
      {
        AddAttribute((HAttribute)o);
      }
      else if (o.GetType() == typeof(HStyleAttribute))
      {
        AddStyleAttribute((HStyleAttribute)o);
      }
      else if (o.GetType() == typeof(HEventHandler))
      {
        AddHandler((HEventHandler)o);
      }
      else
      {
        IEnumerable<HElement> elementList = o as IEnumerable<HElement>;

        if (elementList != null)
        {
          foreach (HElement el in elementList)
          {
            AddSubElement(el);
          }
        }
        else
        {
          IEnumerable<HAttribute> attrList = o as IEnumerable<HAttribute>;

          if (attrList != null)
          {
            foreach (HAttribute attr in attrList)
            {
              AddAttribute(attr);
            }
          }
          else
          {
            IEnumerable<HStyleAttribute> styleList = o as IEnumerable<HStyleAttribute>;

            if (styleList != null)
            {
              foreach (HStyleAttribute style in styleList)
              {
                AddStyleAttribute(style);
              }
            }
            else
            {
              throw new InvalidOperationException("Parameter type not supported");
            }
          }
        }
      }
    }
  }

  void AddHandler(HEventHandler handler)
  {
    element.AttachEvent(Utility.EnumToString<HEventType>(handler.Type), handler.Handler);
  }

  void AddStyleAttribute(HStyleAttribute styleAttribute)
  {
    element.SetStyleAttribute(Utility.EnumToString<HStyleType>(styleAttribute.Type), 
      styleAttribute.Value);
  }

  void AddAttribute(HAttribute attribute)
  {
    element.SetAttribute(Utility.EnumToString<HAttributeType>(attribute.Type), attribute.Value);
  }

  void AddSubElement(HElement subElement)
  {
    element.AppendChild(subElement);
  }
  HtmlElement element;
}

Posted Fri, Oct 17 2008 5:17 PM by mtaulty
Filed under: ,

Comments

Community Blogs wrote Silverlight Cream for October 18, 2008 -- #399
on Sat, Oct 18 2008 11:22 PM
In this issue: Shawn Wildermuth, Laurence Moroney, Dave Relyea, Mike Taulty, Andy Beaulieu, Brad Abrams
Bondage By Request 113007 wrote Bondage By Request 113007
on Sun, Oct 19 2008 1:26 AM
Silverlight news for October 20, 2008 wrote Silverlight news for October 20, 2008
on Mon, Oct 20 2008 5:18 AM
2008 October 21 - Links for today « My (almost) Daily Links wrote 2008 October 21 - Links for today &laquo; My (almost) Daily Links
on Tue, Oct 21 2008 1:33 AM
(C) Mike Taulty, 2009. All rights reserved. The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems