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

[Solved] RadComboBox with RadTreeView Server Control Viewstate

16 Answers 393 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
ctca
Top achievements
Rank 1
ctca asked on 10 Oct 2009, 06:45 PM
I am trying to build this exact same example using a custom server control. Everything seems to be working fairly well other than being able to get the value back after submit from the combo box.

Here is the code for the server control...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using LO.Persistence; 
using LO.Persistence.Services; 
using Telerik.Web.UI; 
using LO.Extensions; 
using LO.Web.ComponentModel; 
 
namespace LO.Web.UI.Controls 
    [BindingProperty("SelectedValue")] 
    public class OComboSelector : CompositeControl, IOControl 
    { 
        #region Properties 
         
        private RadComboBox _comboBox; 
        private RadTreeView _treeView; 
        private OLabel _label; 
        private bool _isPropertyChanged; 
        private bool _isSelectedValueChanged; 
 
        public T GetSelectedValue<T>() where T : IEntity, new() 
        { 
            if (_comboBox == null
            { 
                return ConvertExtension.ConvertTo<T>(string.Empty); 
            } 
            return ConvertExtension.ConvertTo<T>(_comboBox.SelectedValue); 
        } 
        public string SelectedText 
        { 
            get { return ViewState.GetValue("SelectedText", String.Empty); } 
            set 
            { 
                EnsureChildControls(); 
                RadTreeNode node = GetNodeByText(_treeView.Nodes, value); 
                if (node != null
                { 
                    node.Selected = true
                    _comboBox.Items[0].Text = value; 
                    _comboBox.Items[0].Selected = true
                    _comboBox.Text = value; 
                    _comboBox.SelectedValue = node.Value; 
                    ViewState["SelectedValue"] = node.Value; 
                    ViewState["SelectedText"] = value; 
                    OnSelectedValueChanged(new RadTreeNodeEventArgs(node)); 
                } 
            } 
        } 
        public string SelectedValue 
        { 
            get { return ViewState.GetValue("SelectedValue", String.Empty); } 
            set 
            { 
                EnsureChildControls(); 
                RadTreeNode node = GetNodeByValue(_treeView.Nodes, value); 
                if (node != null
                { 
                    node.Selected = true
                    _comboBox.Items[0].Text = node.Text; 
                    _comboBox.Items[0].Selected = true
                    _comboBox.Text = node.Text; 
                    _comboBox.SelectedValue = node.Value; 
                    ViewState["SelectedValue"] = value; 
                    ViewState["SelectedText"] = node.Text; 
                    OnSelectedValueChanged(new RadTreeNodeEventArgs(node)); 
                } 
            } 
        } 
        public override void DataBind() 
        { 
            _treeView.DataBind(); 
            base.DataBind(); 
        } 
        public String EmptyMessage 
        { 
            get { EnsureChildControls(); return _comboBox.EmptyMessage; } 
            set { EnsureChildControls(); _comboBox.EmptyMessage = value; } 
        } 
        public String DataFieldID 
        { 
            get { EnsureChildControls(); return _treeView.DataFieldID; } 
            set { EnsureChildControls(); _treeView.DataFieldID = value; } 
        } 
        public String DataTextField 
        { 
            get { EnsureChildControls(); return _treeView.DataTextField; } 
            set { EnsureChildControls(); _treeView.DataTextField = value; } 
        } 
        public String DataValueField 
        { 
            get { EnsureChildControls(); return _treeView.DataValueField; } 
            set { EnsureChildControls(); _treeView.DataValueField = value; } 
        } 
        public String DataFieldParentID 
        { 
            get { EnsureChildControls(); return _treeView.DataFieldParentID; } 
            set { EnsureChildControls(); _treeView.DataFieldParentID = value; } 
        } 
        public bool AutoPostBack 
        { 
            get { EnsureChildControls(); return _comboBox.AutoPostBack; } 
            set {  
                EnsureChildControls();  
                _comboBox.AutoPostBack = value; 
                if (value == true
                { 
                    _treeView.NodeClick += _treeView_NodeClick; 
                } 
            } 
        } 
        public object DataSource 
        { 
            get { EnsureChildControls(); return _treeView.DataSource; } 
            set { EnsureChildControls(); _treeView.DataSource = value; } 
        } 
        public bool Required 
        { 
            get { return ViewState.GetValue("Required"false); } 
            set { ViewState["Required"] = value; } 
        } 
        public bool ReadOnly 
        { 
            get { return ViewState.GetValue("ReadOnly"false); } 
            set { ViewState["ReadOnly"] = value; } 
        } 
        public string LabelID 
        { 
            get { return ViewState.GetValue("LabelID"string.Empty); } 
            set { ViewState["LabelID"] = value; } 
        } 
        public OLabel Label 
        { 
            get 
            { 
                if (_label == null
                { 
                    _label = ControlUtil.FindLabel(this); 
                } 
                return _label; 
            } 
        } 
        public string Property 
        { 
            get { return ViewState.GetValue("Property"string.Empty); } 
            set { ViewState["Property"] = value; } 
        } 
 
        public bool IsPropertyChanged 
        { 
            get { return _isPropertyChanged; } 
        } 
        public bool IsSelectedValueChanged 
        { 
            get { return _isSelectedValueChanged; } 
        } 
        public IEntity BindingSource 
        { 
            get
            set
        } 
        public string SecurityKey 
        { 
            get { return ViewState.GetValue("SecurityKey"string.Empty); } 
            set { ViewState["SecurityKey"] = value; } 
        } 
        #endregion 
        #region Events 
 
        public event EventHandler<RadTreeNodeEventArgs> SelectedValueChanged; 
        public void OnSelectedValueChanged(RadTreeNodeEventArgs e) 
        { 
            EventHandler<RadTreeNodeEventArgs> handler = SelectedValueChanged; 
            if (handler != null) handler(this, e); 
 
            _isSelectedValueChanged = true
        } 
        public event EventHandler<PropertyChangedEventArgs> PropertyChanged;      
        private void OnPropertyChanged(PropertyChangedEventArgs e) 
        { 
            EventHandler<PropertyChangedEventArgs> handler = PropertyChanged; 
            if (handler != null) handler(this, e); 
 
            _isPropertyChanged = true
        } 
        #endregion 
        #region Methods 
         
        private RadTreeNode GetNodeByValue(RadTreeNodeCollection nodes, string value) 
        { 
            EnsureChildControls(); 
            RadTreeNode returnNode = null
            foreach (RadTreeNode node in nodes) 
            { 
                if (node.Value == value) 
                { 
                    returnNode = node; 
                    break
                } 
                if (node.Nodes.Count > 0) 
                { 
                    node.Expanded = true
                    returnNode = GetNodeByValue(node.Nodes, value); 
                } 
            } 
            return returnNode; 
        } 
        private RadTreeNode GetNodeByText(RadTreeNodeCollection nodes, string value) 
        { 
            EnsureChildControls(); 
            RadTreeNode returnNode = null
            foreach (RadTreeNode node in nodes) 
            { 
                if (node.Text == value) 
                { 
                    returnNode = node; 
                    break
                } 
                if (node.Nodes.Count > 0) 
                { 
                    node.Expanded = true
                    returnNode = GetNodeByText(node.Nodes, value); 
                } 
            } 
            return returnNode; 
        } 
        protected override void CreateChildControls() 
        { 
            _comboBox = new RadComboBox { ID = "InternalComboBox", Width = Width }; 
            _treeView = new RadTreeView { ID = "TreeView" }; 
             
            RadComboBoxItem container = new RadComboBoxItem(); 
            HtmlGenericControl panel = new HtmlGenericControl("div"); 
 
            Controls.Add(_comboBox); 
            _comboBox.Items.Add(container); 
            container.Controls.Add(panel); 
            panel.Controls.Add(_treeView); 
             
            
            panel.ID = "itemTemplate"
            _comboBox.OnClientDropDownOpened = "_onClientDropDownOpenedHandler"
            _treeView.OnClientNodeClicking = "_nodeClicking"
 
            base.CreateChildControls(); 
        } 
        protected override void Render(HtmlTextWriter writer) 
        { 
 
            base.Render(writer); 
        } 
        private void _treeView_NodeClick(object sender, RadTreeNodeEventArgs e) 
        { 
            SelectedValue = ((RadTreeView)sender).SelectedNode.Value; 
            OnSelectedValueChanged(e); 
        } 
        public void Bind() 
        { 
            DataBindingUtil.Bind(this"SelectedValue"); 
        } 
        public void Unbind() 
        { 
            DataBindingUtil.Unbind(this"SelectedValue"); 
        } 
        protected override void OnInit(EventArgs e) 
        { 
            base.OnInit(e); 
        }       
        #endregion   
    } 

Here is how I'm putting it on a page...

<lo:OComboSelector runat="server" ID="testing" /> 

This is the javascript on the page... (and I know for sure that all the control ID's are correct and getting the control it should)

<script type="text/javascript"
 
    function _nodeClicking(sender, args) { 
        var comboBox = $find("ctl00_ctl00_PageContentPlaceHolder_LeftContentPlaceHolder_eventForm_testing_InternalComboBox"); 
        var node = args.get_node(); 
        comboBox.set_text(node.get_text()); 
        comboBox.trackChanges(); 
        comboBox.get_items().getItem(0).set_value(node.get_value()); 
        comboBox.commitChanges(); 
        comboBox.hideDropDown(); 
    } 
 
    function _stopPropagation(e) { 
        if (!e) { 
            e = window.event; 
        } 
        e.cancelBubble = true
    } 
 
    function _onClientDropDownOpenedHandler(sender, eventArgs) { 
        var tree = sender.get_items().getItem(0).findControl("ctl00_ctl00_PageContentPlaceHolder_LeftContentPlaceHolder_eventForm_testing_InternalComboBox_i0_TreeView"); 
        var selectedNode = tree.get_selectedNode(); 
        if (selectedNode) { 
            selectedNode.scrollIntoView(); 
        } 
    } 
    var templatedd = document.getElementById("ctl00_ctl00_PageContentPlaceHolder_LeftContentPlaceHolder_eventForm_testing_InternalComboBox_i0_itemTemplate"); 
    templatedd.onclick = _stopPropagation; 
</script> 


This is my aspx page's code behind....

        protected void Page_Load(object sender, EventArgs e)  
        { 
            if (!IsPostBack) 
            { 
                testing.DataSource = toolTypes; 
                testing.DataTextField = "Name"
                testing.DataValueField = "ToolTypeID"
                testing.DataBind(); 
                testing.SelectedValue = "29"
            } 
            testing.EmptyMessage = "Please select something"
            Response.Write(testing.SelectedText); 
        } 
 

On first page load, I do get the selected text to response write correctly, but when I select something different from the treeview and click the submit button, I don't get the different value, I just get the same one. I'm thinking this has something to do with the javascript block below. If I put "_treeView.NodeClick += _treeView_NodeClick;" in the CreateChildControls() function, it works, but it causes postback every time the node is selected, and it's one postback behind with the correct value...Any ideas?
comboBox.trackChanges();
comboBox.get_items().getItem(0).set_value(node.get_value());
comboBox.commitChanges();

16 Answers, 1 is accepted

Sort by
0
ctca
Top achievements
Rank 1
answered on 12 Oct 2009, 01:00 PM
Shameless bump.

Does anyone have any idea what I'm missing here?
0
Yana
Telerik team
answered on 16 Oct 2009, 07:00 AM
Hello Chad,

I'm so sorry for the delayed reply.

You should  subscribe to OnClientLoad event of RadComboBox and set its text in its handler like this:

function clientLoad(sender) {
    var tree = sender.get_items().getItem(0).findControl("ctl00_ctl00_PageContentPlaceHolder_LeftContentPlaceHolder_eventForm_testing_InternalComboBox_i0_TreeView");
    sender.set_text(tree.get_selectedNode().get_text());
}


All the best,
Yana
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
ctca
Top achievements
Rank 1
answered on 16 Oct 2009, 12:19 PM
Thanks for the response, Yana.

The solution you gave only helps me on the client side before postback. The problem I am having is that on postback, I don't have the value I need on the server side to do anything with.

I'm thinking that my problem has to do with the fact that my RadComboBox and RadTreeView are both private objects in my custom server control class and the view state doesn't have access to them or something. Considering, the combo box selected index technically never changes, I assumed that this javascript would be what I needed to save the value to viewstate...

  comboBox.trackChanges();  
  comboBox.get_items().getItem(0).set_value(node.get_value());  
  comboBox.commitChanges();  

I'm wondering if this javascript can't save the control's value to viewstate because it can't access the control directly considering it's private.

Any ideas?
0
Yana
Telerik team
answered on 22 Oct 2009, 07:49 AM
Hi Chad,

I've prepared a test project based on your code to demonstrate how to fix these issues. Basically the controls are added in  OnInit event handler in order to get the Text and Value of the RadComboBox item.  Please download the attached file and give it a try.

Greetings,
Yana
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
nagendra d
Top achievements
Rank 1
answered on 05 Nov 2009, 02:41 PM
Hi,

  i was a new user to telerix rad controls. I need a rad tree view to be displayed in the rad combobox. i tried for the example solution given by you. Its working fine , but i was getting issues when I go and select the item for second time.

  Issue Will replicate by the following steps
  
  1. Run the aaplication and expand the combo box and select one tree node.[ex: treenode3]
  2. Now again press on the expand button, now I was getting null at
       var tree = sender.get_items().getItem(0).findControl("InternalComboBox_i0_TreeView");
       // tree object will be null
   3. Even i skip the method i was not getting the values at the combobox, just it is showing treenode3 value only.

  Can you please send me the solution Or send me the issue fixed code.
 
0
Yana
Telerik team
answered on 10 Nov 2009, 03:21 PM
Hi Nagendra,

You are right about this issue. You can fix it like this:

1. remove comboBox.get_items().getItem(0).set_text(node.get_text());line from the following method:

function _nodeClicking(sender, args) {
            var comboBox = $find("InternalComboBox");
            var node = args.get_node();
             
            comboBox.trackChanges();
            comboBox.set_text(node.get_text());
            //comboBox.get_items().getItem(0).set_text(node.get_text());
            comboBox.get_items().getItem(0).set_value(node.get_value());
            comboBox.commitChanges();
            comboBox.hideDropDown();
        }

2.  add OnClientLoad event for the combobox:

_comboBox.OnClientDropDownOpened = "_onClientDropDownOpenedHandler";
_comboBox.OnClientLoad = "_onClientLoad";

3. and  the method event handler:

function _onClientLoad(combo) {
            var tree = combo.get_items().getItem(0).findControl("InternalComboBox_i0_TreeView");
            var selectedNode = tree.get_selectedNode();
            if (selectedNode) {
                combo.set_text(selectedNode.get_text());
            }
        }

This fixes the issue at our side.

Best wishes,
Yana
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
nagendra d
Top achievements
Rank 1
answered on 16 Nov 2009, 12:21 PM
Hi,

  By using the above code i was able to solve the issue, but Now I got a new issue.
 I had added one more column as parent column and tried to fill the combo with the parent child relation, but It was loading normally
 here is the code follows..

 

 

DataTable toolTypes = new DataTable();

 

toolTypes.Columns.Add(

 

"Name");

 

toolTypes.Columns.Add(

 

"ToolTypeID");

 

toolTypes.Columns.Add(

 

"ParentToolTypeID");

 

toolTypes.Rows.Add(

 

new String[] {"tool1", "1", "1" });

 

toolTypes.Rows.Add(

 

new String[] { "tool2", "2", "1" });

 

toolTypes.Rows.Add(

 

new String[] { "tool3", "3", "2" });

 

toolTypes.Rows.Add(

 

new String[] { "tool4", "4", "1" });

 

toolTypes.Rows.Add(

 

new String[] { "tool5", "5", "3" });

 

toolTypes.Rows.Add(

 

new String[] { "tool6", "6", "4" });

 

toolTypes.Rows.Add(

 

new String[] { "tool7", "7", "2" });

 

toolTypes.Rows.Add(

 

new String[] { "tool8", "8", "3" });

 

testing.DataSource = toolTypes;

testing.DataTextField =

"Name";

 

testing.DataValueField =

 

"ToolTypeID";

 

testing.DataFieldParentID =

 

"ParentToolTypeID";

 

testing.DataBind();

 

 

0
Simon
Telerik team
answered on 18 Nov 2009, 02:03 PM
Hello nagendra d,

You need to specify a root Node in the underlying data source by setting the ParentToolTipID of a row to 0.

Please see this help topic for more information about the subject.

Best wishes,
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
nagendra d
Top achievements
Rank 1
answered on 24 Nov 2009, 08:46 AM
Hi,
   Even I kept the 0 over there, I was not able to achive the parent child functionality.

Thanks,
Nagendra
0
Simon
Telerik team
answered on 27 Nov 2009, 04:08 PM
Hello nagendra d,

Indeed that is the case.

The default value in your case is null as you are binding to a DataTable.

Please use null instead of 0 and excuse me for misguiding you. Zero (0) is used when binding to IEnumerable or ICollection.

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
nagendra d
Top achievements
Rank 1
answered on 28 Nov 2009, 12:43 PM
Still I was not getting the parent child functionality
And I changed using the below code also, still I was not able to get it.
If you have any example project please provide to me

List

<test> oList = new List<test>

 

{

 

new test() { PID="0", ID="1",text="first"},

 

 

new test() { PID="1", ID="2",text="first1"}

 

};

testing.DataTextField =

"text";

 

testing.DataValueField =

"ID";

 

testing.DataFieldParentID =

"PID";

 

testing.DataSource = oList;

 

testing.DataBind();

Thanks,
Nagendra

0
Simon
Telerik team
answered on 30 Nov 2009, 11:50 AM
Hello nagendra d,

In this case you also need to use null for root Nodes.

So, null denotes root Nodes when the Field/ParentField fields are of reference type and 0 - when they are of value type.

Please see the sample I attached to this post.

Kind regards,
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
nagendra d
Top achievements
Rank 1
answered on 01 Dec 2009, 02:57 AM
I was not asking about the treeview control.
I was asking about the treeview in the combox.
can you please send me an example to fill the combo box with data with the tree view structure
I was able to fill the data in the combo as tree view, but I was not able to show the parent child relation over there.
I had attached the example project, please check it.
0
Simon
Telerik team
answered on 01 Dec 2009, 08:37 AM
Hello nagendra d,

You should bind the RadTreeView that is in the RadComboBox to a data source with properly denoted child-parent relationship as the ones I showed you in my sample.

Since project attachments are not allowed in the forums, can you please paste here the code of the ComboBox (markup and code-behind)?

Best wishes,
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
nagendra d
Top achievements
Rank 1
answered on 01 Dec 2009, 08:49 AM

This is the code taken from the project which you had attached in this ticket. And I had modified the code also

Default.aspx
--------------------
<

script type="text/javascript">

 

 

function _nodeClicking(sender, args) {

 

 

 

var comboBox = $find("InternalComboBox");

 

 

var node = args.get_node();

 

 

comboBox.trackChanges();

comboBox.set_text(node.get_text());

 

//comboBox.get_items().getItem(0).set_text(node.get_text());

 

comboBox.get_items().getItem(0).set_value(node.get_value());

comboBox.commitChanges();

comboBox.hideDropDown();

}

 

function _stopPropagation(e) {

 

 

 

if (!e) {

 

e = window.event;

}

e.cancelBubble =

true;

 

}

 

function _onClientDropDownOpenedHandler(sender, eventArgs) {

 

 

 

var tree = sender.get_items().getItem(0).findControl("InternalComboBox_i0_TreeView_ClientState");

 

 

if(tree != null)

 

{

 

var selectedNode = tree.get_selectedNode();

 

 

if (selectedNode) {

 

selectedNode.scrollIntoView();

}

}

}

 

function _onClientLoad(combo) {

 

 

var tree = combo.get_items().getItem(0).findControl("InternalComboBox_i0_TreeView");

 

 

var selectedNode = tree.get_selectedNode();

 

 

if (selectedNode) {

 

combo.set_text(selectedNode.get_text());

}

}

 

var templatedd = document.getElementById("InternalComboBox_i0_itemTemplate");

 

templatedd.onclick = _stopPropagation;

 

var testcombo = document.getElementById("testing");

 

testcombo.OnClientDropDownOpened =

"_onClientDropDownOpenedHandler";

 

testcombo.OnClientLoad =

"_onClientLoad";

 

 

</

script> 

 

 

<form id="form1" runat="server">

 

 

 

 

<asp:ScriptManager ID="ScriptManager1" runat="server" />

 

 

 

 

<div>

 

 

 

 

<lo:TreeComboBox runat="server" ID="testing" />

 

 

</div>

Default.asp.cs
----------------------

 

protected

void Page_Load(object sender, EventArgs e)

 

{

 

 

DataTable toolTypes = new DataTable();

 

toolTypes.Columns.Add(

"Name");

 

toolTypes.Columns.Add(

"ToolTypeID");

 

toolTypes.Columns.Add(

"ParentToolTypeID");

 

toolTypes.Rows.Add(

new String[] {"tool1", "1", null });

 

toolTypes.Rows.Add(

new String[] { "tool2", "2", null });

 

toolTypes.Rows.Add(

new String[] { "tool3", "3", "2" });

 

toolTypes.Rows.Add(

new String[] { "tool4", "4", "1" });

 

toolTypes.Rows.Add(

new String[] { "tool5", "5", "3" });

 

toolTypes.Rows.Add(

new String[] { "tool6", "6", "4" });

 

toolTypes.Rows.Add(

new String[] { "tool7", "7", "2" });

 

toolTypes.Rows.Add(

new String[] { "tool8", "8", "3" });

 

 

List<test> oList = new List<test>

 

{

 

new test() { PID="0", ID="1",text="first"},

 

 

new test() { PID="1", ID="2",text="first1"}

 

};

testing.DataTextField =

"text";

 

testing.DataValueField =

"ID";

 

testing.DataFieldParentID =

"PID";

 

testing.DataSource = oList;

 

testing.DataBind();

 

// testing.SelectedValue = "4";

 

 

 

 

}

0
Simon
Telerik team
answered on 01 Dec 2009, 03:47 PM
Hello nagendra d,

Please open a support ticket and send us your project there.

We will review it and will modify it to make it work.

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.
Tags
ComboBox
Asked by
ctca
Top achievements
Rank 1
Answers by
ctca
Top achievements
Rank 1
Yana
Telerik team
nagendra d
Top achievements
Rank 1
Simon
Telerik team
Share this question
or