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

New Behavior on RadComboBox on Popup EditForm (Q32011)

2 Answers 137 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Chris Breisch
Top achievements
Rank 1
Chris Breisch asked on 16 Feb 2012, 03:37 PM
This appears to be a bug to me. Maybe it's not, but it's certainly changed behavior from previous releases.

If you have a RadComboBox on a Popup EditForm as part of a RadGrid, the OnLoad event seems cause problems.

Specifically, if I load the combo on the OnLoad event, the SelectedItem/SelectedIndex/SelectedValue properties are not set when the RadGrid's UpdateCommand event is fired. In addition, the RadComboBoxSelectedIndexChangedEventArgs.Value property is not set when the RadComboBox's SelectedIndexChanged event is fired.

This is a change from previous behavior. It doesn't appear to matter whether or not I set EnableLoadOnDemand or MarkFirstMatch.

The sample code below demonstrates the problem. The Popup has two RadComboBoxes, each displaying some test data. The first combo box is loaded programatically during processing of the RadGrid's ItemDataBound event, when IsInEditMode is true. The second combo box is loaded when it's OnLoad event fires. In addition, there are associated Label controls for each RadComboBox, which are set to the selected Value when the SelectedIndexChanged event fires. Finally, the RadGrid displays both of the saved items.

Forgive the length of the sample code. I did try to prune it as much as possible.

EditFormComboWithOnLoad.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EditFormComboWithOnLoad.aspx.cs"
    Inherits="Web.Test.EditFormComboWithOnLoad" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <telerik:RadScriptManager ID="radScriptManager" runat="server" EnablePartialRendering="true">
            <Scripts>
            </Scripts>
        </telerik:RadScriptManager>
        <telerik:RadGrid ID="radGrid" runat="server" AllowPaging="True" AllowSorting="True"
            AutoGenerateColumns="False" GridLines="None" OnNeedDataSource="radGrid_NeedDataSource"
            OnItemDataBound="radGrid_ItemDataBound" OnUpdateCommand="radGrid_UpdateCommand"
            OnItemCommand="radGrid_ItemCommand">
            <MasterTableView CommandItemDisplay="Top" AllowMultiColumnSorting="True" EditMode="PopUp"
                DataKeyNames="AddressId">
                <RowIndicatorColumn>
                    <HeaderStyle Width="20px"></HeaderStyle>
                </RowIndicatorColumn>
                <ExpandCollapseColumn>
                    <HeaderStyle Width="20px"></HeaderStyle>
                </ExpandCollapseColumn>
                <Columns>
                    <telerik:GridTemplateColumn UniqueName="country1" AllowFiltering="False"
                        HeaderText="Address 1">
                        <ItemTemplate>
                            <%# this.GetCountry1( Container.DataItem) %>
                        </ItemTemplate>
                    </telerik:GridTemplateColumn>
                    <telerik:GridTemplateColumn UniqueName="country2" AllowFiltering="False"
                        HeaderText="Address 2">
                        <ItemTemplate>
                            <%# this.GetCountry2( Container.DataItem) %>
                        </ItemTemplate>
                    </telerik:GridTemplateColumn>
                    <telerik:GridTemplateColumn UniqueName="editColumn" AllowFiltering="False">
                        <ItemTemplate>
                            <asp:ImageButton runat="server" ID="ibEdit" SkinID="IconEdit" CommandName="Edit" />
                        </ItemTemplate>
                        <HeaderStyle Width="16px" />
                        <ItemStyle HorizontalAlign="Center" />
                    </telerik:GridTemplateColumn>
                </Columns>
                <EditFormSettings EditFormType="Template">
                    <EditColumn UniqueName="EditCommandColumn">
                    </EditColumn>
                    <PopUpSettings Modal="True" />
                    <FormTemplate>
                        <asp:Panel ID="Panel1" runat="server" DefaultButton="btnSave">
                            <fieldset style="margin: 5px; padding: 10px;">
                                <table>
                                    <tr>
                                        <td>
                                            <asp:Label ID="lblCountry1" runat="server" Text="Country 1:"></asp:Label>
                                        </td>
                                        <td>
                                            <telerik:RadComboBox ID="radCountryBox1" runat="server" EnableLoadOnDemand="False"
                                                MaxHeight="200px" AutoPostBack="true" ShowWhileLoading="false" MarkFirstMatch="true"
                                                Filter="StartsWith" OnSelectedIndexChanged="radCountryBox_SelectedIndexChanged">
                                            </telerik:RadComboBox>
                                        </td>
                                    </tr>
                                        <td>
                                            <asp:Label ID="label2" runat="server" Text="Selected Value:"></asp:Label>
                                        </td>
                                        <td>
                                            <asp:Label ID="lblSelectedValue1" runat="server"></asp:Label>
                                        </td>
                                    <tr>
                                    <tr>
                                        <td>
                                            <asp:Label ID="lblCountry2" runat="server" Text="Country 2:"></asp:Label>
                                        </td>
                                        <td>
                                            <telerik:RadComboBox ID="radCountryBox2" runat="server" EnableLoadOnDemand="False"
                                                MaxHeight="200px" AutoPostBack="true" ShowWhileLoading="false" MarkFirstMatch="true"
                                                OnLoad="CountryBox2_Load"
                                                Filter="StartsWith" OnSelectedIndexChanged="radCountryBox2_SelectedIndexChanged">
                                            </telerik:RadComboBox>
                                        </td>
                                    </tr>
                                        <td>
                                            <asp:Label ID="label3" runat="server" Text="Selected Value:"></asp:Label>
                                        </td>
                                        <td>
                                            <asp:Label ID="lblSelectedValue2" runat="server"></asp:Label>
                                        </td>
                                    <tr>
                                    </tr>
                                    </tr>
                                </table>
                            </fieldset>
                            <table width="100%" border="0" cellpadding="0" cellspacing="0" style="margin-left: 5px;">
                                <tr>
                                    <td align="center">
                                        <asp:Button runat="server" ID="btnSave" CommandName="Update" Text="Save" />   
                                        <asp:Button runat="server" ID="btnCancel" CommandName="Cancel" Text="Cancel" CausesValidation="false" />
                                    </td>
                                </tr>
                            </table>
                        </asp:Panel>
                    </FormTemplate>
                </EditFormSettings>
            </MasterTableView>
        </telerik:RadGrid>
    </div>
    </form>
</body>
</html>

EditFormComboWithOnLoad.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
 
namespace Web.Test
{
    public partial class EditFormComboWithOnLoad : System.Web.UI.Page
    {
        #region FakeDataClasses
        private class Address
        {
            public int PartyId { get; set; }
            public int AddressId { get; set; }
            public int? Country1Id { get; set; }
            public int? Country2Id { get; set; }
        }
 
        private class Country
        {
            public int CountryId { get; set; }
            public string Name { get; set; }
        }
 
        #endregion
 
        private List<Country> _countries1;
        private List<Country> _countries2;
        private static List<Address> _addresses;
 
        public EditFormComboWithOnLoad()
        {
            CreateDummyCountries();
            CreateDummyAddresses();
        }
 
        #region SetupFakeData
        private void CreateDummyCountries()
        {
            _countries1 = new List<Country>();
            _countries2 = new List<Country>();
 
            AddDummyCountriesToList(_countries1);
            AddDummyCountriesToList(_countries2);
        }
 
        private void AddDummyCountriesToList(List<Country> countries)
        {
            Country country1 = new Country();
            country1.CountryId = 1;
            country1.Name = "Country 1";
            countries.Add(country1);
 
            Country country2 = new Country();
            country2.CountryId = 2;
            country2.Name = "Country 2";
            countries.Add(country2);
 
            Country country3 = new Country();
            country3.CountryId = 3;
            country3.Name = "Country 3";
            countries.Add(country3);
 
            Country country4 = new Country();
            country4.CountryId = 4;
            country4.Name = "Country 4";
            countries.Add(country4);
        }
 
        private void CreateDummyAddresses()
        {
            if (_addresses == null)
            {
                _addresses = new List<Address>();
                Address pa = new Address();
 
                pa = new Address();
                pa.PartyId = 1;
                pa.AddressId = 1;
                pa.Country1Id = 1;
                pa.Country2Id = 2;
 
                _addresses.Add(pa);
            }
        }
        #endregion
 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
 
            }
        }
 
        int GetPartyId()
        {
            int partyId = 1;
            return partyId;
        }
 
        #region Grid Events
 
        protected void radGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            radGrid.DataSource =  _addresses;
        }
 
        protected void radGrid_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
        {
            try
            {
                int addressId = -1;
 
                if (e.Item.IsInEditMode && e.Item is GridEditFormItem)
                {
                    GridEditFormItem editedItem = (GridEditFormItem)e.Item;
                    // load CountryBox1 from code. Us OnLoad event to load CountryBox2
                    RadComboBox radCountryBox1 = ((RadComboBox)editedItem.FindControl("radCountryBox1"));
                    CountryBox_Load(radCountryBox1, null);
 
                    // We only want to bind the values for edit mode only
                    if (!(e.Item is GridEditFormInsertItem))
                    {
                        object primaryKey = editedItem.GetDataKeyValue("AddressId");
                        if (primaryKey != null)
                            Int32.TryParse(primaryKey.ToString(), out addressId);
 
                        Address address = null;
 
                        if (addressId > 0)
                            address = _addresses.Where(item => item.AddressId == addressId).FirstOrDefault();
 
                        if (address != null)
                        {
                            ((RadComboBox)editedItem.FindControl("radCountryBox1")).SelectedValue = address.Country1Id.ToString();
                            ((RadComboBox)editedItem.FindControl("radCountryBox2")).SelectedValue = address.Country2Id.ToString();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                e.Canceled = true;
            }
        }
 
        protected void radGrid_UpdateCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
        {
            try
            {
                int addressId = -1;
 
                Address address = null;
 
                GridEditFormItem editedItem = e.Item as GridEditFormItem;
 
                // Conditional logic depending upon if we are inserting or updating
                if (e.Item is GridEditFormInsertItem)
                {
                    address = new Address();
                    address.PartyId = GetPartyId();
                    address.AddressId = _addresses.Max(item => item.AddressId) + 1;
                }
                else
                {
                    object primaryKey = editedItem.GetDataKeyValue("AddressId");
                    if (primaryKey != null)
                        Int32.TryParse(primaryKey.ToString(), out addressId);
 
                    if (addressId > 0)
                        address = _addresses.Where(item => item.AddressId == addressId).FirstOrDefault();
                }
 
                if (address != null)
                {
                    address.Country1Id = TextUtility.TextToNullableInt(((RadComboBox)editedItem.FindControl("radCountryBox1")).SelectedValue.ToString());
                    address.Country1Id = (address.Country1Id == 0 ? null : address.Country1Id);
 
                    address.Country2Id = TextUtility.TextToNullableInt(((RadComboBox)editedItem.FindControl("radCountryBox2")).SelectedValue.ToString());
                    address.Country2Id = (address.Country2Id == 0 ? null : address.Country2Id);
 
                    if (e.Item is GridEditFormInsertItem)
                        _addresses.Add(address);
                }
                else
                {
                    throw new Exception("The record no longer exists.");
                }
            }
            catch (Exception ex)
            {
                e.Canceled = true;
            }
        }
 
        #endregion
 
        protected void CountryBox_Load(object sender, EventArgs e)
        {
            RadComboBox radBox = sender as RadComboBox;
            List<Country> data = _countries1;
            Country none = new Country();
            radBox.DataSource = data;
            radBox.DataTextField = "Name";
            radBox.DataValueField = "CountryId";
            radBox.EmptyMessage = "Select a Country";
            radBox.DataBind();
        }
 
        protected void CountryBox2_Load(object sender, EventArgs e)
        {
            RadComboBox radBox = sender as RadComboBox;
            List<Country> data = _countries2;
            Country none = new Country();
            radBox.DataSource = data;
            radBox.DataTextField = "Name";
            radBox.DataValueField = "CountryId";
            radBox.EmptyMessage = "Select a Country";
            radBox.DataBind();
        }
 
        protected void radCountryBox_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            int countryid;
            Int32.TryParse(e.Value, out countryid);
            Label lbl = (o as RadComboBox).Parent.FindControl("lblSelectedValue1") as Label;
 
            lbl.Text = countryid.ToString();
        }
 
        protected void radCountryBox2_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            int countryid;
            Int32.TryParse(e.Value, out countryid);
            Label lbl = (o as RadComboBox).Parent.FindControl("lblSelectedValue2") as Label;
 
            lbl.Text = countryid.ToString();
        }
 
        protected void radGrid_ItemCommand(object source, GridCommandEventArgs e)
        {
            if (e.CommandName.Equals(RadGrid.InitInsertCommandName))
            {
                radGrid.MasterTableView.EditFormSettings.CaptionFormatString = "Adding new Address for Party";
            }
            else if (e.CommandName.Equals(RadGrid.EditCommandName))
            {
                radGrid.MasterTableView.EditFormSettings.CaptionFormatString = "Editing Address for Party";
            }
        }
 
        protected string GetCountry1(object source)
        {
            // handle null object
            if (source == null) return "(null)";
 
            string returnValue = string.Empty;
 
            Address item = (Address)source;
 
            if (item.Country1Id != null)
                returnValue = TextUtility.PruneText(_countries1.Where(countryItem => countryItem.CountryId == item.Country1Id).First().Name);
            else
                returnValue += "(null)";
 
            return returnValue;
        }
 
        protected string GetCountry2(object source)
        {
            // handle null object
            if (source == null) return "(null)";
 
            string returnValue = string.Empty;
 
            Address item = (Address)source;
 
            if (item.Country2Id != null)
                returnValue = TextUtility.PruneText(_countries2.Where(countryItem => countryItem.CountryId == item.Country2Id).First().Name);
            else
                returnValue += "(null)";
 
            return returnValue;
        }
 
        public class TextUtility
        {
            public static string PruneText(string text)
            {
                return text;
            }
 
            public static int? TextToNullableInt(string text)
            {
                int value;
                if (int.TryParse(text, out value))
                    return value;
                else
                    return (int?)null;
            }
        }
    }
 
 }

EditFormComboWithOnLoad.aspx.designer.cs:
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
 
namespace Web.Test {
     
     
    public partial class EditFormComboWithOnLoad {
         
        /// <summary>
        /// form1 control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.HtmlControls.HtmlForm form1;
         
        /// <summary>
        /// radScriptManager control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::Telerik.Web.UI.RadScriptManager radScriptManager;
         
        /// <summary>
        /// radGrid control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::Telerik.Web.UI.RadGrid radGrid;
    }
}

2 Answers, 1 is accepted

Sort by
0
Accepted
Dimitar Terziev
Telerik team
answered on 21 Feb 2012, 01:04 PM
Hello Chris,

The experienced behavior is not a bug , but the expected one based on the custom logic applied in your scenario. The situation is the following, if you want to bind your ComboBox in its OnLoad event, this should be done only the first time when this event is fired and not upon each post-back. So the flow of your code is the following, upon initial load your second combobox is populated with data. You select and item and a post-back occurs. At that point you have a selected item along with Text and SelectedValue for the RadComboBox itself. Then again its OnLoad event is fired, the combobox is again rebound, which causing its selection to be clear. Then after the OnLoad event, the OnSelectedIndexChanged is fired, but at that point you no longer have a selected item since your control has been rebound.

In order to deal with the current behavior please change your logic as following:
protected void CountryBox2_Load(object sender, EventArgs e)
{
    
    RadComboBox radBox = sender as RadComboBox;
    if (radBox.Items.Count != 0)
        return;
    List<Country> data = _countries2;
    Country none = new Country();
    radBox.DataSource = data;
    radBox.DataTextField = "Name";
    radBox.DataValueField = "CountryId";
    radBox.EmptyMessage = "Select a Country";
    radBox.DataBind();
 
}


All the best,
Dimitar Terziev
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Chris Breisch
Top achievements
Rank 1
answered on 21 Feb 2012, 01:52 PM
Yes, you are correct. Thank you.

However, it is certainly changed behavior from releases prior to Q32011 SP1.
Tags
ComboBox
Asked by
Chris Breisch
Top achievements
Rank 1
Answers by
Dimitar Terziev
Telerik team
Chris Breisch
Top achievements
Rank 1
Share this question
or