Click here to Skip to main content
15,867,704 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi Friends,

I Have created a generic class called DropDownListFiller<T>

In T I put an EntityClass that hold a variable called DataFromService
DataFromService is of IQueryable type.

How do I get SelectedEntity have the values of T.DataFromService?

In the below code SelectedEntity remains null and T is not type DropDownList

What I have tried:

C#
public class DropDownListFiller<T>
    {
        public T SelectedEntity;
        public virtual DropDownList LoadDropDownList(DropDownList ddl, bool AddChooseItem = true, string selectedValue = null, string OtherDataTextField = null)
        {
            
            try
            {
                ddl.DataSource = SelectedEntity.GetType().GetProperty("DataFromService");
                ddl.DataTextField = OtherDataTextField ?? SelectedEntity.GetType().GetProperty("DropDownListDataTextField").ToString();
                ddl.DataValueField = "Id";
                ddl.DataBind();
                if (AddChooseItem)
                    if (ddl.Items.Count > 0)
                        ddl.Items.Insert(0, new ListItem("Selecteer a.u.b.", "0"));
                    else
                        ddl.Items.Insert(0, new ListItem("Geen vrije keuze mogelijk", "0"));

                if (!string.IsNullOrWhiteSpace(selectedValue))
                {
                    MarinEntities.Logging.Log.AddMessage($"selectedValue: {selectedValue}");
                    try
                    {
                        ddl.SelectedValue = ddl.Items.FindByValue(selectedValue).Value;
                    }
                    catch
                    {
                        ddl.SelectedValue = ddl.Items.FindByText(selectedValue).Value;
                    }
                    MarinEntities.Logging.Log.AddMessage($"ddl.SelectedValue: {ddl.SelectedValue}");
                }
            }
            catch (Exception err)
            {
                SelectedEntity.GetType().GetProperty("LastException").SetValue(SelectedEntity, err);
                MarinEntities.Logging.Log.AddException(err);
            }
            return ddl;
        }
Posted
Updated 26-Feb-20 3:51am

1 solution

GetProperty returns a PropertyInfo; you need to call the GetValue method on that PropertyInfo, passing in the instance of the class, to get the actual value of the property.

But there's a much simpler solution: have your entity classes implement an interface, or inherit from a base class. Then add a type constraint to your generic type parameter, and get rid of all of the reflection.
C#
public interface IDropDownListProvider
{
    IEnumerable DataFromService { get; }
    string DropDownListDataTextField { get; }
    Exception LastException { set; }
}

public class DropDownListFiller<T> where T : IDropDownListProvider
{
    public T SelectedEntity { get; set; }
    
    public virtual DropDownList LoadDropDownList(DropDownList ddl, bool AddChooseItem = true, string selectedValue = null, string OtherDataTextField = null)
    {
        try
        {
            ddl.DataSource = SelectedEntity.DataFromService;
            ddl.DataTextField = OtherDataTextField ?? SelectedEntity.DropDownListDataTextField;
            ddl.DataValueField = "Id";
            ddl.DataBind();
            
            if (AddChooseItem)
            {
                if (ddl.Items.Count == 0)
                {
                    ddl.Items.Insert(0, new ListItem("Geen vrije keuze mogelijk", "0"));
                }
                else
                {
                    ddl.Items.Insert(0, new ListItem("Selecteer a.u.b.", "0"));
                }
            }
            
            if (!string.IsNullOrWhiteSpace(selectedValue))
            {
                MarinEntities.Logging.Log.AddMessage($"selectedValue: {selectedValue}");
                
                var selectedItem = ddl.Items.FindByValue(selectedValue) ?? ddl.Items.FindByText(selectedValue);
                if (selectedItem != null)
                {
                    ddl.ClearSelection();
                    selectedItem.Selected = true;
                }
                
                MarinEntities.Logging.Log.AddMessage($"ddl.SelectedValue: {ddl.SelectedValue}");
            }
        }
        catch (Exception err)
        {
            SelectedEntity.LastException = err;
            MarinEntities.Logging.Log.AddException(err);
        }
        
        return ddl;
    }
}
 
Share this answer
 
Comments
Herman<T>.Instance 27-Feb-20 14:37pm    
The type 'MARIN.DS.MarinEntities.Entities.MenuEntity' cannot be used as type parameter 'T' in the generic type or method 'ComboBoxFiller<t>'. There is no implicit reference conversion from 'MARIN.DS.MarinEntities.Entities.MenuEntity' to 'MARIN.DS.MarinEntities.Entities.IDataCollectionProvider<marin.ds.marinentities.entities.menuentity>'.


The Interface had to be:
public interface IDataCollectionProvider<t>
{
IQueryable<t> DataFromService { get; set; }
List<t> DataFromServiceList { get; }
string DropDownListDataTextField { get; }
Exception LastException { get; set; }
}

because T type holds the IQueryable data for the given Entity Framework poco

How to overcome this?
Richard Deeming 27-Feb-20 14:46pm    
The error suggests you're trying to pass in the MenuEntity class, rather than the class which provides the list of MenuEntity objects.

I'm not sure why you had to change the interface - both IQueryable<T> and List<T> implement the non-generic IEnumerable interface, so they should work for the DataFromService property.
Herman<T>.Instance 12-Mar-20 10:05am    
I have it working since begin march. What a GREAT solution. All kudos for you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900