I'm trying to dynamically create and populate listview controls depending on the data that is available for a user. So, depending on the 'Types' in this user's records, 1-5 listivews would be created and populate. I don't want to create them in the client-side code because I created a CMS that would allow administrators to set each 'Type's display box size and order.

I've tried a good deal of strategies, but keep getting this error when i try to bind data:

An exception of type 'System.InvalidOperationException' occurred in System.Web.Extensions.dll but was not handled in user code

Additional information: An item placeholder must be specified on ListView '{ id = Technical }'. Specify an item placeholder by setting a control's ID property to "MyLayout$itemPlaceholder". The item placeholder control must also specify runat="server".

client-side .ascx control:

<asp:Table ID="RecordsTable" runat="server"/>

server-side:

    public void CreateRecordPanels (DataTable RecordsDT)
{
    var DistinctElementTypes = (RecordsDT.AsEnumerable()
               .Select(s => new 
               {
                   id = s.Field<string>("Type"),
               })
               .Distinct()).ToList();

    foreach(var Type in DistinctElementTypes)
    {
        ListView myListView = new ListView();
        myListView.ID = Type.ToString();

        myListView.ItemPlaceholderID = "MyLayout$itemPlaceholder";
        myListView.EmptyDataTemplate = new LiteralItemTemplate("No records");
        myListView.LayoutTemplate = new LiteralItemTemplate("<table><tr>" +
                    "<th></th>" +
                    "<th>Training Element</th>" +
                    "<th>Date</th>" +
                    "</tr>" +
                    "<tr id=\"MyLayout$itemPlaceholder\" runat=\"server\">    </tr>" + "</table>");
        myListView.ItemTemplate = new LiteralItemTemplate("<tr><td>" +
  "<a href=\"{Name}\">{Name}</a></td>" +
  "<td>{TrainingDate}</td></tr>");
        myListView.LayoutCreated += new EventHandler(myListView_LayoutCreated);

        //LoadTemplate("ItemTemplate.ascx");

        TableRow myTableRow = new TableRow();
        RecordsTable.Rows.Add(myTableRow);
        TableCell myTableCell = new TableCell();
        myTableRow.Cells.Add(myTableCell);
        myTableCell.Controls.Add(TechnicalTraining);

        myListView.DataSource = RecordsDT;
        myListView.DataBind();

    }

}

public void myListView_LayoutCreated(object sender, EventArgs e)
{
    //remove the layout template
    ListView myListView = (ListView)sender;
    myListView.Controls.RemoveAt(0);

    //recreate it
    Control newLayoutContainer = new Control();
    myListView.LayoutTemplate.InstantiateIn(newLayoutContainer);
    var userControl = newLayoutContainer.Controls[0];
    userControl.ID = "MyLayout";
    myListView.Controls.Add(newLayoutContainer);
}
}

public class LiteralItemTemplate : IBindableTemplate
{
private string formatString;
public delegate string LambdaExpr(object container);
public Dictionary<string, string > LambdaDictionary = new Dictionary<string, string>();

public LiteralItemTemplate(string FormatString)
{
    formatString = FormatString;
}

public void InstantiateIn(Control container)
{
    LiteralControl ctl = new LiteralControl();
    ctl.DataBinding += new EventHandler(OnDataBinding);
    container.Controls.Add(ctl);
}

public void OnDataBinding(object sender, EventArgs e)
{
    LiteralControl target = (LiteralControl)sender;
    Control item = target.BindingContainer;
    ListViewDataItem LVitem = new ListViewDataItem(0,0);
    LVitem.DataItem = item;
    target.Text = Regex.Replace(formatString, @"(\{.+?\})",
            m =>
            {
                string word = m.Groups[1].Value;
                int ind = word.IndexOf(':');
                return string.Format(
                    string.Format("{{0{0}}}",
                        (ind > 0) ? word.Substring(
                           ind, word.Length - ind - 1) : string.Empty
                        ),
                    evaluateKey(LVitem, word.Substring(
                              1, ((ind>0)?(ind-1):(word.Length - 2))))
                    );
            });
}

private object evaluateKey(object container, string key)
{
    return (LambdaDictionary.ContainsKey(key))?
      LambdaDictionary[key]:DataBinder.Eval(container, key);
}

public System.Collections.Specialized.IOrderedDictionary ExtractValues(Control container)
{
    System.Collections.Specialized.OrderedDictionary _table = 
       new System.Collections.Specialized.OrderedDictionary();
    return _table;
}

Related posts

Recent Viewed