Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DataBindings для ComboBox, связывание ComboBox и enum 
V
    Опции темы
VID
Дата 12.1.2006, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



Привет всем!

Каким образом можно "связать" ComboBox с инстансом типа enum, чтоб отображать все возможные элементы перечисления и чтоб при выборе пользователем оного оно прописывалось в инстанс перечиления? Чтоб не создавать обратной связи между перечислением и ComboBox?
PM MAIL   Вверх
mr.DUDA
Дата 12.1.2006, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Во-первых, набор элементов enum'а не изменяется в рантайме, так что делать binding на элементы не имеет смысла. И что означает "инстанс перечисления"? Объект типа enum с выбранным в combobox'е значением?
Код
    public class Form1 : System.Windows.Forms.Form
    {
        public enum TestEnum
        {
            Alpha,
            Beta,
            Gamma,
            Delta
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad (e);

            this.comboBox1.Items.AddRange(Enum.GetNames(typeof(TestEnum)));
            this.comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            TestEnum result = (TestEnum) Enum.Parse(typeof(TestEnum), this.comboBox1.SelectedItem.ToString());
        }



--------------------
user posted image
PM MAIL WWW   Вверх
VID
Дата 13.1.2006, 07:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



Смысл идеи такой.
Существует класс SettingsManager позволяющий визуализировать по некоторому алгоритму некий класс Settings, то есть визуализировать свойства класса Settings.

В качестве параметра передается объект типа Settings (то есть инстанс класса Settings).
Парсим Settings через рефлексию типов и узнаем что там имеется свойство типа enum, логично предположить что контролом для такого типа может быть ComboBox. Вот и хочется привязать ComboBox и объект типа enum (инстанс перечисления класса Settings). Чтоб не создавать функций для обработки изменения значения в ComboBox'e.

Примерно такая идея smile
PM MAIL   Вверх
mr.DUDA
Дата 13.1.2006, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



А чем PropertyGrid не подходит? Он для таких целей и создавался, имхо.

Цитата(VID @ 13.1.2006, 06:01 Найти цитируемый пост)
Вот и хочется привязать ComboBox и объект типа enum (инстанс перечисления класса Settings). Чтоб не создавать функций для обработки изменения значения в ComboBox'e.

Можно забайндить св-во ComboBox.SelectedValue на объект перечисления, но тогда придётся задать DataSource для combobox'а и создать класс со свойствами, которые будут DisplayMember и ValueMember указанного DataSource. В примере внизу свойство MyEnumInstance байндится напрямую на значение TestEnum, выбранного в combobox'е:

Код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication3
{

    // тестовое перечисление
    [Flags]
    public enum TestEnum
    {
        Alpha = 1,
        Beta = 3,
        Gamma,
        Delta,
        Epsilon = 8,
        Zeta = Alpha | Gamma
    }

    /// <summary>
    /// Класс-элемент DataSource для ComboBox
    /// </summary>
    public class EnumElement<T>
    {
        private T val;
        public T Value
        {
            get { return val; }
            set { val = value; }
        }

        private string displayName;
        public string DisplayName
        {
            get { return displayName; }
            set { displayName = value; }
        }

        internal EnumElement(string displayName, T enumValue)
        {
            this.displayName = displayName;
            this.val = enumValue;
        }

        /// <summary>
        /// Возвращает список элементов перечисления в виде массива EnumElement
        /// </summary>
        public static EnumElement<T>[] GetElements()
        {
            Array enumValues = Enum.GetValues(typeof(T));
            string[] displayNames = Enum.GetNames(typeof(T));
            EnumElement<T>[] ret = new EnumElement<T>[enumValues.Length];
            for(int i = 0; i < enumValues.Length; i++)
                ret[i] = new EnumElement<T>(displayNames[i], (T)enumValues.GetValue(i));
            return ret;
        }
    }

    /// <summary>
    /// Тестовая форма
    /// </summary>
    public partial class Form1 : Form
    {
        TestEnum myEnumInstance;
        /// <summary>
        /// Объект перечисления, на который байндится comboBox1.SelectedValue
        /// </summary>
        public TestEnum MyEnumInstance
        {
            get
            {
                return myEnumInstance;
            }
            set
            {
                myEnumInstance = value;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // устанавливаем DataSource для comboBox1
            this.comboBox1.DataSource = EnumElement<TestEnum>.GetElements();
            this.comboBox1.ValueMember = "Value";
            this.comboBox1.DisplayMember = "DisplayName";

            // байндим comboBox1 на MyEnumInstance
            this.comboBox1.DataBindings.Add("SelectedValue", this, "MyEnumInstance");
        }



--------------------
user posted image
PM MAIL WWW   Вверх
VID
Дата 15.1.2006, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



Спасибо это уже более приемлемо.

А PropertyGrid не подходит ввиду его плохого понимания обычными пользователями.
ИМХО он логичен для программистов, но не user'ов ПО и состряпать с ним хороший SettingsManager не получиться.

Еще раз огромное спасибо!
PM MAIL   Вверх
VID
Дата 15.1.2006, 01:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



Немного инфы для будущих читателей...

Если заранее тип перечисления неизвестен, то есть будет известен только в рантайме,
то шаблоны использовать нельзя, тогда можно переделать класс EnumElement так:

Код

    /// <summary>    
    /// Element class is a DataSource for ComboBox control.
    /// </summary>
    public class EnumElement
    {
        private object _value;
        private string _displayName;

        /// <summary>
        /// Value of this enumeration element.
        /// </summary>
        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }

        /// <summary>
        /// Display name of this enumeration element in the control.
        /// </summary>
        public string DisplayName
        {
            get { return _displayName; }
            set { _displayName = value; }
        }

        /// <summary>
        /// Constructor of EnumElement class.
        /// </summary>
        /// <param name="displayName">
        /// Name of element which displayes in the control.
        /// </param>
        /// <param name="value">
        /// Value of enumeration element.
        /// </param>
        protected EnumElement(string displayName, object value)
        {
            _displayName = displayName;
            _value = value;
        }

        /// <summary>    
        /// Gets a list of enumeration elements.
        /// </summary>    
        /// <param name="enumType">
        /// Type of enumeration to retrieve.
        /// </param>
        /// <returns>
        /// Returns list of enumeration elements as array of EnumElement objects.
        /// </returns>
        public static EnumElement[] GetElements(Type enumType)
        {
            Array enumValues = Enum.GetValues(enumType);
            string[] displayNames = Enum.GetNames(enumType);
            EnumElement[] ret = new EnumElement[enumValues.Length];
            for (int i = 0; i < enumValues.Length; i++)
                ret[i] = new EnumElement(displayNames[i], enumValues.GetValue(i));
            return ret;
        }
    }


а вызов метода EnumElement.GetValue(Type t) осуществлять с использованием рефлексии типов, то есть:
Код

protected override void OnLoad(EventArgs e)    
        {
            base.OnLoad(e);
            // устанавливаем DataSource для comboBox1
            this.comboBox1.DataSource = EnumElement.GetElements(typeof (MyEnumInstance));
            this.comboBox1.ValueMember = "Value";
            this.comboBox1.DisplayMember = "DisplayName";
            // байндим comboBox1 на MyEnumInstance
            this.comboBox1.DataBindings.Add("SelectedValue", this, "MyEnumInstance");
        }

PM MAIL   Вверх
lovermann
Дата 15.1.2006, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 28.12.2004
Где: Прага

Репутация: 1
Всего: 8



Если тип заранее не известне, то нельзя ли здесь использовать generics?
PM WWW ICQ   Вверх
Exception
Дата 15.1.2006, 03:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



Если не известен, юзаем EnumElement<object>.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0472 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.