Добавление ListItems в DropDownList из общего списка

У меня есть этот aspx-код: (образец)

<asp:DropDownList runat="server" ID="ddList1"></asp:DropDownList>   

С помощью этого кода:

List<System.Web.UI.WebControls.ListItem> colors = new List<System.Web.UI.WebControls.ListItem>();
colors.Add(new ListItem("Select Value", "0"));
colors.Add(new ListItem("Red", "1"));
colors.Add(new ListItem("Green", "2"));
colors.Add(new ListItem("Blue", "3"));
ddList1.DataSource = colors;
ddList1.DataBind();

Результат выглядит так:

<select name="ddList1" id="ddList1">
    <option value="Select Value">Select Value</option>
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>   

Мой вопрос: почему мои значения (числа) исчезли, а текст использовался как значение И текст? Я знаю, что это работает, если я использую метод ddList1.Items.Add(New ListItem("text", "value")), но мне нужно использовать общий список в качестве источника данных по другим причинам.


person Espo    schedule 25.09.2008    source источник


Ответы (4)


Поскольку метод DataBind связывает значения, только если установлено свойство DataValueField. Если вы установите для свойства DataValueField значение «Value» перед вызовом DataBind, ваши значения появятся в разметке.

ОБНОВЛЕНИЕ: вам также необходимо установить для свойства DataTextField значение «Text». Это связано с тем, что привязка данных и добавление элементов вручную не работают одинаково. Привязка данных не знает о существовании типа ListItem и создает разметку, оценивая элементы в источнике данных.

person Serhat Ozgel    schedule 25.09.2008
comment
Зачем мне нужно устанавливать это поле? Как я уже сказал, это работает, когда ListItem добавляется непосредственно в коллекцию DropDownList.Items. Я попробовал ваше предложение, и это не помогло. См. Мой обновленный вопрос. - person Espo; 25.09.2008

А вот и метод, который выполняет привязку данных. Вы можете точно видеть, что происходит:

protected internal override void PerformDataBinding(IEnumerable dataSource)
{
    base.PerformDataBinding(dataSource);
    if (dataSource != null)
    {
        bool flag = false;
        bool flag2 = false;
        string dataTextField = this.DataTextField;
        string dataValueField = this.DataValueField;
        string dataTextFormatString = this.DataTextFormatString;
        if (!this.AppendDataBoundItems)
        {
            this.Items.Clear();
        }
        ICollection is2 = dataSource as ICollection;
        if (is2 != null)
        {
            this.Items.Capacity = is2.Count + this.Items.Count;
        }
        if ((dataTextField.Length != 0) || (dataValueField.Length != 0))
        {
            flag = true;
        }
        if (dataTextFormatString.Length != 0)
        {
            flag2 = true;
        }
        foreach (object obj2 in dataSource)
        {
            ListItem item = new ListItem();
            if (flag)
            {
                if (dataTextField.Length > 0)
                {
                    item.Text = DataBinder.GetPropertyValue(obj2, dataTextField, dataTextFormatString);
                }
                if (dataValueField.Length > 0)
                {
                    item.Value = DataBinder.GetPropertyValue(obj2, dataValueField, null);
                }
            }
            else
            {
                if (flag2)
                {
                    item.Text = string.Format(CultureInfo.CurrentCulture, dataTextFormatString, new object[] { obj2 });
                }
                else
                {
                    item.Text = obj2.ToString();
                }
                item.Value = obj2.ToString();
            }
            this.Items.Add(item);
        }
    }
    if (this.cachedSelectedValue != null)
    {
        int num = -1;
        num = this.Items.FindByValueInternal(this.cachedSelectedValue, true);
        if (-1 == num)
        {
            throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
        }
        if ((this.cachedSelectedIndex != -1) && (this.cachedSelectedIndex != num))
        {
            throw new ArgumentException(SR.GetString("Attributes_mutually_exclusive", new object[] { "SelectedIndex", "SelectedValue" }));
        }
        this.SelectedIndex = num;
        this.cachedSelectedValue = null;
        this.cachedSelectedIndex = -1;
    }
    else if (this.cachedSelectedIndex != -1)
    {
        this.SelectedIndex = this.cachedSelectedIndex;
        this.cachedSelectedIndex = -1;
    }
}
person Serhat Ozgel    schedule 25.09.2008
comment
Спасибо. Я думаю, что иметь Text и Value в качестве свойств по умолчанию - это хорошая идея. - person Espo; 25.09.2008

Если вы создаете ListItems, вам вообще не нужно использовать DataBind ().

Просто добавьте их в свой DropDownList:



ddList1.Items.Add(new ListItem("Select Value", "0"));
ddList1.Items.Add(new ListItem("Red", "1"));
ddList1.Items.Add(new ListItem("Green", "2"));
ddList1.Items.Add(new ListItem("Blue", "3"));

DataBind () полезен, когда у вас уже есть коллекция / объект данных (обычно DataTable или DataView), который можно использовать в качестве источника данных, установив DataTextField и DataValueField (как писал buyutec).

person Filini    schedule 25.09.2008
comment
Спасибо за ваш комментарий, даже если он не ответил согласно его последнему предложению. Я не понимал, что это все, что мне нужно было сделать. - person Bryan; 19.03.2013

«Если вы создаете ListItems, вам вообще не нужно использовать DataBind ()».

Добавление непосредственно в раскрывающийся список - простой способ (и, учитывая пример кода, правильный), но, допустим, у вас есть неупорядоченный источник данных и вы хотите, чтобы элементы списка были отсортированы.

Один из способов добиться этого - создать общий список ListItem, а затем использовать унаследованный метод сортировки перед привязкой данных к списку.

Есть много способов снять шкуру с кошки ...

person Community    schedule 03.06.2009