__doPostBack() не запускается, если выпадающий выбранный индекс совпадает

У меня есть два раскрывающихся списка ddlCountry и ddlState и одна кнопка «Отправить».
Пока ddlstate находится на панели обновления.
При отправке значения кнопки обоих раскрывающихся списков сохраняется в базе данных.
И я показываю данные в Repeater Control.( В структуре таблицы HTML) КОД ASPX

<table id="tablelist" class="csstablelist" cellspacing="1" cellpadding="1">
                    <tr>
                        <td class="csstablelisttoptr">
                            ddlCountryID
                        </td>
                        <td class="csstablelisttoptr">
                            ddlCountryText
                        </td>
                        <td class="csstablelisttoptr">
                            ddlstateText
                        </td>
                    </tr>
                    <asp:Repeater ID="repeaterList" runat="server" OnItemDataBound="repeaterList_ItemDataBound">
                        <ItemTemplate>
                            <tr onclick="selectRow(this);">
                                <td class="csstablelisttd" style="display: none">
                                    <asp:Label ID="ddlCountryID" runat="server" Text='<%#Eval("ddlCountryID")%>'></asp:Label>
                                </td>
                                <td class="csstablelisttd">
                                    <asp:Label ID="ddlCountryText" runat="server" Text='<%#Eval("ddlCountryText")%>'></asp:Label>
                                </td>
                                <td class="csstablelisttd">
                                    <asp:Label ID="ddlstateText" runat="server" Text='<%#Eval("ddlstateText")%>'></asp:Label>
                                </td>
                            </tr>
                        </ItemTemplate>
                    </asp:Repeater>
                </table>
<asp:DropDownList ID="ddlCountry" runat="server" CssClass="csstextbox" Width="207px" AutoPostBack="true" OnSelectedIndexChanged="ddlCountry_SelectedIndexChanged">
</asp:DropDownList>
<asp:UpdatePanel ID="updatePanelState" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlState " runat="server" CssClass="csstextbox" Width="177px">
        </asp:DropDownList>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="ddlCountry" EventName="SelectedIndexChanged" />
    </Triggers>
</asp:UpdatePanel>
<asp:Button ID="btnSave" runat="server" Width="80px" OnClientClick="return validateForm();" Text="Save" CssClass="cssbutton" OnClick="btnSave_Click" />


ddlCountryID | ddlCountryText | ddlstateText
1            | USA            | XYZ
2            |India           | PQR

По щелчку TR я пишу ниже (SelectRow(this)) функцию в javascript для выделения значения повторителя и значения раскрывающегося списка и их выбора.

<script type="text/javascript">
function selectRow(objTR)
{
 var ddlCountry =document.getElementById('<%=ddlCountry.ClientID %>');
 var ddlState =document.getElementById('<%=ddlState .ClientID %>');

    for (i = 0; i < ddlCountry .options.length; i++)
    {
        if (ddlCountry .options[i].text == objTR.cells[1].innerText.trim())
            break;
    }           
    ddlCountry .options[i].selected = true;

    __doPostBack(ddlCountry .id, objTR.cells[2].innerText.trim());    
}
</script>

Я пишу ddlCountry SelectedIndexChangedEvent в коде позади.

Из Javascript я запускаю __doPostBack() и передаю ddlCountry в качестве цели события ddlStateText в качестве аргумента события для SelectedIndexChangedEvent и получаю значение в подобном событии.

string stateDescription = Request["__EVENTARGUMENT"];
ddlState .Items.FindByText(stateDescription ).Selected = true;//for highliting the repeater value and dropdown value match and selected

Страна привязки на страницеЗагрузить

 if(!Ispostback)
protected Void BindCountry()

{

strSQL = @"SELECT countryID,Country from Country_Master";
        DataTable dataTableCountry = null;
        dataTableCountry = objSqlDbComm.ExecuteDatasetQuery(strSQL).Tables[0];

        int countryID;
                string Country;     
        var dictioneryCountry = new Dictionary<int, string>();
        foreach(DataRow dr in dataTableCountry.Rows)
        {
            countryID = Convert.ToInt32(dr["countryID"]);
            Country= dr["Country"].ToString();          
            dictioneryCountry.Add(countryID,Country);
        }
        ddlCountry.Items.Clear();
        ddlCountry.DataTextField = "Value";
        ddlCountry.DataValueField = "Key";
        ddlCountry.DataSource = dictioneryCountry;
        ddlCountry.DataBind();
        ddlCountry.Items.Insert(0, new ListItem("[Select]", "-1"));
        ddlCountry.Items[0].Selected = true;
}

Моя проблема в том, что у меня есть следующие данные ретранслятора.

ddlCountryID | ddlCountryText | ddlstateText
1            | USA            | XYZ
2            |India           | PQR
2            |India           | MNO

Когда я выбираю строку номер 3, в которой есть страна Индия и состояние mno, тогда метод __dopostback() срабатывает.

Когда я перехожу к строке номер 1, метод __dopostback() срабатывает.

Когда я перехожу из строки с номером 1 в 3, тогда метод срабатывает правильно, но когда я перехожу из строки с номером 3 в строку 2 с идентификатором страны, тот же метод __dopostback() не срабатывает, и состояние не выбирается из ddlstate.


person Nikhil D    schedule 30.05.2012    source источник
comment
как вы привязываете ddlCountry?   -  person Imran Rizvi    schedule 30.05.2012
comment
я делаю привязку ddlCountry только в !ispostback{BindCountry();}   -  person Nikhil D    schedule 30.05.2012
comment
почему он должен срабатывать, если вы ничего не меняли?   -  person jcolebrand    schedule 16.06.2012
comment
только я должен отображать значение данных ретранслятора в соответствующем раскрывающемся списке.   -  person Nikhil D    schedule 16.06.2012
comment
Если вы приняли ответ Итисона, то почему вы не дали ему это очко за награду?   -  person Prince Antony G    schedule 21.06.2012
comment
Отлично, спасибо вам обоим.   -  person Itison    schedule 21.06.2012


Ответы (2)


Если вы отлаживаете свой код, вы увидите, что __doPostBack() действительно работает, потому что код в Page_Load выполняется (попробуйте установить здесь точку останова, чтобы проверить). Проблема в том, что индекс вашего DropDownList не меняется, поэтому событие IndexChanged не запускается, а ddlCountry_SelectedIndexChanged никогда не запускается. Когда вы вызываете __doPostBack(), это не то же самое, что вызов ddlCountry_SelectedIndexChanged вручную из кода программной части.

Есть ли какая-то конкретная причина, по которой вы будете отправлять сообщение, кроме как установить это значение в раскрывающемся списке?

РЕШЕНИЕ 1

Я бы посоветовал удалить строку __doPostBack() и добавить вместо нее следующее:

var state = objTR.cells[2].innerText.trim();
for (var i = 0; i < ddlState.options.length; i++)
{
    if (ddlState.options[i].text == state)
    {
        ddlState.options[i].selected = true;
        break;
    }
}

РЕШЕНИЕ 2

В качестве альтернативы, если вам действительно нужно отправить ответ, вы можете сделать следующее:

а. Добавьте скрытую кнопку внутри панели обновлений, например:

<div style="display: none">
<asp:Button ID="btnState" OnClick="btnState_Click" runat="server" />
</div>

б. Измените свой javascript, чтобы сделать следующее после выбора страны:

document.getElementById('__EVENTARGUMENT').value = objTR.cells[2].innerText.trim();
document.getElementById('<%= btnState.ClientID %>').click();

в. Создайте функцию FilterState() и вызовите ее из события indexchanged ddlcountry.

protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterState();
}

private void FilterState()
{
// insert whatever filtering code you had here
}

д. Добавьте свою функцию btnState_Click (обратите внимание, что способ, которым вы устанавливали выбранный элемент ddlState ранее, приведет к ошибке, если элемент уже выбран):

protected void btnState_Click(object sender, EventArgs e)
{
    FilterState();
    string state = Request["__EVENTARGUMENT"];
    if (state != "")
        ddlState.SelectedValue = state;
}

РЕШЕНИЕ 3

Третье решение позволит вам по-прежнему использовать __doPostBack и полностью отказаться от события SelectedIndexChanged, поместив его в функцию Page_Load:

if (IsPostBack && Request["__EVENTTARGET"] == ddlCountry.UniqueID)
{
    FilterState();
    string stateDescription = Request["__EVENTARGUMENT"];
    if (stateDescription != "")
        ddlState.SelectedValue = stateDescription;
}

С другой стороны, для вашей функции BindCountry нет реальной причины использовать словарь, вы можете просто напрямую связать DataTable:

strSQL = @"SELECT countryID,Country from Country_Master";
DataTable dataTableCountry = objSqlDbComm.ExecuteDatasetQuery(strSQL).Tables[0];
ddlCountry.Items.Clear();
ddlCountry.DataSource = dataTableCountry;
ddlCountry.DataTextField = "Country";
ddlCountry.DataValueField = "countryID";
ddlCountry.DataBind();
ddlCountry.Items.Insert(0, new ListItem("[Select]", "-1"));
ddlCountry.Items[0].Selected = true;
person Itison    schedule 16.06.2012
comment
да, есть особая причина, по которой я использую dopostback. Я дам вам пояснение, что я выбираю страну из данных ретранслятора, если я выбираю страну США, то я фильтрую ее состояние в событии ddlCountryselect. и выделяю соответствующее состояние в раскрывающемся списке, которое присутствует в столбце состояния ретранслятора. Да, его истинный DropDownList не меняется, поэтому событие IndexChanged не запускается, но есть ли способ исправить функциональность при выполнении dopostback (если мы обновим DOM, тогда это возможно) - person Nikhil D; 16.06.2012
comment
Что ж, мое второе решение заключалось в выполнении обратной передачи с помощью кнопки, которая имеет тот же эффект. Я изменил его так, чтобы фильтрация выполнялась независимо от того, была ли это выбор другой страны или щелчок по строке в элементе управления повторителем. В противном случае нет, вы не можете использовать __doPostBack для элемента управления DropDownList и заставить его выполнять событие SelectedIndexChanged без фактического изменения индекса. Всегда есть обходные пути, которые вы можете использовать для этого, но это совершенно не нужно, и любой, кто посмотрит на ваш код, вероятно, будет сбит с толку. Нецелесообразно использовать SelectedIndexChanged, когда он не меняется. - person Itison; 16.06.2012
comment
но я должен запускать только dopostback из javascript, когда пользователь выбирает страну из даты повторителя, даже индекс раскрывающегося списка тот же. Да, есть решение, даже когда индекс раскрывающегося списка тот же. Я исследую много, но ничего не нахожу. (ваш второй вариант события нажатия кнопки хороший) - person Nikhil D; 17.06.2012
comment
Я не совсем уверен, что вы имеете в виду. Вы сказали, что второй вариант хорош, но похоже, что вы все еще не считаете его приемлемым. Что он не позволяет вам сделать? Почему вы так сильно хотите использовать решение, включающее dopostback для ddlCountry? Это кажется действительно произвольным. - person Itison; 17.06.2012
comment
ltison: спасибо за ваш ответ, я прямо скажите мне, можем ли мы использовать мою функциональность, используя dopostback, даже если выпадающий индекс одинаков (да или нет). я должен найти решение, почему мы не можем использовать dopostback для того же выпадающего индекса. я приму ваш ответ, если у меня есть причина - person Nikhil D; 18.06.2012
comment
Да, есть еще одна вещь, которую вы могли бы сделать. Я отредактировал свой ответ, чтобы было немного проще различать разные решения. См. решение № 3. Как упоминалось ранее, если вы вызываете __doPostBack, он все равно отправляет обратно независимо от того, изменился ли индекс или нет. Если он не изменится, событие SelectedIndexChanged не сработает... поэтому вам придется переместить свой код в Page_Load. На мой взгляд, немного странно использовать __doPostBack для этого в первую очередь, но это сработает. - person Itison; 19.06.2012
comment
Во втором решении почему FilterState(); позвони два раза - person Nikhil D; 19.06.2012
comment
Потому что btnState_Click и ddlCountry_SelectedIndexChanged никогда не запускаются с одной и той же обратной передачей. Я только что включил вызов FilterState() в ddlCountry_SelectedIndexChanged, потому что вы сказали, что фильтруете состояние при изменении страны. Основная идея решения заключается в том, что фильтрация/выбор состояния осуществляется в btnState_Click. - person Itison; 19.06.2012
comment
если я удалю FilterState() в ddlCountry_SelectedIndexChanged, тогда он получит ошибку множественного выбора значения в ddlstate - person Nikhil D; 19.06.2012
comment
Да, вы должны изменить ddlState .Items.FindByText(stateDescription ).Selected = true; в ddlState.SelectedValue = stateDescription;. Я упоминал об этом в решении 2, часть d. - person Itison; 19.06.2012
comment
решение 2 идеально, но имеет один недостаток FilterState(); выполняется два раза - person Nikhil D; 19.06.2012
comment
Он не выполняется дважды. Когда вы выбираете другую страну, она выполняется один раз в ddlCountry_SelectedIndexChanged. Когда вы щелкаете строку в повторителе, она выполняется один раз в btnState_Click. Это не происходит одновременно. - person Itison; 19.06.2012

Это может быть связано с тем, что вы не привязываете отдельное значение для раскрывающегося списка для Text = "India", поэтому сервер не распознает, что значение было изменено, и, следовательно, не обрабатывает событие selectedindexchanged.

Попробуйте создать источник данных с разным значением для текста Индии или просто используйте один текст Индии.

Я ясно вижу, что в списке для Индии есть две повторяющиеся записи с дублирующимся ключом (2)

Это не рекомендуется. используйте только одну запись, которая должна иметь уникальный ключ.

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

    foreach(DataRow dr in dataTableCountry.Rows)
    {
        countryID = Convert.ToInt32(dr["countryID"]);
        Country= dr["Country"].ToString();

        if ( ! dictioneryCountry.Contains(countryID))
        {
           dictioneryCountry.Add(countryID,Country);
        }
    }

Дайте мне знать, если это работает

person Imran Rizvi    schedule 30.05.2012
comment
я связываю ddlCountry только один раз при загрузке страницы !ispostback{BindCountry();} - person Nikhil D; 30.05.2012
comment
Спасибо за ответ .. Независимо от того, что я показываю в данных ретранслятора. Я всегда использую два или номер штата для одной страны. Я запускаю событие selectedindexchanged из javascript. А также я использовал ваш код, но не работает. - person Nikhil D; 30.05.2012
comment
ПривязатьСтрану(); метод срабатывает при первой загрузке страницы не для каждой обратной передачи - person Nikhil D; 31.05.2012