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

Child Records via multiselect combo box

6 Answers 130 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Michael
Top achievements
Rank 1
Michael asked on 04 Aug 2012, 04:46 PM
Greetings.

I have a 100% code generated RadGrid.  It's purpose in life is to interrogate and render UI to support a Code-First Entity Framework model.

During entity edits/inserts, I would like to display a RadComboBox with checkboxes (multiselect) for child entities.  For example:

Editing Company X
ComboBox shows 20 potential employees (entire universe of the Employee entity)
Employees can be selected, and the child relationship between Company -> Employee (1 to many) are updated during RadGrid save.

Getting the combobox to appear and populate itself with the list of potential choices is no problem. I'm running into trouble when saving.  I'm trying to use the same approach that I use for other custom templates associated with the grid....


public IOrderedDictionary ExtractValues(Control container)
        {
            OrderedDictionary od = new OrderedDictionary();
            foreach (RadComboBoxItem item in rcb.Items)
            {
                if (item.Checked)
                   {
                    od.Add(name.Singularize(), item.Value); // bind the selected value to the FK Id
                }
            }
            return od;
        }

This fails for a couple reasons.  1) If I select more than one checkbox, I run into an issue trying to add the same key twice.  2) More importantly, even if I only select one item, the RadGrid update process doesn't like what I'm trying to do here (complains that a property named Employee was not found in Company).  This makes sense since Employee is a related collection, and obviously I need to be doing things differently in ExtractValues (or somewhere else).... I'm just not sure what/where.

Thanks!
Mike

6 Answers, 1 is accepted

Sort by
0
Michael
Top achievements
Rank 1
answered on 06 Aug 2012, 03:59 PM
Any initial thoughts on this from anyone?  Thanks.
0
Michael
Top achievements
Rank 1
answered on 08 Aug 2012, 01:08 AM
I have no doubt there's a simple way to do what I'm trying to do here (handle child records within a combobox on a custom edit template in a generic, non-concrete way).  Is there more information I can provide that might help folks provide some insight here?  Thanks.
0
Pavlina
Telerik team
answered on 09 Aug 2012, 01:26 PM
Hi Michael,

Can you please specify if you are using Load On Demand of RadComboBox? Note that  checkboxes and load-on-demand should not be used together as explained in the below help article: 
http://www.telerik.com/help/aspnet-ajax/combobox-usability-checkboxes.html

And for more information why the combobox items are not accessible on the server-side when loading them on demand you can check the following topic:
http://www.telerik.com/help/aspnet-ajax/combobox-load-on-demand-access-items-server-side.html

I hope this information helps.

Kind regards,
Pavlina
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
Michael
Top achievements
Rank 1
answered on 10 Aug 2012, 01:59 AM
Nope -- not using LoD for ComboBox.  The ComboBox is part of a custom edit template.  It gets loaded during Instantiation. Typically in a custom edit template I'd return an IOrderedDictionary from ExtractValues with the changes.  In this case, since we have the possibility for multiple responses (1 or more checks), I'm at a loss in terms of what I should be returning from ExtractValues, or if that's even where I should be concentrating.

Every implementation of custom edit templates I've seen has only been concerned with one value per template...  the fact that I'm trying to use the template to support the "many" side of a 1-to-many relationship is what's tripping me up.

My template for the collection is below.  Thanks.


/// <summary>
/// This template provides a checkbox dropdown list for multi selection
/// of collections related to the primary entity  (1 to many)
/// </summary>
public class AEGCollectionEditTemplate : IBindableTemplate
{
    protected RadComboBox rcb;
    private string name;
    private bool _bind;
 
    private AdvancedEntityGrid _aeg;
    private PropertyInfo _pi;
 
    List<string> Ids;
 
    public AEGCollectionEditTemplate(string name, bool bind, AdvancedEntityGrid aeg, PropertyInfo pi)
    {
        this.name = name;
        this._bind = bind;
        this._aeg = aeg;
        this._pi = pi;
    }
    public IOrderedDictionary ExtractValues(Control container)
    {
        Ids = new List<string>();
 
        //GridEditFormItem container2 = (GridEditFormItem)rcb.NamingContainer;
        //CarinaEntityObject entity = EntityDataSourceExtensions.GetItemObject<CarinaEntityObject>(container2.DataItem);
 
        OrderedDictionary od = new OrderedDictionary();
        foreach (RadComboBoxItem item in rcb.Items)
        {
            if (item.Checked)
            {
                Ids.Add(item.Value);
                //od.Add(name.Pluralize(), item.Value); // bind the selected value to the FK Id
            }
        }
        return od;
    }
 
    public void InstantiateIn(Control container)
    {
        // TODO: Implement this method
        rcb = new RadComboBox();
        rcb.CheckBoxes = true;
        rcb.ID = "rcb" + name;
 
        try
        {
            string sql = "SELECT Id, Label FROM " + name.Pluralize();
            ObjectResult<CarinaEntityObject> or = _aeg.GetUnderlyingContext().ExecuteStoreQuery<CarinaEntityObject>(sql);
 
            foreach (CarinaEntityObject h in or)
            {
                RadComboBoxItem item = new RadComboBoxItem(h.Label, h.Id.ToString());
                rcb.Items.Add(item);
            }
        }
        catch (Exception e)
        {
        }
         
 
        if (_bind)
            rcb.DataBinding += new EventHandler(rcb_DataBinding);
 
        container.Controls.Add(rcb);
    }
 
 
    private void rcb_DataBinding(object sender, EventArgs e)
    {
        //try
        {
            string fieldName = name;
            RadComboBox rcb = (RadComboBox)sender; // is this overloading the scope of tb??? TODO!!! Check all of them
            GridEditFormItem container = (GridEditFormItem)rcb.NamingContainer;
 
            // I need the collection of child items, which I'll then iterate through and set
            // to checked
 
            // convert from an EDS wrapper to the actual entity..
            CarinaEntityObject entity = EntityDataSourceExtensions.GetItemObject<CarinaEntityObject>(container.DataItem);
            dynamic items = DataBinder.Eval(entity, fieldName);
 
            foreach (CarinaEntityObject item in items)
            {
                int idx = rcb.FindItemIndexByValue(item.Id.ToString());
                rcb.Items[idx].Checked = true;
            }
 
        }
        //catch (Exception ex)
        //{
        //}
    }
}
0
Michael
Top achievements
Rank 1
answered on 14 Aug 2012, 04:11 PM
Bump.
0
Pavlina
Telerik team
answered on 15 Aug 2012, 09:21 AM
Hi Michael,

You can not use ExtractValues in your case. Instead you should find the combobox placed in custom edit template and access the checked items manually.

Regards,
Pavlina
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
Michael
Top achievements
Rank 1
Answers by
Michael
Top achievements
Rank 1
Pavlina
Telerik team
Share this question
or