DropDownList AppendDataBoundItems (первый элемент должен быть пустым и без дубликатов) - PullRequest
35 голосов
/ 08 апреля 2009

У меня есть DropDownList внутри UpdatePanel, который заполняется при обратной передаче от SqlDataSource. У него есть параметр, который является другим элементом управления. Иногда мне нужно несколько постбэков, но происходит то, что каждый раз, когда обновляется панель обновления, элементы добавляются в DropDownList. Таким образом, DropDownList в конечном итоге имеет неверные данные или повторные данные.

У меня есть свойство AppendDataBoundItems, установленное на true, потому что мне нужно, чтобы первый элемент был пустым.

Как я могу преодолеть эту проблему? Есть ли другой способ получить пустой первый элемент?

(Этот DropDownList находится в веб-приложении ASP.NET 2.0, а код позади - на C #)

Ответы [ 7 ]

62 голосов
/ 08 апреля 2009

Вместо использования AppendDataboundItems='true' (что приведет к проблеме, о которой вы говорите), ответьте на событие DataBound для DropDownList, а затем добавьте свой «пустой» элемент в начало списка.

<asp:DropDownList runat="server" ID="MyList"
  ondatabound="MyListDataBound"></asp:DropDownList>

Тогда в вашем коде позади:

protected void MyListDataBound(object sender, EventArgs e)
{
    MyList.Items.Insert(0, new ListItem("- Select -", ""));
}
5 голосов
/ 22 июля 2015

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

Во-первых, мы должны понять AppendDataBoundItems. Если AppendDataBoundItems = "true", ListItems добавляются к DropDownList без очистки старых. В противном случае DropDownList очищается перед следующим DataBind. MSDN AppendDataBoundItems doc

В основном ответы охватывают 2 варианта:

1. Определите пустую опцию в html и добавьте ListItems из базы данных в DropDownList только один раз.

Обратите внимание на 3 вещи здесь:

  • Пробел ListItem определен в html
  • AppendDataBoundItems="true"
  • DataBind НЕ вызывается на обратных передачах или когда элемент DropDownList количество> 1

Источник:

<asp:DropDownList ID="MyList" runat="server" AppendDataBoundItems="true" DataValueField="Id" DataTextField="Name" >
    <asp:ListItem Text="- Select One -" Value="" />
</asp:DropDownList>

Код позади:

protected void Page_Load(object sender, System.EventArgs e)
{
    if (MyList.Items.Count <= 1 ) {
        MyList.DataSource = MyDataSource;
        MyList.DataBind();
    }
}

Примечание: мне нравится логика проверки счета против проверки IsPostBack. Хотя PostBacks часто являются причиной дублирования привязки данных, это может быть вызвано другими способами. Проверка количества элементов - это просто проверка того, загружен ли он уже.

ИЛИ (можно использовать IsPostBack вместо)

protected void Page_Load(object sender, System.EventArgs e)
{
    if (!IsPostBack) {
        MyList.DataSource = MyDataSource;
        MyList.DataBind();
    }
}

2. Очистите и перезагрузите DropDownList при каждом обновлении страницы.

Обратите внимание на 3 отличия от первого варианта:

  • AppendDataBoundItems="false" (если он не определен, то false это значение по умолчанию)
  • Пробел ListItem добавляется в коде позади. Мы не можем определить это в HTML потому что с AppendDataBoundItems="false" это будет очищено.
  • DataBind вызывается на каждый Page_Load

Источник:

<asp:DropDownList ID="MyList" runat="server" DataValueField="Id"  DataTextField="Name" 
    OnDataBound="MyList_DataBound" >
</asp:DropDownList>

Код:

protected void Page_Load(object sender, System.EventArgs e)
{
    MyList.DataSource = MyDataSource;
    MyList.DataBind();
}

protected void MyList_DataBound(object sender, EventArgs e)
{
    MyList.Items.Insert(0, new ListItem("- Select One -", ""));
}
4 голосов
/ 21 декабря 2009

Вы, вероятно, связываете этот DropDownList в коде позади. Таким образом, вы не должны делать это после обратной передачи снова:

// probably in Page_Load method
if (!Page.IsPostBack)
{
    // do data binding here
};
3 голосов
/ 27 декабря 2010

Вот идея, мы можем использовать 2 события: DataBound и DataBinding :

protected void MyListDataBound(object sender, EventArgs e)
{
  MyList.Items.Insert(0, new ListItem("- Select -", ""));
}

protected void MyListDataBinding(object sender, EventArgs e)
{
  MyList.Items.Items.Clear();
}
0 голосов
/ 22 июля 2017

Просто добавьте EnableViewState = "false" к раскрывающемуся тегу

<asp:DropDownList runat="server" ID="DropDownList1" DataSourceID="SqlDataSource" 
DataTextField="Name" DataValueField="ID" EnableViewState="false" 
AppendDataBoundItems="true">
    <asp:ListItem Value="">Select</asp:ListItem>
</asp:DropDownList>
0 голосов
/ 23 июля 2010

Вот идея.

В раскрывающемся списке есть свойство с именем AutoPostBack, установите его в значение true, а затем в коде позади вы поместите весь метод привязки внутри if(!Page.IsPostBack). Это сработало для меня.

С уважением.

0 голосов
/ 05 апреля 2010
<asp:DropDownList ID="DropDownList1" AppendDataBoundItems="true" runat="server"
  DataSourceID="SqlDataSource1" DataTextField="state" DataValueField="state">
    <asp:ListItem Text="(Select a State)" Value="" />
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
  ConnectionString="<%$ ConnectionStrings:pubsConnectionString %>"
  SelectCommand="SELECT DISTINCT [state] FROM [authors]">
</asp:SqlDataSource>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...