We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

How to populate DropDownList using List<ExpandoObject>

Hello,

Is it possible to use List<ExpandoObject> as a DataSource?

My code so far:


    <EjsDropDownList TValue="int?" TItem="ExpandoObject" ID="ctl1" Placeholder="Select..." ShowClearButton="true" DataSource="@DataSource2">
        <DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings>
    </EjsDropDownList>

@code {
    public List<ExpandoObject> DataSource2 { get; set; } = new List<ExpandoObject>();

for (int i = 1; i <= 10; i++)
        {
            
            dynamic expando = new ExpandoObject();
            expando.ID = i;
            expando.Text = $"Text..{i}";

            DataSource2.Add(expando);

        }
}


Thank you in advance,

Bill

6 Replies

GG Gopi Govindasamy Syncfusion Team January 17, 2020 06:23 AM UTC

Hi Bill,  

Greeting from Syncfusion support. 

Yes, possible to bind the list<object> data to dropdownlist component. You can bind the List<ExpandoObject> data to DataSourc property and add the list data to page OnInitialized() event. We have prepared sample based on your requirement, please find the code snippet and sample for your reference.  

@using Syncfusion.EJ2.Blazor.DropDowns; 
 
<EjsDropDownList TValue="int?" TItem="ExpandoObject" ID="ctl1" Placeholder="Select..." ShowClearButton="true" DataSource="@DataSource2"> 
    <DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings> 
</EjsDropDownList> 
 
@code { 
    public List<ExpandoObject> DataSource2 { get; set; } = new List<ExpandoObject>(); 
 
    protected override void OnInitialized() 
    { 
        for (int i = 1; i <= 10; i++) 
        { 
 
            ExpandoObject expando = new ExpandoObject(); 
            expando.ID = i; 
            expando.Text = $"Text..{i}"; 
 
            DataSource2.Add(expando); 
 
        } 
    } 
 
    public class ExpandoObject 
    { 
        public int ID { get; set; } 
        public string Text { get; set; } 
    } 
} 
 


Regards,
Gopi G. 



BL Bill Lemonis January 17, 2020 09:02 AM UTC

Hello,

Thanks for the reply, but this isn't what I really looking for.
The fields ID and Text are just there as an example. I'm creating the Dropdown's dynamically among with other components and I'm setting everything at runtime, even the property names (in my example ID and Text)

In your example, you just have the 2 fields with a specific type (int and string in a simple class), but I have cases where  my datasource that may have 3 or more fields with types that are not just int and string. This code prior to the last version was working just fine because the "TItem" wasn't introduced!!! 

The problem with TItem is that it works with standard types and not with dynamic (same as described in the following post:

List < dynamic >DataSource2  to List < ExpandoObject >DataSource2


On the other hand, ComboBox (it doesn't have the property TItem), works with dynamic properties. I'm afraid that if "TItem" will be added in Combox, it wont work either.

Probably my initial question was simpler, and I didn't described fully my code. My project is huge and depends entirely of what is stored in DB and that's why I can't attached it but I will try to describe it using pseudo code:
----------------------------------------------------------------------------------------------------------------
RenderFragment b = builder =>
{
//ControlsFromDB is a List containg the controls that they will be drawn on the form
foreach(var ctrl in ControlsFromDB)
        {
//some other code
..................
switch(ctrl.Type){
     //Draw DropDown Control
     case DropDown:
          List < ExpandoObject > DataSource2=new List< ExpandoObject > (); // List < ExpandObject > used to be List < dynamic >!!!
          // ctrl.Datasource contains a dynamic list with n-fields (Dapper dynamic Select)  
          foreach(var items in ctrl.Datasource){
               dynamic expando1 = new ExpandoObject();
               foreach(var valuepair in items)
                    ((ExpandoObject)expando1).AddProperty(valuepair.Key,valuepair.Value ); //my extension to add properties to dynamic object

               DataSource2.Add(expando);
}

builder.OpenComponent(cnt++, typeof(EjsDropDownListExpandoObject>)); 
                                builder.AddAttribute(cnt++, "Value",ctrl objVal);
                                builder.AddAttribute(cnt++, "DataSource",  DataSource2);
                                builder.AddAttribute(cnt++, "ShowClearButton", true);


etc.......................

The dropdown now it shows empty rows when I open it!

I hope that my question is more clear and I'm sorry for the misunderstanding.

Thanks again,

Bill


SN Sevvandhi Nagulan Syncfusion Team January 21, 2020 05:15 PM UTC

Hi Bill, 

We have checked the reported requirement. We would like to inform you that, we have provided generic type support for DropDownList(Tvalue and TItem). So you need to specify the Tvalue and TItem while rendering the component also, in the shared code snippet we can see that you did not bind the field property. If you are using the object data, you need to bind the field property. Kindly refer the below code, 

<div id="component-container"> 
    @DynamicRender 
</div> 
 
<EjsButton ID="dynamic-button" Content="Render DropDownList" @onclick="RenderComponent"></EjsButton> 
 
@code { 
private RenderFragment DynamicRender { get; set; } 
 
public string value { get; set; } 
 
public List<ExpandoObject> DataSource2 { get; set; } = new List<ExpandoObject>(); 
 
private RenderFragment CreateComponent() => builder => 
{ 
    builder.OpenComponent(0, typeof(EjsDropDownList<string, ExpandoObject>)); 
    builder.AddAttribute(1, "Value", value); 
    builder.AddAttribute(2, "DataSource", DataSource2); 
    builder.AddAttribute(3, "ShowClearButton", true); 
    builder.AddAttribute(4, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((builder2) => 
    { 
       builder2.AddMarkupContent(5, "\r    "); 
       builder2.OpenComponent<Syncfusion.EJ2.Blazor.DropDowns.DropDownListFieldSettings> 
    (6); 
     
        builder2.AddAttribute(7, "Value", "ID"); 
        builder2.AddAttribute(8, "Text", "Text"); 
        builder2.CloseComponent(); 
        builder2.AddMarkupContent(9, "\r"); 
    })); 
        builder.CloseComponent(); 
    }; 
 
    private void RenderComponent() 
    { 
    DynamicRender = CreateComponent(); 
    } 
    protected override void OnInitialized() 
    { 
    for (int i = 1; i <= 10; i++) 
    { 
 
    ExpandoObject expando = new ExpandoObject(); 
    expando.ID = i; 
    expando.Text = $"Text..{i}"; 
 
    DataSource2.Add(expando); 
 
    } 
    } 
    public class ExpandoObject 
    { 
    public int ID { get; set; } 
    public string Text { get; set; } 
    } 
    } 

Please find the sample below, 

 

Regards, 
Sevvandhi N 



BL Bill Lemonis January 21, 2020 07:37 PM UTC

Thanks for your reply,

Still, this isn't want I'm asking. I need to bind (from the System.Linq.Expressions.dll library) the System.Dynamic.ExpandoObject (and not a class called ExpandoObject) and assign n-number of properties with different names at runtime!!


As I explained on my previous post, there is a for-loop where I create dropdowns dynamically and then I  assign to each one them a datasource where the fields are not always Text and ID, but they vary. 

Please note that my  code used to work with the previous versions. The new version (17.4.) has introduced the  TItem property for the dropdown control and now my controls show EMPTY ROWS. On the other hand, ComboBox which it doesn't have the TItem property yet, works just fine. The problem is that I must use dropdowns.

In other words, what actually fits in my case is TItem property could accept dynamic or object type. Both of them, I know, are not accepted and closer to them is the ExpandoObject mentioned before.
 
Actually, I have a filter box where the controls are created according of what the main form shows. For example, the main form handles the personnel my filter box  has a set of some controls and among them, one dropdown with the names, another dropdown with the departments etc. 
So, the first dropdown, its Value property  is  set to "ID" and the Text property to "FullName":

        builder2.AddAttribute(cnt++, "Value", ctrl.LookupField);  // ctrl.LookupField contains the value "ID" 
        builder2.AddAttribute(cnt++, "Text", ctrl.LookupDisplay); //ctrl.LookupDisplay contains the value "FullName"

The for-loop continues and encounters the next dropdown which is the Department dropdown where the Text property now is called "DepartmentName":

          builder2.AddAttribute(cnt++, "Value", ctrl.LookupField);  // ctrl.LookupField again is called "ID" 
        builder2.AddAttribute(cnt++, "Text", ctrl.LookupDisplay); //but ctrl.LookupDisplay contains the value "DepartmentName"

 etc, etc. 


In some cases,  a Datasource may have more that 2 fields, so getting back the selected row data from that dropdown, I get the information I need, as simple as that.

If  this still is not clear of what I'm trying to do, please tell in order to implement a minified version of my project (but it will take a lot of afford and that's way I haven't done it already).

Thanks again,

Bill    
 




BL Bill Lemonis January 21, 2020 08:53 PM UTC

Hi,


In the mean time, I've created a small project having the controls placed at design time, just to show of what I'm trying to do so far.
As you can see the first dropdown show empty rows,

Please just downgrade the project to version 17.3.0.29-beta and you will see that the  dropdown show the data


Thanks,

Bill  

Attachment: BlazorAppGrid_ecc1003d.zip


SP Sureshkumar P Syncfusion Team January 24, 2020 04:40 AM UTC

Hi Bill,  
 
We have validated your requirement. We considered as reported issue as feature at our end. This feature will be included in the February second week patch release which is expected to be rolled out on 11th February 2020. We appreciate your patience until then.  
 
You can now track the reported issue from the below feedback link,  
 
 
Regards,  
Sureshkumar P 


Loader.
Live Chat Icon For mobile
Up arrow icon