Wednesday, May 12, 2010

Creating Run time table in Silverlight using html

Hi, after a long time I am back with a new post. Recently during a completly dynamic silverlight framework developement I had to create dynamic layout which can create tabular layout as was created in html. eg.






You can see here the html for a table and its representation. I had to read this html at runtime and create a similar layout in silverlight at run time. That layout was actually the layout of the main shell of the framework.
The html part I put into somewhere in the clientbin and instructed in the code to read it using web-client. Once the xml was read it was sent to be processed by the service class.

Entity:
    public enum VAlignment
{
bottom = 1, middle = 2, top = 3, stretch = 4
}

public enum HAlignment
{
center = 1, left = 2, right = 3, stretch = 4
}

public enum Unit
{
pixcel = 1, percent = 2
}

public class TableBase
{
private HAlignment _HAlign;
private VAlignment _VAlign;
private string _Height;
private double _height;
private string _Width;
private double _width;

public string Name { get; set; }

public string SetWidth
{
set
{
_Width = value;

if (double.TryParse(_Width, out _width))
{
WidthUnit = Unit.pixcel;
}
else
{
if (_Width.Trim().Length > 0 && _Width.Trim().Split(new char[] { '%' }).Length > 1)
{
if (double.TryParse(_Width.Trim().Split(new char[] { '%' })[0], out _width))
{
WidthUnit = Unit.percent;
}
}
else
{
if (_Width.Trim().Length > 0 && _Width.Trim().Substring(_Width.Trim().Length - 2, _Width.Trim().Length).ToLower() == "px")
{
if (double.TryParse(_Width.Trim().Substring(0, _Width.Trim().Length - 2), out _width))
{
WidthUnit = Unit.pixcel;
}
}
}
}
}
get
{
return _Width;
}
}

public double GetWidth
{
get
{
return _width;
}
}

public string SetHeight
{
set
{
_Height = value;

if (double.TryParse(_Height, out _height))
{
HeightUnit = Unit.pixcel;
}
else
{
if (_Height.Trim().Length > 0 && _Height.Trim().Split(new char[] { '%' }).Length > 1)
{
if (double.TryParse(_Height.Trim().Split(new char[] { '%' })[0], out _height))
{
HeightUnit = Unit.percent;
}
}
else
{
if (_Height.Trim().Length > 0 && _Height.Trim().Substring(_Height.Trim().Length - 2, _Height.Trim().Length).ToLower() == "px")
{
if (double.TryParse(_Height.Trim().Substring(0, _Height.Trim().Length - 2), out _height))
{
HeightUnit = Unit.pixcel;
}
}
}
}
}
get
{
return _Height;
}
}

public double GetHeight
{
get
{
return _height;
}
}

public Unit WidthUnit { get; private set; }

public Unit HeightUnit { get; private set; }

public string SetHAlign
{
set
{
if (value.ToLower() == "center") _HAlign = HAlignment.center;
else
if (value.ToLower() == "left") _HAlign = HAlignment.left;
else
if (value.ToLower() == "right") _HAlign = HAlignment.right;
else
if (value.ToLower() == "stretch") _HAlign = HAlignment.stretch;
else
_HAlign = HAlignment.center;
}
}

public HAlignment GetHAlign
{
get
{
return _HAlign;
}
}

public string SetVAlign
{
set
{
if (value.ToLower() == "middle") _VAlign = VAlignment.middle;
else
if (value.ToLower() == "bottom") _VAlign = VAlignment.bottom;
else
if (value.ToLower() == "top") _VAlign = VAlignment.top;
else
if (value.ToLower() == "stretch") _VAlign = VAlignment.stretch;
else
_VAlign = VAlignment.middle;
}
}

public VAlignment GetVAlign
{
get
{
return _VAlign;
}
}
}

public class Table : TableBase
{
public List<TypeRow> TR { get; set; }
}
---------------------------------------------------------------------------------------------
Helper Class:
        private static XElement XMLStructure()
{
return XElement.Load(@"Data/LayoutStructure.xml");
}

public static IEnumerable<Table> GetTables()
{
XElement documentRoot = XMLStructure();
List<Table> tblList = new List<Table>();
foreach (XNode node in documentRoot.Nodes())
{
XElement childElement = XElement.Parse(node.ToString());
if (childElement.Name.LocalName == "table")
{
Table tbl = new Table();
tbl.Name = childElement.Attribute("id") != null ? childElement.Attribute("id").Value : "";
tbl.SetWidth = childElement.Attribute("width") != null ? childElement.Attribute("width").Value : "";
tbl.SetHeight = childElement.Attribute("height") != null ? childElement.Attribute("height").Value : "";
tbl.SetHAlign = childElement.Attribute("align") != null ? childElement.Attribute("align").Value : "";
tbl.SetVAlign = childElement.Attribute("valign") != null ? childElement.Attribute("valign").Value : "";

tbl.TR = getTR(childElement);
tblList.Add(tbl);
}
}
return tblList;
}

private static List<TypeRow> getTR(XElement doc)
{
List<TypeRow> trList = new List<TypeRow>();
foreach (XNode node in doc.Nodes())
{
XElement childElement = XElement.Parse(node.ToString());
if (childElement.Name.LocalName == "tr")
{
TypeRow tr = new TypeRow();
tr.Name = childElement.Attribute("id") != null ? childElement.Attribute("id").Value : "";
tr.SetWidth = childElement.Attribute("width") != null ? childElement.Attribute("width").Value : "";
tr.SetHeight = childElement.Attribute("height") != null ? childElement.Attribute("height").Value : "";
tr.SetHAlign = childElement.Attribute("align") != null ? childElement.Attribute("align").Value : "";
tr.SetVAlign = childElement.Attribute("valign") != null ? childElement.Attribute("valign").Value : "";

tr.TD = getTD(childElement);
trList.Add(tr);
}
}
return trList;
}

private static List<TypeData> getTD(XElement doc)
{
List<TypeData> tdList = new List<TypeData>();
foreach (XNode node in doc.Nodes())
{
XElement childElement = XElement.Parse(node.ToString());
if (childElement.Name.LocalName == "td")
{
TypeData td = new TypeData();
td.Name = childElement.Attribute("id") != null ? childElement.Attribute("id").Value : "";
td.SetWidth = childElement.Attribute("width") != null ? childElement.Attribute("width").Value : "";
td.SetHeight = childElement.Attribute("height") != null ? childElement.Attribute("height").Value : "";
td.SetHAlign = childElement.Attribute("align") != null ? childElement.Attribute("align").Value : "";
td.SetVAlign = childElement.Attribute("valign") != null ? childElement.Attribute("valign").Value : "";

td.TABLE = getTable(childElement);
tdList.Add(td);
}
}
return tdList;
}

private static List<Table> getTable(XElement obj)
{
List<Table> tblList = new List<Table>();
foreach (XNode node in obj.Nodes())
{
XElement childElement = XElement.Parse(node.ToString());
if (childElement.Name.LocalName == "table")
{
Table tbl = new Table();
tbl.Name = childElement.Attribute("id") != null ? childElement.Attribute("id").Value : "";
tbl.SetWidth = childElement.Attribute("width") != null ? childElement.Attribute("width").Value : "";
tbl.SetHeight = childElement.Attribute("height") != null ? childElement.Attribute("height").Value : "";
tbl.SetHAlign = childElement.Attribute("align") != null ? childElement.Attribute("align").Value : "";
tbl.SetVAlign = childElement.Attribute("valign") != null ? childElement.Attribute("valign").Value : "";

tbl.TR = getTR(childElement);
tblList.Add(tbl);
}
}
return tblList;
}
------------------------------------------------------------------------------------------
Service Class:
public UIElement GetUI()
{
GridList = new List<Grid>();
IEnumerable<Table> TableCollection = XmlHelper.GetTables();
Grid grd = new Grid();
grd.SetValue(Grid.RowProperty, 0);
grd.SetValue(Grid.ColumnProperty, 0);
grd.Width = LayoutWidth;
grd.Height = LayoutHeight;
if (TableCollection.Count() > 0)
{
grd = CreateTable(TableCollection.First(), grd);
SetPostProperties(grd);
}

return grd;
}

private void SetPostProperties(Grid grd)
{
double widthSum=0, heightSum=0, cntWidth=0, cntHeight=0;

if (grd.Children.Count != grd.RowDefinitions.Count)
{
foreach (UIElement ele in grd.Children)
{
if (ele.GetType().Name == "Grid")
{
if (!double.IsNaN(((Grid)ele).Width))
widthSum += ((Grid)ele).Width;
else
cntWidth += 1;


}
}
}

if (grd.Children.Count != grd.ColumnDefinitions.Count)
{
foreach (UIElement ele in grd.Children)
{
if (ele.GetType().Name == "Grid")
{


if (!double.IsNaN(((Grid)ele).Height))
heightSum += ((Grid)ele).Height;
else
cntHeight += 1;
}
}
}

if(cntWidth==0) cntWidth=1;
if(cntHeight==0) cntHeight=1;

foreach (UIElement ele in grd.Children)
{
if (ele.GetType().Name == "Grid")
{
if (double.IsNaN(((Grid)ele).Width) && cntWidth>0) ((Grid)ele).Width = (((Grid)((Grid)ele).Parent).Width - widthSum) / cntWidth;
if (double.IsNaN(((Grid)ele).Height) && cntHeight>0) ((Grid)ele).Height = (((Grid)((Grid)ele).Parent).Height - heightSum) / cntHeight;

SetPostProperties((Grid)ele);
}
}
}



#endregion

private Grid CreateTable(Table tab, Grid grd)
{
grd = SetGridProperty(tab, grd);

foreach (TypeRow tr in tab.TR)
{
RowDefinition rd = new RowDefinition();
if (tr.HeightUnit == 0)
rd.Height = new GridLength(1.0,GridUnitType.Star);
else
rd.Height = new GridLength(tr.GetHeight);

grd.RowDefinitions.Add(rd);
}

int i = 0;
foreach (TypeRow tr in tab.TR)
{
Grid grdchild = new Grid();
grdchild = SetGridProperty(tr, grdchild);
grdchild.SetValue(Grid.RowProperty, i);


foreach (TypeData td in tr.TD)
{
ColumnDefinition cd = new ColumnDefinition();
if (td.WidthUnit == 0)
cd.Width = new GridLength(1.0, GridUnitType.Star);
else
cd.Width = new GridLength(td.GetWidth);
grdchild.ColumnDefinitions.Add(cd);
}

int j = 0;
foreach (TypeData td in tr.TD)
{
Grid grdgrandchild = new Grid();
grdgrandchild = SetGridProperty(td, grdgrandchild);
grdgrandchild.SetValue(Grid.ColumnProperty, j);

if (td.TABLE.Count > 0)
{
Grid paramGrid = new Grid();
paramGrid.SetValue(Grid.RowProperty, i);
paramGrid.SetValue(Grid.ColumnProperty, j);
Table childtab = td.TABLE.First();
grdgrandchild.Children.Add(CreateTable(childtab, paramGrid));
//SetGridProperty(childtab, paramGrid);
}
j++;

GridList.Add(grdgrandchild);
grdchild.Children.Add(grdgrandchild);
//SetGridProperty(td, grdgrandchild);
}
GridList.Add(grdchild);
grd.Children.Add(grdchild);
//SetGridProperty(tr, grdchild);
i++;
}
GridList.Add(grd);
return grd;
}

private Grid SetGridProperty(TableBase tab, Grid grd)
{
//grd.ShowGridLines = true;
//grd.Background = new SolidColorBrush(Colors.Orange);
if(tab.Name!="")
grd.Name = tab.Name;

if (tab.Name == "ContentGrid")
{
grd.ColumnDefinitions.Add(new ColumnDefinition() {Width=new GridLength(0.0) });
grd.ColumnDefinitions.Add(new ColumnDefinition());
}

if (grd.Parent != null && grd.Parent.GetType().Name == "Grid")
{
grd.Width = ((Grid)grd.Parent).ActualWidth;
grd.Height = ((Grid)grd.Parent).ActualHeight;
}

if (tab.WidthUnit == Unit.percent)
grd.Width = (grd.ActualWidth * tab.GetWidth) / 100;
else
if (tab.WidthUnit == Unit.pixcel)
grd.Width = tab.GetWidth;

if (tab.HeightUnit == Unit.percent)
grd.Height = (grd.ActualHeight * tab.GetHeight) / 100;
else
if (tab.HeightUnit == Unit.pixcel)
grd.Height = tab.GetHeight;

if (tab.GetVAlign == VAlignment.bottom) grd.VerticalAlignment = VerticalAlignment.Bottom;
else
if (tab.GetVAlign == VAlignment.middle) grd.VerticalAlignment = VerticalAlignment.Center;
else
if (tab.GetVAlign == VAlignment.stretch) grd.VerticalAlignment = VerticalAlignment.Stretch;
else
if (tab.GetVAlign == VAlignment.top) grd.VerticalAlignment = VerticalAlignment.Top;


if (tab.GetHAlign == HAlignment.center) grd.HorizontalAlignment = HorizontalAlignment.Center;
else
if (tab.GetHAlign == HAlignment.left) grd.HorizontalAlignment = HorizontalAlignment.Left;
else
if (tab.GetHAlign == HAlignment.right) grd.HorizontalAlignment = HorizontalAlignment.Right;
else
if (tab.GetHAlign == HAlignment.stretch) grd.HorizontalAlignment = HorizontalAlignment.Stretch;

return grd;
}