Общий метод и передача любого перечисления в качестве параметра - PullRequest
0 голосов
/ 30 января 2012

All

Я пытаюсь разобраться со своими последними битами в Enum-фреймворке.

Моя цель: я хочу отправить любой тип enum, преобразовать его в список и связать с раскрывающимся списком. я буду использовать ObjectDataSource в качестве DataSource для данного выпадающего списка. Я хочу создать составной элемент управления, который принимает только один параметр; тип enum. Составной элемент управления сортирует привязку данных и все остальные биты и биты.

Теперь единственная проблема, которую я имею, - преобразовать универсальный метод в совместимый с ObjectDataSource.

Вот код моего текущего метода, который мне нужно использовать в моем ObjectDataSource. Итак, этот метод работает нормально и возвращает список элементов для типа Enum WeekDays. Однако мне нужна та же функциональность, но мне нужно заменить WeekDays любым типом enum.

Код:

public class DropDownData
{

    public EnumDataItemList GetList()
    {
        EnumDataItemList items = new EnumDataItemList();

        foreach (int value in Enum.GetValues(WeekDays))
        {
            EnumDataItem item = new EnumDataItem();

            WeekDays d = (WeekDays)value;

            //Set display text
            if (!string.IsNullOrEmpty(DataHandlers.GetAttributeValue<DisplayTextAttribute, string>(d)))
            {
                //Translation logic goes here
                item.Text = DataHandlers.GetAttributeValue<DisplayTextAttribute, string>(d);
            }
            else
            {
                //Translation logic goes here
                item.Text = Enum.GetName(typeof(WeekDays), value);  
            }

            item.Value = value; //Actual value
            item.ToolTip = DataHandlers.GetAttributeValue<ToolTipAttribute, string>(d);
            item.Description = DataHandlers.GetAttributeValue<Lia.Library.Enums.CustomAttributes.DescriptionAttribute, string>(d);
            item.HelpText = DataHandlers.GetAttributeValue<HelpTextAttribute, string>(d);
            item.ExcludeOnBinding = DataHandlers.GetAttributeValue<ExcludeOnBinding, bool>(d);

            if (!item.ExcludeOnBinding)
            {
                items.Add(item);                    
            }
        }
        return items;
    }

}

public class EnumDataItemList : List<EnumDataItem>
{

}

Насколько я знаю, я не могу использовать универсальный метод с ObjectDataSOurce, но универсальный класс в порядке. Я просто не могу заставить его работать с общим классом, и вся помощь очень ценится. Когда все заработает, я буду рад поделиться полным решением.

Я использую Framework 2.0.

Ответы [ 3 ]

3 голосов
/ 30 января 2012

Это должно помочь вам.(Выдает исключение, если T не является типом перечисления.)

public static EnumDataItemList GetList<T>() where T : struct
{
    EnumDataItemList items = new EnumDataItemList();
    foreach (int e in Enum.GetValues(typeof(T)))
    {
       EnumDataItem item = new EnumDataItem();
       item.Text = Enum.GetName(typeof(T), e);
       item.Value = e;
    }
  //Rest of code goes here
}

Использование:

EnumDataItemList days = GetList<WeekDays>();

, если вы не хотите использовать универсальный метод, вы можете изменить его на:

public static EnumDataItemList GetList(Type t)
{
        EnumDataItemList items = new EnumDataItemList();
        foreach (int e in Enum.GetValues(t))
        {
           EnumDataItem item = new EnumDataItem();
           item.Text = Enum.GetName(t, e);
           item.Value = e;
        }
      //Rest of code goes here
}
2 голосов
/ 30 января 2012

Альтернатива Магнусу, но идея почти такая же (просто не хотел выбрасывать ее после удара ;-)) - просто перебирает значение enum, а не int.То же использование:

public static class DropDownData
{
    // struct, IComparable, IFormattable, IConvertible is as close as we'll 
    // get to an Enum constraint. We don't actually use the constraint for 
    // anything except rudimentary compile-time type checking, though, so 
    // you may leave them out.
    public static EnumDataItemList GetList<T>() 
            where T : struct, IComparable, IFormattable, IConvertible
    {
        // Just to make the intent explicit. Enum.GetValues will do the
        // type check, if this is left out:
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Type must be an enumeration");
        }

        EnumDataItemList items = new EnumDataItemList();

        foreach (Enum e in Enum.GetValues(typeof(T)))
        {
            EnumDataItem items = new EnumDataItem();

            // Note: This assumes the enum's underlying type is
            // assignable to Int32 (for example, not a long):
            int value = Convert.ToInt32(e);

            // The same attribute retrieval code as in the 
            // WeekDays example, including:
            item.Text = e.ToString(); // e is Enum here, no need for GetName
        }
    }
}
0 голосов
/ 10 июня 2016

Кажется, я решил эту проблему немного по-другому и придумал что-то довольно лаконичное, что, похоже, работает для меня.Я не могу претендовать на это как на оригинальную работу, так как не помню, нашел ли я ее и скопировал ли я, или собрал ее из кусочков и кусочков, которые я нашел, с какой-то моей собственной оригинальной работой.Я добавил метод расширения для перечислений, который дает мне функцию ToDisplayText для получения моего пользовательского атрибута перечисления с тем же именем.

    this.ddlBlah.DataSource =
      Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
      .ToDictionary(x => x, x => x.ToDisplayText());
    this.ddlBlahs.DataValueField = "key";
    this.ddlBlah.DataTextField = "value";
    this.ddlBlah.DataBind();


public static string ToDisplayText(this Enum Value)
{
  try
  {
    Type type = Value.GetType();
    MemberInfo[] memInfo = type.GetMember(Value.ToString());

    if (memInfo != null && memInfo.Length > 0)
    {
      object[] attrs = memInfo[0].GetCustomAttributes(
                                    typeof(DisplayText),
                                    false);
      if (attrs != null && attrs.Length > 0)
        return ((DisplayText)attrs[0]).DisplayedText;
    }
  }
  catch (Exception ex)
  {
    throw new Exception("Your favorite error handling here");
  }
  return Value.ToString();

  // End of ToDisplayText()
}


[System.AttributeUsage(System.AttributeTargets.Field)]
public class DisplayText : System.Attribute
{
  public string DisplayedText;

  public DisplayText(string displayText)
  {
    DisplayedText = displayText;
  }

  // End of DisplayText class definition
}
...