Использование комбинированного окна Windows Forms со списком <KeyValuePair <UserEnum, String >> в качестве источника данных - C # - PullRequest
1 голос
/ 18 декабря 2009

В настоящее время я работаю над графическим интерфейсом Windows Forms, и у меня есть Combo, который мне нужен для отображения списка строковых значений в качестве DisplayMembers и использования списка определенных пользователем значений enum в качестве ValueMember. В настоящее время я возвращаю List> из моей функции доступа к базе данных, и я хотел бы привязать это к моему Combo box. Я попытался присвоить список свойству .DataSource, назначив «Ключ» для .DataMember и «Значение» для .DisplayMember. Это явно недопустимый подход, так как он не работает.

Может кто-нибудь дать мне другой подход, который находится в хорошей форме и действительно работает?

Спасибо

Ответы [ 2 ]

4 голосов
/ 18 декабря 2009

Я использую свой собственный класс EnumPair<> в сочетании с двумя методами расширения, чтобы связать комбинированные списки со свойствами с типами enum.

Посмотрите, может ли это помочь вам, чтобы вы могли работать непосредственно с перечислениями.

Используйте это после реализации:

comboBox.BindToEnumValue<MyEnumType>(myBindingSourceInstance, "PropertyNameOfBindingSource");

Это предполагает, что в вашей форме есть ComboBox с именем "comboBox", Enum с именем "MyEnumType" и экземпляр BindingSource. PropertyNameOfBindingSource должен быть именем свойства типа, список которого имеет ваш BindingSource, с свойством PropertyType типа MyEnumType. Реализация фоновой работы приведена ниже, методы расширения не нужны, я просто не люблю писать практически идентичные строки кода; -)

public static class ComboBoxExtensions
{
    public static void BindToEnumValue<TEnum>(this ComboBox cbo, BindingSource bs, string propertyName)
    {
        cbo.DataSource = EnumPair<TEnum>.GetValuePairList();
        cbo.ValueMember = EnumPair<TEnum>.ValueMember;
        cbo.DisplayMember = EnumPair<TEnum>.DisplayMember;
        cbo.DataBindings.Add(new Binding("SelectedValue", bs, propertyName));
    }

    public static void BindClear(this ComboBox cbo)
    {
        cbo.DataSource = null;
        cbo.DataBindings.Clear();
    }
}

/// <summary>
/// Represents a <see cref="EnumPair"/> consisting of an value 
/// of an enum T and a string represantion of the value.
/// </summary>
/// <remarks>
/// With this generic class every <see cref="Enum"/> can be
/// dynamically enhanced by additional values, such as an empty
/// entry, which is usefull in beeing used with 
/// <see cref="ComboBox"/>es.
/// </remarks>
/// <typeparam name="T">The type of the <see cref="Enum"/> to represent.</typeparam>
public partial class EnumPair<T>
{
    #region Constants

    public const string ValueMember = "EnumValue";
    public const string DisplayMember = "EnumStringValue";

    #endregion

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="EnumPair"/> class.
    /// </summary>
    public EnumPair()
    {
        Type t = typeof(T);
        if (!t.IsEnum)
        {
            throw new ArgumentException("Class EnumPair<T> can only be instantiated with Enum-Types!");
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="EnumPair"/> class.
    /// </summary>
    /// <param name="value">The value of the enum.</param>
    /// <param name="stringValue">The <see cref="string"/> value of the enum.</param>
    public EnumPair(T value, string stringValue)
    {
        Type t = typeof(T);
        if (!t.IsEnum)
        {
            throw new ArgumentException("Class EnumPair<T> can only be instantiated with Enum-Types!");
        }

        this.EnumValue = value;
        this.EnumStringValue = stringValue;
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets the value part of the <see cref="EnumPair"/>.
    /// </summary>
    public T EnumValue { get; set; }

    /// <summary>
    /// Gets or sets the string value of the <see cref="EnumPair"/>.
    /// </summary>
    public string EnumStringValue { get; set; }

    #endregion

    #region Methods

    /// <summary>
    /// Returns a <see cref="string"/> that represents the current <see cref="EnumPair"/>.
    /// </summary>
    public override string ToString()
    {
        return this.EnumStringValue;
    }

    /// <summary>
    /// Generates a <see cref="List<T>"/> of the values
    /// of the <see cref="Enum"/> T.
    /// </summary>
    public static List<EnumPair<T>> GetValuePairList()
    {
        List<EnumPair<T>> list = new List<EnumPair<T>>();
        EnumPair<T> pair = new EnumPair<T>();

        foreach (var item in Enum.GetValues(typeof(T)))
        {
            pair = new EnumPair<T>();
            pair.EnumValue = (T)item;
            pair.EnumStringValue = ((T)item).ToString();
            list.Add(pair);
        }

        return list;
    }

    /// <summary>
    /// Implicit conversion from enum value to <see cref="EnumPair<>"/> from that enum.
    /// </summary>
    /// <param name="e">The enum value to convert to.</param>
    /// <returns>A <see cref="EnumPair<>"/> to the enum value.</returns>
    public static implicit operator EnumPair<T>(T e)
    {
        Type t = typeof(EnumPair<>).MakeGenericType(e.GetType());
        return new EnumPair<T>((T)e, ((T)e).ToString());
    }

    #endregion
}
0 голосов
/ 13 сентября 2011

Вы можете попробовать что-то вроде этого:

ddTemplates.DataSource =
  Enum.GetValues(typeof(EmailTemplateType))
  .Cast<EmailTemplateType>().ToList()
  .Select(v => new KeyValuePair<int, string>((int)v, v.ToString())).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...