Herman<T>.Instance Ответов: 1

Используйте источник данных из универсального класса в качестве источника для выпадающего списка


Привет Друзья,

Я создал универсальный класс под названием DropDownListFiller<T>

В T я помещаю EntityClass, который содержит переменную с именем DataFromService
DataFromService имеет тип IQueryable.

Как я могу получить SelectedEntity имеют значения, т. DataFromService?

В приведенном ниже коде SelectedEntity остается нулевым и T не является типом DropDownList

Что я уже пробовал:

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;
        }

1 Ответов

Рейтинг:
9

Richard Deeming

GetProperty возвращает PropertyInfo; вам нужно позвонить в GetValue метод на этом PropertyInfo, передавая экземпляр класса, чтобы получить фактическое значение свойства.

Но есть гораздо более простое решение: пусть ваши классы сущностей реализуют интерфейс или наследуют от базового класса. Затем добавьте ограничение типа к вашему параметру универсального типа и избавьтесь от всех отражений.

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;
    }
}


Herman&lt;T&gt;.Instance

Тип 'MARIN.DS.MarinEntities.Сущности.MenuEntity' не может использоваться в качестве параметра типа 'T' в универсальном типе или методе 'ComboBoxFiller<t>'. Неявное преобразование ссылок из 'MARIN.DS.MarinEntities отсутствует.Сущности.MenuEntity' to 'MARIN.DS.MarinEntities.Сущности.IDataCollectionProvider<marin.ds.marinentities.entities.menuentity>'.


Интерфейс должен был быть:
публичный интерфейс IDataCollectionProvider<t>
{
IQueryable<t> DataFromService { get; set; }
List<t> DataFromServiceList { get; }
строка DropDownListDataTextField { get; }
Исключение LastException { get; set; }
}

потому что тип T имеет интерфейс IQueryable данные по данному объекту рамках Роко

Как это преодолеть?

Richard Deeming

Ошибка предполагает, что вы пытаетесь пройти в MenuEntity класс, а не класс, который предоставляет список MenuEntity объекты.

Я не совсем понимаю, зачем вам понадобилось менять интерфейс - и то, и другое IQueryable<T> и List<T> реализуйте не-универсальные IEnumerable интерфейс, поэтому они должны работать на DataFromService собственность.

Herman&lt;T&gt;.Instance

У меня он работает с начала марта. Какое замечательное решение. Вся слава тебе.