This is a migrated thread and some comments may be shown as answers.

Can't find my controls on ItemCreated

3 Answers 93 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Christophe
Top achievements
Rank 1
Christophe asked on 06 Feb 2013, 01:53 AM
Hi there,

I browsed the forum and check the online help documentation as well but no matter what I can't get it to work.
The doc says :

protected void RadListView1_ItemCreated(object sender, RadListViewItemEventArgs e)
{
    if (e.Item is RadListViewDataItem)
    {
        Label label = e.Item.FindControl("Label1") as Label;
    }
}
It looks pretty easy but still. See below my code. I'm creating a ListView in the code behind since I need to name some controls using IDs of some of my DB objects. Therefore in my ItemTemplate and AlternatatingItemTemplate (as described here : telerik doc) I needed to bind the Table element to get the required ID from the DB prior to building up the controls inside:
protected void Page_Init(object sender, EventArgs e)
        {
            rlvConfigGng = new RadListView();
            rlvConfigGng.ID = "rlvConfigGng";
            rlvConfigGng.DataSourceID = "dsConfigGng";
            rlvConfigGng.ItemCommand += new EventHandler<RadListViewCommandEventArgs>(rlvConfigGng_ItemCommand);
            rlvConfigGng.LayoutTemplate = new LayoutTemplate();
            rlvConfigGng.ItemTemplate = new ItemTemplate();
            rlvConfigGng.AlternatingItemTemplate = new AlternItemTemplate();
            rlvConfigGng.InsertItemTemplate = new InsertTemplate();
            rlvConfigGng.EditItemTemplate = new EditItemTemplate();
            rlvConfigGng.ItemPlaceholderID = "itemPlaceholder";
 
// This is where I declare my event handler when an Item has been created
            rlvConfigGng.ItemCreated += new EventHandler<RadListViewItemEventArgs>(rlvConfigGng_ItemCreated);
 
            var rbtInsert = new RadButton();
            rbtInsert.ID = "rbtInsert";
            rbtInsert.Text = "Create New Set";
            rbtInsert.Icon.PrimaryIconCssClass = "rbAdd";
            rbtInsert.Click += new EventHandler(rbtInsert_Click);
 
// gngPlaceHolder is the PlaceHolder defined in my aspx page and containing my ListView
            gngPlaceHolder.Controls.Add(rlvConfigGng);
            gngPlaceHolder.Controls.Add(rbtInsert);
        }   
 
        void rlvConfigGng_ItemCreated(object sender, RadListViewItemEventArgs e)
        {
            if (e.Item is RadListViewDataItem)
            {
                var item = e.Item as RadListViewDataItem;
                var n = e.Item.FindControl("rtbValue_1_1") as RadNumericTextBox;
// n is ALWAYS null. I can't find my control in there  :(
            }
        }
 
public class ItemTemplate : ITemplate
    {
        #region ITemplate Members
        private int _idx { get; set; }
 
        public ItemTemplate()
        {
            _idx = 1;
        }
 
        public void InstantiateIn(Control container)
        {
 
            var ItemTable = new Table();
            ItemTable.DataBinding += new EventHandler(ItemTable_DataBinding);
 
            container.Controls.Add(ItemTable);
        }
 
        void ItemTable_DataBinding(object sender, EventArgs e)
        {
            Table ItemTable = (Table)sender;
            var setId = new Label(); // This is the label holding the DB value, and the reason why I need to put that code in my databinding event
            setId.ID = "setId";
            setId.Text = ((ItemTable.NamingContainer as RadListViewDataItem).DataItem as DataRowView)["SetId"].ToString();
            var ItemTableRow1 = new TableRow();
            var ItemTableRow2 = new TableRow();
            var ItemTableRow3 = new TableRow();
            var ItemTableRow4 = new TableRow();
            var ItemTableRow5 = new TableRow();
            var ItemTableRow6 = new TableRow();
 
            ItemTable.CssClass = "gngSets";
            for (var cnt = 0; cnt < 13; cnt++)
                ItemTableRow1.Cells.Add(new TableCell());
 
            var rbtDelete = new ImageButton();
            rbtDelete.CommandName = "Delete";
            rbtDelete.CommandArgument = setId.Text;
 
            ItemTableRow1.Cells[0].Controls.Add(setId);
            ItemTableRow1.Cells[0].RowSpan = 6;
            ItemTableRow1.Cells[0].Controls.Add(rbtDelete);
            ItemTableRow1.Cells[2].Controls.Add(new Label() { Text = "Value" });
            ItemTableRow1.Cells[3].Controls.Add(new Label() { Text = "Display Message" });
            ItemTableRow1.Cells[4].Controls.Add(new Label() { Text = "#" });
            ItemTableRow1.Cells[5].Controls.Add(new Label() { Text = "Go ?" });
            ItemTableRow1.Cells[6].Controls.Add(new Label() { Text = "Enable" });
            ItemTableRow1.Cells[8].Controls.Add(new Label() { Text = "Value" });
            ItemTableRow1.Cells[9].Controls.Add(new Label() { Text = "Display Message" });
            ItemTableRow1.Cells[10].Controls.Add(new Label() { Text = "#" });
            ItemTableRow1.Cells[11].Controls.Add(new Label() { Text = "Go ?" });
            ItemTableRow1.Cells[12].Controls.Add(new Label() { Text = "Enable" });
 
// This part generate TableCells collection to embed my controls
            ItemTableRow2.Cells.AddRange(_tcc(_idx, setId.Text));
            ItemTableRow3.Cells.AddRange(_tcc(++_idx, setId.Text));
            ItemTableRow4.Cells.AddRange(_tcc(++_idx, setId.Text));
            ItemTableRow5.Cells.AddRange(_tcc(++_idx, setId.Text));
            ItemTableRow6.Cells.AddRange(_tcc(++_idx, setId.Text));
 
            ItemTable.Rows.Add(ItemTableRow1);
            ItemTable.Rows.Add(ItemTableRow2);
            ItemTable.Rows.Add(ItemTableRow3);
            ItemTable.Rows.Add(ItemTableRow4);
            ItemTable.Rows.Add(ItemTableRow5);
            ItemTable.Rows.Add(ItemTableRow6);
        }
 
        private TableCell[] _tcc(int idx, string setId)
        {
            var tcc = new TableCell[12];
            var rtbDisplayMsg = new RadTextBox();
            var rtbNumber = new RadNumericTextBox();
            var rtbValue = new RadNumericTextBox();
            var cbgng = new RadButton();
            var cbEnabled = new RadButton();
 
            cbgng.ButtonType = RadButtonType.ToggleButton;
            cbgng.ToggleType = ButtonToggleType.CheckBox;
            cbgng.AutoPostBack = false;
            cbEnabled.ButtonType = RadButtonType.ToggleButton;
            cbEnabled.ToggleType = ButtonToggleType.CheckBox;
            cbEnabled.AutoPostBack = false;
 
// This is where I setup my controls IDs according to the setId value coming from my DB
            rtbValue.ID = "rtbValue_" + setId + "_" + idx;
            rtbNumber.ID = "rtbNumber_" + setId + "_" + idx;
            rtbDisplayMsg.ID = "rtbDisplayMsg_" + setId + "_" + idx;
            cbgng.ID = "cbgng_" + setId + "_" + idx;
            cbEnabled.ID = "cbEnabled_" + setId + "_" + idx;
 
            var rtbDisplayMsg1 = new RadTextBox();
            var rtbNumber1 = new RadNumericTextBox();
            var rtbValue1 = new RadNumericTextBox();
            var cbgng1 = new RadButton();
            var cbEnabled1 = new RadButton();
 
            cbgng1.ButtonType = RadButtonType.ToggleButton;
            cbgng1.ToggleType = ButtonToggleType.CheckBox;
            cbgng1.AutoPostBack = false;
            cbEnabled1.ButtonType = RadButtonType.ToggleButton;
            cbEnabled1.ToggleType = ButtonToggleType.CheckBox;
            cbEnabled1.AutoPostBack = false;
 
            rtbValue1.ID = "rtbValue_" + setId + "_" + (idx + 5);
            rtbNumber1.ID = "rtbNumber_" + setId + "_" + (idx + 5);
            rtbDisplayMsg1.ID = "rtbDisplayMsg_" + setId + "_" + (idx + 5);
            cbgng1.ID = "cbgng_" + setId + "_" + (idx + 5);
            cbEnabled1.ID = "cbEnabled_" + setId + "_" + (idx + 5);
 
// I then add my controsl to my TableCells
            for (var cnt = 0; cnt < tcc.Length; cnt++)
                tcc[cnt] = new TableCell();
            tcc[0].Controls.Add(new Label() { Text = idx + "." });
            tcc[1].Controls.Add(rtbValue);
            tcc[2].Controls.Add(rtbDisplayMsg);
            tcc[3].Controls.Add(rtbNumber);
            tcc[4].Controls.Add(cbgng);
            tcc[5].Controls.Add(cbEnabled);
            tcc[6].Controls.Add(new Label() { Text = (idx + 5) + "." });
            tcc[7].Controls.Add(rtbValue1);
            tcc[8].Controls.Add(rtbDisplayMsg1);
            tcc[9].Controls.Add(rtbNumber1);
            tcc[10].Controls.Add(cbgng1);
            tcc[11].Controls.Add(cbEnabled1);
 
            return tcc;
        }
 
        #endregion
    }
What Am I doing wrong ? I wish I could just set up my templates in aspx and bind their values to it but I need 2 datasources. One for my ListItems and a second one for the controls contained in my items (see image attached). Idea anyone ? Thanks

3 Answers, 1 is accepted

Sort by
0
Christophe
Top achievements
Rank 1
answered on 07 Feb 2013, 12:02 AM
I finally manually found it browsing my objects in debug mode (see attached picture). It's hiding deeeeep inside my item object but still it exists and the FindControl() method doesn't get it ???? WHYYYYY !!??
0
Christophe
Top achievements
Rank 1
answered on 07 Feb 2013, 01:16 AM
No one ?? :(
0
Christophe
Top achievements
Rank 1
answered on 07 Feb 2013, 11:21 PM
Alright. I had to come up with the following extension method for my controls:

/// <summary>
/// This method search recursively within the host control for the targeted control ID
/// </summary>
/// <param name="root"></param>
/// <param name="ControlId">The ID of the control to look for</param>
/// <returns>Returns null if nothing was found</returns>
public static Control FindControlRecursive(this Control root, string ControlId)
{
    if (root.ID == ControlId)
        return root;
 
    foreach (Control ctrl in root.Controls)
    {
        Control targetCtrl = ctrl.FindControlRecursive(ControlId);
        if (targetCtrl != null)
            return targetCtrl;
    }
    return null;
}

Now I can do the following :
protected void rlvConfigGng_ItemDataBound(object sender, Telerik.Web.UI.RadListViewItemEventArgs e)
{
    if (e.Item is RadListViewDataItem)
    {
        var test = item.FindControlRecursive("TheIDofMyControl") as RadNumericTextBox;
    }
}

Obviously, this works with any Controls.
Would be good to have someone@Telerik opinion on this matter. Anyway, it's fixed and hope this will help if someone is facing the same issue.

Cheers
Tags
ListView
Asked by
Christophe
Top achievements
Rank 1
Answers by
Christophe
Top achievements
Rank 1
Share this question
or