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

SelectedIndexChanged loosed filtering'values

3 Answers 103 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tonio
Top achievements
Rank 2
Tonio asked on 20 Dec 2011, 12:11 PM
Hello all,
I'm use the RadGrid in WebServerControl and I'm have a problem with the event of "SelectedIndexChanged" with "AllowFilteringByColumn = true;"
This is the declaration code for my RadGrid : 
var Grid = 
new RadGrid
            {
                AllowFilteringByColumn = true,
                AllowPaging = true,
                AllowSorting = true,
                ShowStatusBar = true,
                ShowHeader = true,
                GridLines = GridLines.None,
                PageSize = PageSize,
                EnableViewState = true,
                ID = string.Format("{0}_Grid", ID)
            };

When I'm selected a row after use filters, the grid is rebind and my filter is loosed.
The value of "SelectedValue" doesn't match with my selection and the grid is reinitialised.

My Code:
WebServerControl:
public class CustomRadGrid : WebControl, INamingContainer
{
    protected RadAjaxManager AjaxManager;
    protected RadAjaxLoadingPanel AjaxLoadingPanel;
    protected RadGrid Grid;
    protected ObjectDataSource ObjDataSource;
 
    #region PROPERTIES
    public string SelectCountMethod;
    public string SelectMethod;
    public string MaximumRowsParameterName;
    public string StartRowIndexParameterName;
    public string DataObjectTypeName;
    public List<KeyValuePair<string, string>> SelectParameters;
 
    /// <summary>
    /// Display columns in gridview
    /// </summary>
    /// <value>
    /// Key = ColumnName       
    /// Value = DiplayName, Type of the column ToString()
    /// </value>
    public List<KeyValuePair<string, KeyValuePair<string, Type>>> DisplayColumns;
 
    /// <summary>
    /// Data Key Names uses in Master Table View
    /// </summary>
    public string[] DataKeyNames;
 
    /// <summary>
    /// If you want use external DataSource, set this DataSourceID
    /// </summary>
    public string DataSourceID;
 
    /// <summary>
    /// Set this for initialize a control to refresh after row selection
    /// </summary>
    public string ControlIDToRefresh { private get; set; }
 
    /// <summary>
    /// Gets or sets the size of the page.
    /// </summary>
    /// <value>
    /// The size of the page.
    /// </value>
    private int _pageSize;
    public int PageSize
    {
        get
        {
            return (Grid != null) ? Grid.PageSize : _pageSize;
        }
        set
        {
            _pageSize = value;
            if (Grid != null)
            { Grid.PageSize = _pageSize; }
        }
    }
 
    /// <summary>
    /// Gets the index of the current page.
    /// </summary>
    /// <value>
    /// The index of the current page.
    /// </value>
    public int CurrentPageIndex
    {
        get
        {
            EnsureChildControls();
            return (Grid != null) ? Grid.CurrentPageIndex : 0;
        }
    }
 
    /// <summary>
    /// Gets the selected value.
    /// </summary>
    private string _selectedValue;
    public string SelectedValue
    {
        get
        {
            return string.IsNullOrEmpty(_selectedValue) ? "" : _selectedValue;
        }
    }
 
    /// <summary>
    /// Save grid settings
    /// </summary>
    private string _settings;
 
    #endregion PROPERTIES
 
    /// <summary>
    /// Initializes a new instance of the <see cref="CustomRadGrid"/> class.
    /// </summary>
    public CustomRadGrid()
    {
        PageSize = 20;
        DataSourceID = "";
    }
 
    /// <summary>
    /// Gets a <see cref="T:System.Web.UI.ControlCollection"/> object that represents the child controls for a specified server control in the UI hierarchy.
    /// </summary>
    /// <returns>
    /// The collection of child controls for the specified server control.
    ///   </returns>
    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return base.Controls;
        }
    }
 
    /// <summary>
    /// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
    /// </summary>
    /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
 
        #region DataSource
        if (string.IsNullOrEmpty(DataSourceID))
        {
            ObjDataSource = new ObjectDataSource
            {
                //EnablePaging = true,
                TypeName = "BLL.BL",
                ID = string.Format("{0}_ObjDataSource", ID),
                SelectMethod = SelectMethod,
                SelectCountMethod = SelectCountMethod
            };
            if (!string.IsNullOrEmpty(MaximumRowsParameterName))
                ObjDataSource.MaximumRowsParameterName = MaximumRowsParameterName;
            if (!string.IsNullOrEmpty(StartRowIndexParameterName))
                ObjDataSource.StartRowIndexParameterName = StartRowIndexParameterName;
            ObjDataSource.Selecting += ObjDataSourceSelecting;
            foreach (var selectParameter in SelectParameters)
            {
                ObjDataSource.SelectParameters.Add(selectParameter.Key, selectParameter.Value);
            }
            Controls.Add(ObjDataSource);
        }
        #endregion DataSource
 
        #region GRID
        Grid = new RadGrid
        {
            AllowFilteringByColumn = true,
            AllowPaging = true,
            AllowSorting = true,
            ShowStatusBar = true,
            ShowHeader = true,
            GridLines = GridLines.None,
            PageSize = PageSize,
            EnableViewState = true,
            ID = string.Format("{0}_Grid", ID)
        };
        if (DisplayColumns == null || DisplayColumns.Count == 0)
        {
            Grid.MasterTableView.AutoGenerateColumns = Grid.AutoGenerateColumns = true;
        }
        else
        {
            Grid.MasterTableView.AutoGenerateColumns = Grid.AutoGenerateColumns = false;
            foreach (var displayColumn in DisplayColumns)
            {
                Grid.MasterTableView.Columns.Add(new GridBoundColumn
                {
                    UniqueName = displayColumn.Key,
                    DataField = displayColumn.Key,
                    DataType = displayColumn.Value.Value,
                    HeaderText = displayColumn.Value.Key,
                    DataFormatString =
                        displayColumn.Value.Value == typeof(DateTime)
                            ? "{0:d}"
                            : "{0}"
                });
            }
        }
 
        Grid.ClientSettings.EnableRowHoverStyle = true;
        Grid.ClientSettings.EnableAlternatingItems = true;
        Grid.ClientSettings.EnablePostBackOnRowClick = true;
        Grid.ClientSettings.Selecting.AllowRowSelect = true;
 
        Grid.MasterTableView.CommandItemDisplay = GridCommandItemDisplay.Top;
        Grid.MasterTableView.CommandItemSettings.ShowRefreshButton = false;
        Grid.MasterTableView.CommandItemSettings.ShowAddNewRecordButton = false;
        Grid.MasterTableView.CommandItemSettings.ShowExportToExcelButton = true;
        Grid.MasterTableView.PagerStyle.AlwaysVisible = true;
 
        //Select the DataSource
        if (string.IsNullOrEmpty(DataSourceID) && ObjDataSource != null)
        { Grid.DataSourceID = ObjDataSource.ID; }
        else if (ObjDataSource == null && !string.IsNullOrEmpty(DataSourceID))
        { Grid.DataSourceID = DataSourceID; }
        else
        { Grid.NeedDataSource += OnNeedDataSource; }
        //Initialise DataKeys
        if (DataKeyNames != null && DataKeyNames.Count() > 0)
        { Grid.MasterTableView.DataKeyNames = DataKeyNames; }
 
        //Grid events
        //Grid.Init += GridInit;
        Grid.ItemCommand += GridItemCommand;
        Grid.ItemCreated += GridItemCreated;
        Grid.SelectedIndexChanged += GridSelectedIndexChanged;
        Controls.Add(Grid);
 
        #endregion GRID
 
        #region AJAX
        //Initialise Ajax Manager
        AjaxLoadingPanel = new RadAjaxLoadingPanel
        {
            InitialDelayTime = 1,
            MinDisplayTime = 200,
            ID = string.Format("{0}_AjaxLoadingPanel", ID)
        };
        Controls.Add(AjaxLoadingPanel);
 
        AjaxManager = RadAjaxManager.GetCurrent(Page);
        if (AjaxManager == null)
        {
            AjaxManager = new RadAjaxManager
            {
                ID = string.Format("{0}_AjaxManager", ID),
                DefaultLoadingPanelID = AjaxLoadingPanel.ID,
                EnableAJAX = true
            };
            Controls.Add(AjaxManager);
            Page.Items.Add(typeof(RadAjaxManager), AjaxManager);
        }
 
        //Set Ajax Settings:
        if (!string.IsNullOrEmpty(ControlIDToRefresh))
        {
            var ajaxSetting = new AjaxSetting(Grid.ID);
            ajaxSetting.UpdatedControls.Add(new AjaxUpdatedControl(ControlIDToRefresh, AjaxLoadingPanel.ID));
            ajaxSetting.EventName = "OnRowSelected";
            AjaxManager.AjaxSettings.Add(ajaxSetting);
        }
        AjaxManager.AjaxSettings.AddAjaxSetting(Grid, Grid, AjaxLoadingPanel, UpdatePanelRenderMode.Inline);
 
        //To export in Excel:
        if (!Page.ClientScript.IsStartupScriptRegistered(GetType(), string.Format("{0}_onRequestStart", ID)))
        {
            var onRequestStart = string.Format("function {0}_onRequestStart(ajaxManager, eventArgs){{if(eventArgs.EventTarget.indexOf('ExportToExcelButton') != -1){{eventArgs.EnableAjax = false;}}}}", ID);
            Page.ClientScript.RegisterStartupScript(GetType(), string.Format("{0}_onRequestStart", ID), onRequestStart, true);
            AjaxManager.ClientEvents.OnRequestStart = string.Format("{0}_onRequestStart", ID);
        }
        #endregion AJAX
    }
 
    /// <summary>
    /// Grids the init.
    /// Reduce the set of filter functions so that the filter menu can only show the NoFilter, Contains, EqualTo, GreaterThan and LessThan items
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    void GridInit(object sender, EventArgs e)
    {
        var menu = Grid.FilterMenu;
        var i = 0;
        while (i < menu.Items.Count)
        {
            if (menu.Items[i].Text == "NoFilter" || menu.Items[i].Text == "Contains" || menu.Items[i].Text == "EqualTo" || menu.Items[i].Text == "GreaterThan" || menu.Items[i].Text == "LessThan")
            {
                i++;
            }
            else
            {
                menu.Items.RemoveAt(i);
            }
        }
    }
 
    #region GRID EVENTS
    /// <summary>
    /// Delegate to attach method on SelectedIndexChanged
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public delegate void SelectedIndexChangedHandler(object sender, EventArgs e);
 
    /// <summary>
    /// Occurs when [selected index changed].
    /// </summary>
    [Category("Configuration"), Browsable(true), Description("Evènement associé au gridview")]
    public event SelectedIndexChangedHandler SelectedIndexChanged;
 
    /// <summary>
    /// Grids the selected index changed.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    void GridSelectedIndexChanged(object sender, EventArgs e)
    {
        _selectedValue = (string)(Grid.SelectedValue ?? "");
        if (SelectedIndexChanged != null)
            SelectedIndexChanged(this, e);
    }
 
    /// <summary>
    /// Delegate to attach method on NeedDataSource
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public delegate void NeedDataSourceHandler(object sender, EventArgs e);
 
    /// <summary>
    /// Occurs when [need data source].
    /// </summary>
    [Category("Configuration"), Browsable(true), Description("Evènement associé au gridview")]
    public event NeedDataSourceHandler NeedDataSource;
 
    /// <summary>
    /// Called when [need data source].
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="Telerik.Web.UI.GridNeedDataSourceEventArgs"/> instance containing the event data.</param>
    void OnNeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
        if (NeedDataSource != null) { NeedDataSource(this, e); }
        else if (string.IsNullOrEmpty(DataSourceID)) { Grid.DataSource = ObjDataSource; }
    }
    #endregion GRID EVENTS
 
    #region EXPORT
    /// <summary>
    /// To know if exporting
    /// </summary>
    bool _isExport = false;
 
    /// <summary>
    /// Grids the item created.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="Telerik.Web.UI.GridItemEventArgs"/> instance containing the event data.</param>
    void GridItemCreated(object sender, GridItemEventArgs e)
    {
        //Remove the filter line when exporting data
        if (e.Item is GridFilteringItem && _isExport)
            e.Item.Visible = false;
    }
 
    /// <summary>
    /// Grids the item command.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="Telerik.Web.UI.GridCommandEventArgs"/> instance containing the event data.</param>
    private void GridItemCommand(object sender, GridCommandEventArgs e)
    {
        if (e.CommandName == RadGrid.ExportToExcelCommandName ||
             e.CommandName == RadGrid.ExportToWordCommandName ||
             e.CommandName == RadGrid.ExportToCsvCommandName)
        {
            Grid.ExportSettings.OpenInNewWindow = true;
            Grid.ExportSettings.ExportOnlyData = true;
            Grid.ExportSettings.IgnorePaging = true;
            Grid.ExportSettings.Excel.Format = GridExcelExportFormat.Html;
            Grid.ExportSettings.FileName = string.Format("[{0}]Export", DateTime.Now.ToString("yyyyMMdd_HHmm"));
            _isExport = true;
        }          
    }
    #endregion EXPORT
 
    #region DATASOURCE
    /// <value>
    /// The data source.
    /// </value>
    public object DataSource
    {
        set
        {
            EnsureChildControls();
            Grid.DataSource = value;
        }
    }
 
    /// <summary>
    /// Objs the data source selecting.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs"/> instance containing the event data.</param>
    private void ObjDataSourceSelecting(object sender, ObjectDataSourceSelectingEventArgs e)
    {
        if (SelectParameters != null)
        {
            ObjDataSource.SelectParameters.Clear();
            if (!e.ExecutingSelectCount &&
                SelectParameters.Count != 0)
            {
                foreach (var selectParameter in SelectParameters)
                {
                    ObjDataSource.SelectParameters.Add(selectParameter.Key, selectParameter.Value);
                }
            }
        }
 
    }
    #endregion DATASOURCE
}

WebPart who's use it :

public class DIList : Abstract.BaseAjaxWebpart
    {
        protected GridViewDI DIs;
        protected EditDI DIEdit;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
 
            DIEdit = new EditDI { ID = string.Format("{0}_DIEdit", this.ID) };
            Controls.Add(DIEdit);
 
            DIs = new GridViewDI { ID = string.Format("{0}_DIList", this.ID), ControlIDToRefresh = DIEdit.ID };
            Controls.AddAt(0, DIs);
            DIs.SelectedIndexChanged += DIListSelectedIndexChanged;
        }
 
        void DIListSelectedIndexChanged(object sender, EventArgs e)
        {
            DIEdit.idDIValue = DIs.SelectedValue;
        }
    }

3 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 22 Dec 2011, 12:16 PM
Hello Tonio,

Most often this problem is caused by the way you are adding the RadGrid instance to the page. In your scenario you are adding RadGrid on PageLoad event and you are doing this every time the page is requested from server. With this approach every time you are creating new instance of RadGrid and thus you are bypassing the ViewState which is unable to recreate the control in the way that was before the last request.

So, in this case you should add the control to the page only on initial page load before any postbacks have occurred. You could try to change your code like this:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!Page.IsPostBack)
    {
        DIEdit = new EditDI { ID = string.Format("{0}_DIEdit", this.ID) };
        Controls.Add(DIEdit);
 
        DIs = new GridViewDI { ID = string.Format("{0}_DIList", this.ID), ControlIDToRefresh = DIEdit.ID };
        Controls.AddAt(0, DIs);
        DIs.SelectedIndexChanged += DIListSelectedIndexChanged;
    }
}

Thus you will add RadGrid only the first time the page is requested from the server, and after that the ViewState will take care of recreating the control.

Give this suggestion a try and check whether the issue is resolved.



Regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Tonio
Top achievements
Rank 2
answered on 22 Dec 2011, 03:11 PM
Hi Andrey,
I tested your solution but it does'nt work for me... the control disappears after selecting a grid line or after change current page.
Finally I'm remove AJAX in my control and I add AJAX on the webpart with this code:

   protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
 
            var ajaxLoadingPanel = new RadAjaxLoadingPanel
            {
                InitialDelayTime = 1,
                MinDisplayTime = 200,
                ID = string.Format("{0}_AjaxLoadingPanel", ID)
            };
            Controls.Add(ajaxLoadingPanel);
 
            var ajaxManager = RadAjaxManager.GetCurrent(Page);
            if (ajaxManager == null)
            {
                ajaxManager = new RadAjaxManager
                {
                    ID = string.Format("{0}_AjaxManager", ID),
                    DefaultLoadingPanelID = ajaxLoadingPanel.ID,
                    EnableAJAX = true
                };
                Controls.Add(ajaxManager);
                Page.Items.Add(typeof(RadAjaxManager), ajaxManager);
            }
 
            var upd = new RadAjaxPanel { ID = string.Format("{0}_UpdatePanel", ID), EnableAJAX = true, LoadingPanelID = ajaxLoadingPanel.ID };
            var editDI = new EditDI { ID = string.Format("{0}_DIEdit", ID) };
            var gridViewDI = new GridViewDI { ID = string.Format("{0}_DIList", ID) };
 
            gridViewDI.SelectedIndexChanged += delegate
            {
                editDI.idDIValue = gridViewDI.SelectedValue;
            };
 
            upd.Controls.Add(gridViewDI);
            upd.Controls.Add(editDI);
            Controls.Add(upd);
 
        }


0
Andrey
Telerik team
answered on 22 Dec 2011, 07:36 PM
Hi Tonio,

As this help article says when you are adding dynamically controls on Page_Load event you need to add the control to the respective collection first and then to set its settings. This should be done because no  ViewState is preserved until you add the control to the Controls collection of the page. That is the reason for loosing the filter expression of RadGrid and the other problem you have at the beginning.

Your code should look something like this:

protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
 
        var ajaxLoadingPanel = new RadAjaxLoadingPanel();
        Controls.Add(ajaxLoadingPanel);
        ajaxLoadingPanel.InitialDelayTime = 1;
        ajaxLoadingPanel.MinDisplayTime = 200;
        ajaxLoadingPanel.ID = string.Format("{0}_AjaxLoadingPanel", ID);     
         
 
        var ajaxManager = RadAjaxManager.GetCurrent(Page);
        if (ajaxManager == null)
        {
            ajaxManager = new RadAjaxManager();
            Controls.Add(ajaxManager);
            ajaxManager.ID = string.Format("{0}_AjaxManager", ID);
            ajaxManager.DefaultLoadingPanelID = ajaxLoadingPanel.ID;
            ajaxManager.EnableAJAX = true;           
             
            Page.Items.Add(typeof(RadAjaxManager), ajaxManager);
        }
 
        var upd = new RadAjaxPanel();
        Controls.Add(upd);
        upd.ID = string.Format("{0}_UpdatePanel", ID);
        upd.EnableAJAX = true;
        upd.LoadingPanelID = ajaxLoadingPanel.ID;
         
        var editDI = new EditDI();
        upd.Controls.Add(editDI);
        editDI.ID = string.Format("{0}_DIEdit", ID);
 
        var gridViewDI = new GridViewDI();
        upd.Controls.Add(gridViewDI);
        gridViewDI.ID = string.Format("{0}_DIList", ID);
 
        gridViewDI.SelectedIndexChanged += delegate
        {
            editDI.idDIValue = gridViewDI.SelectedValue;
        };
    }

You could check this article about dynamic controls on the Infinities Loop blog.

And about the SelectedIndexChanged event you need to verify that you have set the AutoPostback property to true.

If after applying these correction to your code you still have problems, please share a working sample of your code, so we could test it on our side.

Kind regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
Tags
Grid
Asked by
Tonio
Top achievements
Rank 2
Answers by
Andrey
Telerik team
Tonio
Top achievements
Rank 2
Share this question
or