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

[Solved] RadListBox behaving strangely embedded in server control

2 Answers 167 Views
ListBox
This is a migrated thread and some comments may be shown as answers.
Lasse Schioettz
Top achievements
Rank 1
Lasse Schioettz asked on 17 Dec 2009, 04:39 PM
Hi,

I like the functionality provided by a pair of listboxes set up as a source and target. What I don't like is to have to declare them separately, databind and ultimately looping through the items in the target listbox to get a list of selected values. I have therefore tried to wrap all of this in a server control. The constructor takes a name, an IEnumerable list as datasource and the names of the text and value properties. It also provides a "GetSelectedItems()" method that returns the selected values as a CSV string (which is what I need). When I instantiate this server control it looks and appears to function as expected.

Now to the problem: when the page posts back the target listbox is empty. The items added clientside disappears. Clearly, this is not supposed to happen, so I must have done something wrong. I enclose the code for my server control below. Any pointers will be greatly appreciated.

Sincerely,
Lasse

namespace Company.PDC.WebParts  
{  
    using System;  
    using System.Collections;  
    using System.ComponentModel;  
    using System.Web.UI;  
    using System.Web.UI.WebControls;  
    using Telerik.Web.UI;  
 
    [ToolboxData("<{0}:SearchListBox runat=server></{0}:SearchListBox>")]  
    public class SearchListBox : WebControl  
    {
        #region Attributes  
 
        private Table listBoxTable;  
        private RadListBox source;  
        private RadListBox target;  
        private string separator = ";";  
        private string anyElement = "- Any -";  
        private int height = 200;  
        private int width = 200;
        #endregion  
 
        #region Constructors  
 
        public SearchListBox(string controlName, IEnumerable dataSource, string textField, string valueField)  
        {  
            this.ID = controlName;  
            this.source = new RadListBox();  
            this.target = new RadListBox();  
            this.EnableViewState = true;  
            this.source.EnableViewState = true;  
            this.target.EnableViewState = true;  
            this.LoadData(dataSource, textField, valueField);  
        }
        #endregion  
 
        #region Properties  
 
        public string Separator  
        {  
            get 
            {  
                return this.separator;  
            }  
 
            set 
            {  
                this.separator = value;  
            }  
        }  
 
        public string AnyElement  
        {  
            get 
            {  
                return this.anyElement;  
            }  
 
            set 
            {  
                this.anyElement = value;  
            }  
        }  
 
        public new int Height  
        {  
            get 
            {  
                return this.height;  
            }  
 
            set 
            {  
                this.height = value;  
            }  
        }  
 
        public new int Width  
        {  
            get 
            {  
                return this.width;  
            }  
 
            set 
            {  
                this.width = value;  
            }  
        }  
 
        public bool IsEmpty  
        {  
            get 
            {  
                return this.target.Items.Count.Equals(0);  
            }  
        }
        #endregion  
 
        #region Public Methods  
 
        /// <summary>  
        /// Retrieves a list of selected items.  
        /// </summary>  
        /// <returns>  
        /// A separator delimited string of selected values.  
        /// </returns>  
        public string GetSelectedValues()  
        {  
            string values = string.Empty;  
            foreach (RadListBoxItem item in this.target.Items)  
            {  
                values += item.Value + this.Separator;  
            }  
 
            return values;  
        }
        #endregion  
 
        #region Override Methods  
 
        protected override void CreateChildControls()  
        {  
            base.CreateChildControls();  
 
            this.DefineListBoxes();  
            this.Controls.Add(this.listBoxTable);  
        }  
 
        protected override void RenderContents(HtmlTextWriter output)  
        {  
            this.source.RenderControl(output);  
            this.target.RenderControl(output);  
        }
        #endregion  
 
        #region Private Support Methods  
 
        private void LoadData(IEnumerable dataSource, string textField, string valueField)  
        {  
            this.source.DataSource = dataSource;  
            this.source.DataTextField = textField;  
            this.source.DataValueField = valueField;  
            this.source.DataBind();  
        }  
 
        private void DefineListBoxes()  
        {  
            this.source.Height = this.Height;  
            this.source.Width = this.Width;  
            this.target.Height = this.Height;  
            this.target.Width = this.Width - 35;  
            this.target.ID = this.ID + "target";  
            this.source.ID = this.ID + "source";  
            this.source.AllowTransfer = true;  
            this.source.AllowTransferDuplicates = false;  
            this.source.TransferMode = ListBoxTransferMode.Copy;  
            this.source.TransferToID = this.target.ID;  
 
            this.listBoxTable = new Table();  
            TableRow row = new TableRow();  
            TableCell cellSource = new TableCell();  
            TableCell cellTarget = new TableCell();  
            cellSource.Controls.Add(this.source);  
            cellTarget.Controls.Add(this.target);  
            row.Cells.Add(cellSource);  
            row.Cells.Add(cellTarget);  
            this.listBoxTable.Rows.Add(row);  
        }
        #endregion  
    }  
}  
 

2 Answers, 1 is accepted

Sort by
0
Simon
Telerik team
answered on 19 Dec 2009, 12:28 PM
Hello Lasse Schioettz,

Thank you for providing your code.

The target ListBox looses its state because it is added to the Page Control Tree in the CreateChildControls method, which in your case fires in the PreRender phase. So both ListBoxes miss to load their PostData and they do not reflect they client-side changes.

In order to resolve this I suggest you create the ListBoxes in the OnInit override of the parent control:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
 
    this.DefineListBoxes(); 
    this.Controls.Add(this.listBoxTable);
}

Greetings,
Simon
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Lasse Schioettz
Top achievements
Rank 1
answered on 21 Dec 2009, 07:29 AM
Hi Simon,

Thanks for your suggestion. I just tried it out and alas, it makes no difference - still no values in the target listbox after or during postback.

UPDATE:
If I move the instantiation of the server control on the consuming page to the override of CreateChildControls it works fine. So OnInit in teh server control and CreateChildControls in the consuming page is the combo that works. Thanks again for your directions.

Sincerely,
Lasse
Tags
ListBox
Asked by
Lasse Schioettz
Top achievements
Rank 1
Answers by
Simon
Telerik team
Lasse Schioettz
Top achievements
Rank 1
Share this question
or