Почему моя UpdatePanel не обновляет мой список, как я ожидаю, при нажатии кнопки?

У меня есть форма с раскрывающимся списком, двумя кнопками и двумя списками внутри UpdatePanel. Выпадающий список и списки привязаны к SqlDatasources. Выпадающий список позволяет вам выбрать свой отдел.

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

Второй список показывает обратный список этих элементов. (Вакансии в базе данных, не связанные с вашим отделом)

Когда элемент удаляется из 1-го списка, он должен отображаться во 2-м списке. Когда элемент удаляется из второго списка, он должен отображаться в первом списке.

Эта функция позволяет вам добавлять и удалять вакансии из вашего отдела.

Две кнопки на странице функционируют как кнопки «Добавить» и «Удалить». Все работает, за исключением того, что списки не будут надежно обновляться. Сами данные обновляются в базе данных, и если я обновлю (F5), они будут отображаться правильно.

<asp:ScriptManager ID="smgrDeptsJobs" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="uPanelDeptsJobs" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlDepartments" runat="server" 
            DataSourceID="sqldsDepartments" DataTextField="Department" 
            DataValueField="DeptID" Width="150px" AutoPostBack="True">
        </asp:DropDownList>

        <asp:ListBox ID="lstJobsIn" runat="server" DataSourceID="sqldsJobsIn" 
            DataTextField="JobName" DataValueField="JobID" height="156px" 
            width="220px">
        </asp:ListBox>

        <asp:Button ID="btnAddJob" runat="server" Text="&lt;&lt;" Width="70px" 
            CausesValidation="False" />

        <asp:Button ID="btnRemoveJob" runat="server" Text="&gt;&gt;" Width="70px" 
            CausesValidation="False" />

        <asp:ListBox ID="lstJobsOut" runat="server" DataSourceID="sqldsJobsOut" 
            DataTextField="JobName" DataValueField="JobID" height="156px" 
            width="220px">
        </asp:ListBox>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="ddlDepartments" 
            EventName="SelectedIndexChanged" />
        <asp:AsyncPostBackTrigger ControlID="btnAddJob" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="btnRemoveJob" EventName="Click" />
    </Triggers>
</asp:UpdatePanel>

Код для двух событий нажатия кнопки приведен ниже:

Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdInsert.CommandText = _
        "INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
        "(@DeptID, @JobID)"

    ' Declare the data types for the parameters
    sqlCmdInsert.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdInsert.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdInsert.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdInsert.Parameters("@JobID").Value = lstJobsOut.SelectedValue

    ' Execute the insert Statement
    sqlCmdInsert.ExecuteNonQuery()

    sqlJobsDB.Close()

End Sub

Protected Sub btnRemoveJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdDelete As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdDelete.CommandText = _
        "DELETE FROM tblDeptsJobs WHERE tblDeptsJobs.DeptID = @DeptID AND tblDeptsJobs.JobID = @JobID"

    ' Declare the data types for the parameters
    sqlCmdDelete.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdDelete.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdDelete.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdDelete.Parameters("@JobID").Value = lstJobsIn.SelectedValue

    ' Execute the insert Statement
    sqlCmdDelete.ExecuteNonQuery()

    sqlJobsDB.Close()

End Sub

Такое ощущение, что когда я добавляю или удаляю задание, список, в котором я последний раз выбрал элемент, не обновляется.

Я также не могу заставить раскрывающийся список обновлять списки, не устанавливая для автоматической отправки в раскрывающемся списке значение True.

Уродливое исправление Band-Aid, которое я придумал, использует метод listbox.items.clear(), а затем перепривязывает данные для каждого списка.


person Lucretius    schedule 29.07.2011    source источник
comment
Можете ли вы добавить код на стороне сервера для асинхронных обратных передач?   -  person Becuzz    schedule 29.07.2011
comment
Если вы не женаты на UpdatePanel, я бы предложил просто сделать это с помощью javascript/jQuery и веб-методов. У меня всегда были головные боли с панелями ASP Update.   -  person Dan    schedule 29.07.2011
comment
@Becuzz Насколько я понимаю, обработчик на стороне сервера для асинхронных обратных передач — это ScriptManager. ‹asp:ScriptManager ID=smgrDeptsJobs runat=server› ‹/asp:ScriptManager›   -  person Lucretius    schedule 29.07.2011
comment
@Lucretius Я имею в виду функции, которые вызываются на сервере. Например, какая функция/код запускается, когда я нажимаю btnAddJob? btnAddJob_Click? (Именно здесь я предполагаю, что вы вносите изменения в свою базу данных.) Это будет полезно.   -  person Becuzz    schedule 29.07.2011
comment
@Becuzz Понятно, сейчас добавлю. Один оператор вставки, другой оператор удаления. Примечание. Я еще не закодировал обработку исключений, например, если кто-то попытается добавить одну и ту же запись дважды (просто двойным щелчком), это сломает ее.   -  person Lucretius    schedule 29.07.2011
comment
Я вижу, что списки привязаны к источникам данных SQL (я предполагаю). Где они находятся на вашей странице? Не похоже, что они находятся в панели обновлений.   -  person Becuzz    schedule 29.07.2011
comment
Их нет на панели обновлений, они внизу страницы.   -  person Lucretius    schedule 30.07.2011


Ответы (2)


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

Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdInsert.CommandText = _
        "INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
        "(@DeptID, @JobID)"

    ' Declare the data types for the parameters
    sqlCmdInsert.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdInsert.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdInsert.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdInsert.Parameters("@JobID").Value = lstJobsOut.SelectedValue

    ' Execute the insert Statement
    sqlCmdInsert.ExecuteNonQuery()

    sqlJobsDB.Close()

    //may need to do explicit call to DB to get data here
    //after you have the data, rebind
    lstJobsIn.DataBind();
    lstJobsOut.DataBind();
End Sub

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

person Becuzz    schedule 01.08.2011
comment
Вот что я в итоге сделал (отредактировал свой первый пост). Я не знаю, было ли это необходимо или нет, но я сделал .clear() в обоих этих списках до .DataBind(), и теперь они работают правильно. Списки, вероятно, нуждаются только в .clear(), если у вас есть свойство изменить элементы с привязкой к данным, установленное на true. - person Lucretius; 03.08.2011

Просто установите для autopostback раскрывающегося списка значение true, удалите все триггеры и установите ChildrenAsTriggers="true" на панели обновлений.

person Yuriy Rozhovetskiy    schedule 29.07.2011
comment
На снимке экрана я выбрал «Техническое обслуживание» в раскрывающемся списке отделов. Я попытался переместить задание Mixer из списка справа в список слева. Он отображается слева, но не удаляется из списка справа. i53.tinypic.com/35i4srb.png Если я обновлю страницу вручную (F5), она удаляется из списка справа. - person Lucretius; 29.07.2011
comment
Можете ли вы поместить свои элементы управления DataSource в ту же панель UpdatePanel? - person Yuriy Rozhovetskiy; 30.07.2011
comment
Пробовал, не получилось. Сами данные изменяются в базе данных, поэтому их обновление не поможет обновить списки. - person Lucretius; 31.07.2011