Столкнулся со следующей проблемой при привязке данных в ячейке GridView.
Имею ячейку типа TemplateField — в ней в режиме редактирования т.е. в EditItemTemplate
расположил 3 DropDownList. (Сущности данных немного изменил чтобы не объяснять взаимосвязь поэтому в истинге скуль запросы другие — те которыми пользуюсь) К примеру хочу заполнить первый комбо бокс Городами, второй в зависимости от выбора в первом — Улицами, а третий, в зависимости от второго заполнить номерами домов. И номер дома обновлять в строке грида. В общем все делаю в темплэйт филде как и с одним дропдауномлистом — но вылезает ошибка:
"Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control."
Листинг следующий:
<asp:TemplateField HeaderText="Бригада" SortExpression="BRIGADENAME">
<EditItemTemplate>
<asp:DropDownList ID="ddlWorkshop11" runat="server" AutoPostBack="True"
DataSourceID="SqlDataSource112" DataTextField="NAME" DataValueField="ID"
SelectedValue='<%# Eval("WORKSHOPID") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource112" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString01 %>"
ProviderName="<%$ ConnectionStrings:ConnectionString01.ProviderName %>"
SelectCommand="SELECT WORKSHOP.ID, WORKSHOP.DIVISIONID, DIVISION.NAME AS DIVISIONNAME, WORKSHOP.NAME FROM WORKSHOP, DIVISION WHERE WORKSHOP.DIVISIONID = DIVISION.ID AND ((DIVISION.ID = :DIVISIONID) OR (DIVISION.ID = 0)) ORDER BY WORKSHOP.NAME NULLS FIRST">
<SelectParameters>
<asp:ControlParameter ControlID="ddlDivision01" Name="DIVISIONID"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<asp:DropDownList ID="ddlDistrict11" runat="server"
DataSourceID="SqlDataSource113" DataTextField="NAME" DataValueField="ID"
SelectedValue='<%# Eval("DISTRICTID") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource113" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString01 %>"
ProviderName="<%$ ConnectionStrings:ConnectionString01.ProviderName %>"
SelectCommand="SELECT DISTRICT.ID, DIVISION.ID AS DIVISIONID, DIVISION.NAME AS DIVISIONNAME, DISTRICT.WORKSHOPID, WORKSHOP.NAME AS WORKSHOPNAME, DISTRICT.NAME FROM WORKSHOP, DIVISION, DISTRICT WHERE WORKSHOP.DIVISIONID = DIVISION.ID AND WORKSHOP.ID = DISTRICT.WORKSHOPID AND (DIVISION.ID = :DIVISIONID OR DIVISION.ID = 0) AND (WORKSHOP.ID = :WORKSHOPID OR WORKSHOP.ID = 0) ORDER BY DISTRICT.NAME NULLS FIRST">
<SelectParameters>
<asp:ControlParameter ControlID="ddlDivision01" DefaultValue="0"
Name="DIVISIONID" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="ddlWorkshop11" DefaultValue="0"
Name="WORKSHOPID" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<asp:DropDownList ID="ddlBrigade11" runat="server"
DataSourceID="SqlDataSource114" DataTextField="NAME" DataValueField="ID"
SelectedValue='<%# Eval("BRIGADEID") %>' AutoPostBack="True">
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource114" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString01 %>"
ProviderName="<%$ ConnectionStrings:ConnectionString01.ProviderName %>"
SelectCommand="SELECT BRIGADE.ID, WORKSHOP.DIVISIONID, DIVISION.NAME AS DIVISIONNAME, DISTRICT.WORKSHOPID, WORKSHOP.NAME AS WORKSHOPNAME, BRIGADE.DISTRICTID, DISTRICT.NAME AS DISTRICTNAME, BRIGADE.NAME FROM WORKSHOP, DIVISION, DISTRICT, BRIGADE WHERE WORKSHOP.DIVISIONID = DIVISION.ID AND WORKSHOP.ID = DISTRICT.WORKSHOPID AND DISTRICT.ID = BRIGADE.DISTRICTID AND (DIVISION.ID = :DIVISIONID OR DIVISION.ID = 0) AND (WORKSHOP.ID = :WORKSHOPID OR WORKSHOP.ID = 0) AND (DISTRICT.ID = :DISTRICTID OR DISTRICT.ID = 0) ORDER BY BRIGADE.NAME NULLS FIRST">
<SelectParameters>
<asp:ControlParameter ControlID="ddlDivision01" DefaultValue="0"
Name="DIVISIONID" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="ddlWorkshop11" DefaultValue="0"
Name="WORKSHOPID" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="ddlDistrict11" DefaultValue="0"
Name="DISTRICTID" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblWorkshopName11" runat="server"
Text='<%# Eval("WORKSHOPNAME") %>'></asp:Label>
,
<asp:Label ID="lblDistrictName11" runat="server"
Text='<%# Eval("DISTRICTNAME") %>'></asp:Label>
,
<asp:Label ID="lblBrigadeName11" runat="server"
Text='<%# Eval("BRIGADENAME") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Вот в общем проблема как и ЭдитИтемТемплэйт-е заполнять последоватьельно из БД дроп даун листы — может есть у кого примерчик или какие мысли...
Здравствуйте, Аноним, Вы писали:
А>"Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control." А>Вот в общем проблема как и ЭдитИтемТемплэйт-е заполнять последоватьельно из БД дроп даун листы — может есть у кого примерчик или какие мысли...
Сегодня провозились с коллегой над его проблемой в абсолютно этом же виде. Перепробовал я все грязные хаки, которые знал, вывод, что в событии SelectedChanged нельзя вызывать DataBind другому при тех условиях, что описаны.
Самое странное, что не получилось даже привязываться от второго DataSource к первому комбику — я, когда начал рассматривать эту возможность, был уверен, что получится.
Воркараунд неутешительный — заполнять значениями комбик напрямую вытягивая данные с бизнес-слоя (new ListItem{} для каждого элемента). Пока так...
Фантастический говнокод! Мой Вам совет: забудьте про источники данных, связывание, контролы и прочую изжившую себя муть из мира WebForms. Просто пишите HTML и заполняйте его данными из POCO-сущностей.
Здравствуйте, Makc2, Вы писали:
M>Фантастический говнокод! Мой Вам совет: забудьте про источники данных, связывание, контролы и прочую изжившую себя муть из мира WebForms. Просто пишите HTML и заполняйте его данными из POCO-сущностей.
а как в приведённом примере добиться повторного использования кода?
Смотря что подразумевается под повторным использованием кода. Если речь идёт о стандартных HTML-тэгах, то я не вижу проблемы в их повторном использовании. Это всё равно, что говорить о повторном использовании точек и запятых. Если же речь идёт о повторном использовании сложной разметки, созданной верстальщиком, типа блоков со скруглёнными углами, то это можно вынести в отдельный метод, например так:
public static class Markup
{
public static string RoundedBox(Func<string> body = null)
{
var result = new StringBuilder();
result.Append(@"<div class=""rounded_box"">");
if (body != null)
{
result.Append(body());
}
result.Append("</div>");
return result.ToString();
}
}
Здравствуйте, Makc2, Вы писали:
M> Если же речь идёт о повторном использовании сложной разметки, созданной верстальщиком, типа блоков со скруглёнными углами, то это можно вынести в отдельный метод
да, речь именно о сложных кусках кода.
M>Это по-сути аналог HTML-хелпера из ASP.NET MVC.
теперь надо ещё сообщить данные в этот кусочек кода (в обощённом виде, конечно). Прикрутить поддержку картинок, скриптов, стилей (чтобы всё это шло с самим контролом и не нужно было добавлять всё это ручками на каждой странице).
Ну и собственно в итоге это выглядит не менее плохо, чем в WebForms.
N>теперь надо ещё сообщить данные в этот кусочек кода (в обощённом виде, конечно). Прикрутить поддержку картинок, скриптов, стилей (чтобы всё это шло с самим контролом и не нужно было добавлять всё это ручками на каждой странице). N>Ну и собственно в итоге это выглядит не менее плохо, чем в WebForms.
Вы, кажется, не поняли, что я хотел сказать. Я имел в виду, если программист знает, что такое HTML, то ему нет нужды использовать WebForms-контролы и мучиться с преодолением их ограничений. В подавляющем большинстве случаев кода будет на порядок меньше и он будет намного проще. Более того, создавать обобщённые конструкции, как правило, не приходится: взял HTML-код макета сайта, задвоил в нём ковычки и фигурные скобки, влепил в string.Format(@"") и вставил данные в нужные места.