Проблемы с AJAX CascadingDropDown и DropDownList SelectedValue в EditItemTemplate

У меня проблема с EditItemTemplate из FormView.

Когда я использую такой код в InsertItemTemplate, все работает:

<asp:DropDownList ID="Lic_PosiadaczLicencjiIDDropDownList" runat="server" 
    SelectedValue='<%# Bind("Lic_PosiadaczLicencjiID") %>' />
<asp:CascadingDropDown ID="CascadingDropDown1" runat="server" 
    TargetControlID="Lic_PosiadaczLicencjiIDDropDownList" Category="Knt_Kod" 
    ServicePath="~/ManagerLicencjiService.asmx" ServiceMethod="GetKontrahenci">
</asp:CascadingDropDown>  

Но когда я использую точно такой же код в EditItemTemplate, я получаю сообщение об ошибке SelectedValue, потому что его нет в списке элементов. Я думаю, что проблема в том, что DropDownList проверяется на значения до его заполнения службой. Когда я запускаю отладчик, ошибка возникает до точки останова в методе службы.

Как решить эту проблему?


person Wodzu    schedule 30.09.2010    source источник


Ответы (1)


<rant> Я обнаружил, что ПЗС-матрица очень неуклюжа и полна плохо документированных обходных путей</rant>, но вот как можно сделать что-то столь же простое, как выбор значения при заполнении ddl. Обратите внимание, что выбранное значение не задано в DDL и передается в веб-службу, где выполняется выбор.

<asp:ScriptManager ID="sm1" runat="server"></asp:ScriptManager>
<asp:FormView ID="fv1" runat="server" DataSourceID="yourDataSource">
    <EditItemTemplate>
        <asp:DropDownList ID="Lic_PosiadaczLicencjiIDDropDownList" runat="server" />
        <asp:CascadingDropDown ID="CascadingDropDown1" runat="server" 
            TargetControlID="Lic_PosiadaczLicencjiIDDropDownList" Category="Knt_Kod" 
            ServicePath="~/ManagerLicencjiService.asmx" ServiceMethod="GetKontrahenci"
            UseContextKey="true" ContextKey='<%# Bind("Lic_PosiadaczLicencjiID") %>'>
        </asp:CascadingDropDown>
    </EditItemTemplate>
</asp:FormView>

<asp:sqldatasource id="yourDataSource"
    selectcommand="select Lic_PosiadaczLicencjiID FROM yourdatabase"
    UpdateCommand="Update yourdatabase set Lic_PosiadaczLicencjiID = @newvalue WHERE Lic_PosiadaczLicencjiID = @Lic_PosiadaczLicencjiID"
    connectionstring="<%$ ConnectionStrings:yourConnectionString %>" 
    runat="server" 
    onupdating="yourDataSource_Updating">
    <UpdateParameters>
        <asp:Parameter Name="newvalue" DbType="String" />
    </UpdateParameters>
</asp:sqldatasource>

код позади:

protected void yourDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
    e.Command.Parameters["@newvalue"].Value = ((DropDownList)fv1.FindControl("Lic_PosiadaczLicencjiIDDropDownList")).SelectedValue;
}

а в вашей веб-службе, из которой вы получаете данные, вам необходимо добавить контекстный ключ к подписи точно так, как показано, поскольку он чувствителен к регистру. Затем вы проверяете возвращенные вами значения для выбранного значения и устанавливаете selected = true. Если вам нужно выбранное значение вместо выделенного текста, проверьте x.value вместо x.name.

[WebMethod]
public CascadingDropDownNameValue[] GetKontrahenci(string knownCategoryValues, string category, string contextKey)
{
     CascadingDropDownNameValue[] results = getdata();

     CascadingDropDownNameValue selectedVal = (from x in results where x.name == contextKey select x).FirstOrDefault();
     if (selectedVal != null)
         selectedVal.isDefaultValue = true;

    return results;
}

Надеюсь это поможет!

person JumpingJezza    schedule 04.10.2010
comment
Полностью поддерживаю твою тираду! ;-) Не говоря уже о том, что Microsoft переходит на jQuery. К сожалению, я не могу отметить ваше сообщение как ответ, потому что это не решает основную проблему, заключающуюся в том, что ASP требует элементы (выбранный элемент) из DDL до того, как DDL будет заполнен ими. сервисным методом. Я нашел решение для этого, но уродливое: я заполняю DDL одним известным элементом на стороне сервера перед привязкой данных. Однако вы помогли мне с другой проблемой: stackoverflow.com/questions/3838203/ +1 :) - person Wodzu; 04.10.2010
comment
Удалив тег SelectedValue из DDL, как показано выше, страница aspx не должна требовать элементы (выбранный элемент) из DDL до того, как DDL будет заполнен ими с помощью метода службы. - person JumpingJezza; 05.10.2010
comment
Я сделал, как вы сказали, и ошибка не возвращается. Я вижу элементы в списке, contextKey работает. Однако теперь операция обновления не работает. Под словом "не работает" я подразумеваю, что вновь выбранные значения не передаются в базу данных. Вместо этого старые передаются, поэтому обновления нет. - person Wodzu; 05.10.2010
comment
Вы используете onitemUpdating для обновления базы данных? Я получаю новое значение, когда тестирую свое приложение. - person JumpingJezza; 05.10.2010
comment
Тогда я, должно быть, делаю что-то не так ... Я не использую событие ItemUpdating. Но я использую оба элемента управления DDL и CDD в EditItemTemplate. У вас это работает в EditItemTemplate? - person Wodzu; 05.10.2010
comment
Да, все, что у меня есть в моем EditItemTemplate, - это код выше + кнопка обновления. В представлении формы есть OnItemUpdating = fv1_ItemUpdating, относящийся к моему методу кода, который выполняет обновление. - person JumpingJezza; 05.10.2010
comment
Не могли бы вы попробовать выполнить автоматическое обновление через DataSource вместо того, чтобы делать это вручную в этом случае? - person Wodzu; 05.10.2010
comment
ну, я обычно не использую источники данных, поскольку я не очень понимаю, как их отлаживать без использования профилировщика sql и не доверять подобным автоматическим вещам (в свое время мы кодировали в DOS на черно-зеленом экране), но Я обновил свой ответ выше :) - person JumpingJezza; 06.10.2010
comment
Так что код неизбежен: | Довольно странно, что мне не нужно указывать значение (явно) для набора данных в режиме вставки, но я должен сделать это в обновлении. Спасибо за ваше время :) - person Wodzu; 06.10.2010
comment
нп! кстати, ASP - это не то же самое, что asp.net, поэтому вам, вероятно, следует пометить вопрос заново :) - person JumpingJezza; 06.10.2010