ASP.NET WebForms DropDownList привязка данных странное поведение? - PullRequest
5 голосов
/ 25 января 2012

Резюме

Я загружаю города из контекста данных в два разных списка и связываю их с соответствующими элементами управления DropDownList.

Хотя код одинаков для обоих, и отличаются только данные и, очевидно, имя элементов управления, привязка данных не работает должным образом только для одного из них. Вместо отображения названия города отображается его идентификатор, то есть только для первого варианта!

Код-за

У нас есть два элемента управления DropDownList:

  1. DestinationDropDownList;
  2. OriginDropDownList.

Затем я их заселяю.

public partial class MyControl : UserControl {
    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            var instruction = new City() {
                CityId = Guid.Empty,
                CityName = "- Select a city -"
            };

            var destinations = context.Cities.ToList();
            destinations = destinations.OrderBy(c => c.CityName).ToList();
            destinations.Insert(0, instruction);
            DestinationDropDownList.DataSource = destinations;
            DestinationDropDownList.DataTextField = "CityName";
            DestinationDropDownList.DataValueField = "CityId";
            DestinationDropDownList.DataBind();

            var origins = context.Cities.ToList();
            origins = origins.OrderBy(c => c.CityName).ToList();
            origins.Insert(0, instruction);
            OriginDropDownList.DataSource = origins;
            OriginDropDownList.DataTextField = "CityName";
            OriginDropDownList.DataValueField = "CityId";
            OriginDropDownList.DataBind();
        }
    }
    private static readonly MyDataContext context = new MyDataContext();
}

HTML

<asp:DropDownList ID="DestinationDropDownList" runat="server" />
<asp:DropDownList ID="OriginDropDownList" runat="server" />

Отображение данных

*DestinationDropwDownList*
    - 0000-0000-0000-0000-0000 (empty Guid)
    - CityName 01
    - CityName 02
    - ...

*OriginDropDownList*
    - - Select a city -
    - CityName 01
    - CityName 02
    - ...

Правильное отображение отображается с помощью OriginDropDownList. Почему DestinationDropDownList отображает данные некорректно, то есть для первого и только первого элемента в списке !? Я совсем не понимаю и потерял несколько часов, пытаясь найти решение! = (

  1. Я пытался удалить первый элемент перед вставкой инструкции;
  2. Я дважды пытался вставить инструкцию, затем удалить первую;
  3. Я пытался следовать методу DropDownList.Items.Add(string), и он ничего не отображал, как в первом ряду, вместо пустого Guid.

Вопросы

  1. Встречались ли когда-либо такие проблемы с элементом управления DropDownList?
  2. Как исправить это поведение!?

РЕДАКТИРОВАТЬ # 1

michielvoo * Ответ 1080 * помог мне найти новый способ привязки данных к инструкции. Через его код найден обходной путь:

<asp:DropDownList ID="DestinationDropDownList" runat="server"
                  AppendDataBoundItems="true"
                  CssClass="required">
    <asp:ListItem Value="- Select a city -" />
</asp:DropDownList>

удаление инструкции вставки из кода только для этого самого DropDownList. Теперь он отображает именно то, что я хотел с самого начала.

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

РЕДАКТИРОВАТЬ # 2

С помощью кода, указанного в ответе michielvoo, он полностью решил проблему, с которой я столкнулся, когда DropDownList отображал свойство ListItem.Value вместо свойства ListITem.Text только и только для первого элемента в списке. Я не знаю, что не так с другими способами, но этот работает отлично!

Спасибо, michielvoo!

Спасибо вам всем за поддержку! =) * +1107 *

1 Ответ

7 голосов
/ 25 января 2012

Я не сталкивался с этой проблемой раньше, но постараюсь ответить на ваш второй вопрос.Я не вижу особой ценности в добавлении первого «учебного» элемента через код (поправьте меня, если я ошибаюсь).Я бы предпочел добавить его непосредственно к разметке:

<asp:DropDownList ID="DestinationDropwDownList" runat="server"
  AppendDataBoundItems="true"
  DataTextField="CityName"
  DataTextField="CityId">
  <asp:ListItem Text="- Select a city -" />
</asp:DropDownList>

Первый элемент переживет привязку данных благодаря использованию атрибута AppendDataBoundItems.Я также добавил атрибуты DataTextField и DataValueField, вы также можете удалить их из кода.

Еще одна вещь, которую вы можете сделать перед привязкой данных, это проекция сущностей на ListItem экземпляры:

DestinationDropDownList.DataSource = 
  from d in destinations
  select new ListItem() {
    Text = d.CityName,
    Value = d.CityId.ToString()
  };
DestinationDropDownList.DataBind();

Таким образом, вам не нужно устанавливать свойства DataTextField или DataValueField для элемента управления, поскольку вы уже сами создаете элементы списка.

...