How to use different editors depending on some row data?

11 posts, 2 answers
  1. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 22 Nov 2010 Link to this post

    Hello,

    I'm very new to ASP.Net and RadControls for ASP.Net.
    I'm creating a web application intended to help the user building a SQL Query for a given table. The user needs to specify filters for the query for a set of pre-selected fields.
    I decided to use a RadGridView for letting the user entering this information. Each row represents a filter, and those filters include a comparison operator and a value to compare against it.
    I have already managed for populating a dropdown column dinamically with the possible set of operators one could apply for each field depending on it's data type. Now I'd like to be able to decide at runtime for each row what editor to use (depending on the field's data type too) for letting the user enter the value. Please note that when I talk about a field I'm talking about it's logical representation: a row, not a column.
    Is it possible at all? Any help will be very apreciated.
    Thanks in advance,

    Gonzalo
  2. NLV
    NLV avatar
    87 posts
    Member since:
    Aug 2009

    Posted 24 Nov 2010 Link to this post

    Hello Gonzalo

    I would simply achieve that by trapping the event 'ItemCreated'. Put a GridTemplateColumn with an empty panel in it. During the ItemCreated event trap the panel creating for each row and based on the data on another column add your dynamic control into the panel.

    Note: There could be better ways

    Regards
    NLV.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Answer
    Tsvetoslav
    Admin
    Tsvetoslav avatar
    1823 posts

    Posted 25 Nov 2010 Link to this post

    Hi Gonzalo,

    Raghavendra's approach is viable but I'd like to make one small correction: if you need to use data from other columns in order to programmatically create the controls in the dynamic column you should use the ItemDataBound event, not the ItemCreated one.

    Hope it helps.

    Best wishes,
    Tsvetoslav
    the Telerik team
    Browse the vast support resources we have to jumpstart your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
  5. Answer
    NLV
    NLV avatar
    87 posts
    Member since:
    Aug 2009

    Posted 25 Nov 2010 Link to this post

    Oh yeah. Since the control creation is based on 'data' you need to use ItemDataBound.
  6. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 25 Nov 2010 Link to this post

    Thank you very much guys, for your valuable help.
    I will try the proposed approch and let you know ASAP.
    Best wishes,

    Gonzalo
  7. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 25 Nov 2010 Link to this post

    Guys, you rock!
  8. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 27 Nov 2010 Link to this post

    Hello Again,
    I followed your advice and it worked ok when displaying the grid and for letting the user entering values.
    However, at a later stage I need to grab those values and then I run into trouble because the panel's controls collection contains only a literal control. I don't know why it doesn't preserve the original objects.
    I created the template like this:

    <telerik:GridTemplateColumn HeaderText="Indice el valor" UniqueName="ValorComparacion">
       <ItemTemplate>
           <asp:Panel ID="TemplatePanel" runat="server">
                 
           </asp:Panel>                                
       </ItemTemplate>
    </telerik:GridTemplateColumn>

    Then, in the code behind I add the controls based on the databound data:
    protected void GridFiltros_ItemDataBound(object sender, GridItemEventArgs e)
    {
        if (e.Item.DataItem != null
        {                
            Panel p = (Panel)e.Item.FindControl("TemplatePanel");
            if (p != null)
            {
                TableFieldInfo info = (TableFieldInfo)e.Item.DataItem;
                switch (info.Tipo)
                {
                    case TiposDato.Fecha:
                        p.Controls.Add(new RadDatePicker());
                        break;
                    case TiposDato.Logico:
                        p.Controls.Add(new CheckBox());
                        RadComboBox operador = (RadComboBox)e.Item.FindControl("RadComboBoxOperador");
                        if (operador != null)
                            operador.Enabled = false;
                        break;
                    default:
                        p.Controls.Add(new RadTextBox());
                        break;
                }                   
            }
        }
    }

    After that when the user clicks on a button I iterate over the rows.  I grab the panel from the row like this and call the method intended to read the control's value:

    ...
    Panel p = (Panel)row["ValorComparacion"].FindControl("TemplatePanel");
    string value = GetEditorValue(p, tipo);
    ...

    Here's the GetEditorValue method definition:

    private string GetEditorValue(Panel panel, string tipo)
    {
        TiposDato tipoDato = (TiposDato)Enum.Parse(typeof(TiposDato), tipo);
        object valor;
        switch (tipoDato)
        {
            case TiposDato.Fecha:
                RadDatePicker dp = (RadDatePicker)panel.Controls[0];
                valor = dp.SelectedDate;
                break;
            case TiposDato.Logico:
                CheckBox ch = (CheckBox)panel.Controls[0];
                valor = ch.Checked;
                break;
            default:
                RadTextBox tb = (RadTextBox)panel.Controls[0];
                valor = tb.Text;
                break;
        }
        return valor.ToString();
    }

    And then, when the method tryes to cast the unique control the panel contains, it throws an exception because it's a literal control instead off a RadTextBox for example.
    Any clue??
    Thanks in advance,

    Gonzalo
  9. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 27 Nov 2010 Link to this post

    Ok, I finally got it to work.
    Instead of adding controls at runtime I created a user control containing all the different editors I need. I made all of them invisible.
    Then, instead of adding a panel to the template as originally suggested I added my user control.
    At runtime, using the ItemDatabound event I call a method on my user control (DynamicInput) in which I decide which editor to make visible depending on data from other columns.

    ...
    DynamicInput di = (DynamicInput)e.Item.FindControl("DynamicInput1");
    TableFieldInfo info = (TableFieldInfo)e.Item.DataItem;
    di.DisplayEditor(info.Tipo);
    ...

    Here's the code for the DisplayMethod:

    public void DisplayEditor(TiposDato tipo)
    {    
        switch (tipo)
        {                      
            case TiposDato.Logico:
                this.CheckBox1.Visible=true;
                break;
            case TiposDato.Fecha:
                this.RadDatePicker1.Visible = true;
                this.RadDatePicker1.SelectedDate = DateTime.Today;
                this.RadDatePicker1.DateInput.CausesValidation = true;
                break;
            default:
                 this.RadTextBox1.Visible=true;
                 break;
        }
    }

    then, I iterarate over the rows and read the values like this:
    foreach (GridDataItem row in this.GridFiltros.MasterTableView.Items)
    {
        ...
        string tipo = row["Tipo"].Text;
        DynamicInput p = (DynamicInput)row["ValorComparacion"].FindControl("DynamicInput1");
        string value;
        value = p.GetValue((TiposDato)Enum.Parse(typeof(TiposDato), tipo));
        ...
    }

    And finally, the code for the GetValue method:
    public string GetValue(TiposDato tipo)
    {            
        object valor="";
        switch (tipo)
        {
            case TiposDato.Logico:
                valor = this.CheckBox1.Checked;
                break;
            case TiposDato.Fecha:
                valor = this.RadDatePicker1.SelectedDate;
                break;
            default:
                valor = this.RadTextBox1.Text;
                break;
        }
        return valor.ToString();
    }

    This is working Ok for me.
    Thanks a lot.

    Regards,

    Gonzalo
  10. Harry
    Harry avatar
    6 posts
    Member since:
    Mar 2012

    Posted 17 May 2013 Link to this post

    How do you handle postbacks from the controls created.  The conrols disappear  on postback.
  11. Harry
    Harry avatar
    6 posts
    Member since:
    Mar 2012

    Posted 17 May 2013 Link to this post

    Seems like a tacky solution.
  12. gmendez
    gmendez avatar
    82 posts
    Member since:
    Jun 2012

    Posted 19 May 2013 Link to this post

    Hello Harry,

    Sorry I can't help you. I don't even have access to the source code anymore.
    Regards,

    Gonzalo
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017