2011-07-19 33 views
5

Tengo 2 DropDownList controles en mi formulario, el segundo de los cuales usa el SelectedValue del primero como uno de sus parámetros de enlace.Implementando el enlace DropDownList en cascada en un control de plantilla

Tanto DropDownList controles están en un FormView.InsertItemTemplate con SelectedValue propiedades unidos a la fuente de datos la FormView 's utilizando una expresión de enlace.

La primera vez que el FormView se renderiza en modo Insertar, todo funciona bien. El problema es después de un AutoPostBack desde el primer DropDownList, el FormView no se vuelve a vincular, sin embargo, dado que el ControlParameter en el segundo DropDownList ha cambiado, SÍ se enlaza (como estaba previsto), pero se produce una excepción en la Expresión vinculante de la segunda DDL, asumo desde la FormView no es vinculante para que pase:

System.InvalidOperationException: métodos de enlace de datos tales como Eval(), XPath(), y bind() sólo se pueden utilizar en el contexto de un control de datos .

Aquí es el marcado:

<InsertItemTemplate> 
. 
. 
. 
<tr class="GridViewRowB"> 
        <td class="GridViewCell"> 
         Offense Type 
        </td> 
        <td class="GridViewCell"> 
         <asp:DropDownList ID="ddlOffenseType" runat="server" DataSourceID="dsOffenseType" 
          AutoPostBack="true" DataValueField="OffenseTypeID" DataTextField="Description" 
          SelectedValue='<%# Bind("OffenseTypeID") %>'> 
         </asp:DropDownList> 
         <asp:ObjectDataSource ID="dsOffenseType" runat="server" TypeName="OffenseType" 
          SelectMethod="GetAll"> 
          <SelectParameters> 
           <asp:Parameter Name="ActiveOnly" DefaultValue="True" Type="Boolean" /> 
          </SelectParameters> 
         </asp:ObjectDataSource> 
        </td> 
       </tr> 
       <tr class="GridViewRowA"> 
        <td class="GridViewCell"> 
         Attorney 
        </td> 
        <td class="GridViewCell"> 
         <asp:DropDownList ID="ddlAttorney" runat="server" DataSourceID="dsAttorney" DataValueField="AttorneyID" 
          DataTextField="AttorneyNameWithCount" SelectedValue='<%# Bind("AttorneyID") %>'> 
         </asp:DropDownList> 
         <asp:ObjectDataSource ID="dsAttorney" runat="server" TypeName="Attorney" 
          SelectMethod="GetAttorneyWithCaseCount"> 
          <SelectParameters> 
           <asp:Parameter Name="ActiveOnly" DefaultValue="True" Type="Boolean" /> 
           <asp:ControlParameter Name="OffenseTypeID" Type="Int32" ControlID="ddlOffenseType" 
            PropertyName="SelectedValue" /> 
          </SelectParameters> 
         </asp:ObjectDataSource> 
        </td> 
       </tr> 
. 
. 
. 
</InsertItemTemplate> 

Mi pregunta es: ¿Cuál es la mejor manera de hacer este trabajo funcionalidad? ¿Es posible mantener ambos DDL dentro de la plantilla? Preferiría evitar el uso del kit de herramientas AJAX u otras soluciones del lado del cliente.

Respuesta

8

Esto es un problema cuando utilizamos la lista desplegable en cascada en Controles de enlace de datos como DetailsView/FormView y lo he enfrentado muchas veces. Debe eliminar la Expresión de enlace de su Segunda lista desplegable SelectedValue='<%# Bind("AttorneyID") %>', y luego funcionará.

En segundo lugar, si elimina la expresión de enlace, debe pasar el valor manualmente en el evento FormView ItemInserting. p.ej.

protected void frmAsset_ItemInserting(object sender, FormViewInsertEventArgs e) 
{ 
    eValues["AttorneyID"] = ((DropDownList)((FormView)sender).FindControl("ddlAttorny")).SelectedValue; 
} 
+0

bien así .... entonces yo tendría que manejar 'FormView .ItemInserting' y agrega el parámetro en forma manual? ¿Qué pasa con el mismo problema en el modo 'Editar'? ¿Maneja los valores inicial y actualizado manualmente? El código de ejemplo para la posteridad sería apreciado. – pseudocoder

+0

yah, exactamente. tienes que hacer lo mismo para editar también. –

+0

Comprobé que esta solución funciona. ¡Gracias! Tenía algunas ideas similares a esta, pero no estaba seguro de cómo la mayoría de las personas abordan el problema. – pseudocoder

2

Esto puede ser un poco tarde, pero mejor tarde que nunca:

Protected Sub DetailsView1_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating 
    e.NewValues("AtendeeSubType") = DirectCast(DirectCast(sender, DetailsView).FindControl("dropdownlist3"), DropDownList).SelectedValue 
End Sub 

He probado esto para el evento ItemUpdating de una vista de detalles, pero creo que va a trabajar para una formview, interruptor solo las partes que necesita y funcionará.

Editar: Puede comprobar esta referencia: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.itemupdating.aspx

4

En realidad Quiero poner esta respuesta en caso de que nadie se quedó atascado como lo hice. Lo que dijo Muhammad Akhtar funciona perfectamente, sin embargo, encontré una solución más simple.
En

<asp:DropDownList ID="ddlAttorney" runat="server" DataSourceID="dsAttorney" DataValueField="AttorneyID" DataTextField="AttorneyNameWithCount" SelectedValue='<%# Bind("AttorneyID") %>'> 

cambio Bind("AttorneyID")-DataBinder.Eval (Container.DataItem, "AttorneyID")
Funciona perfectamente!
EDIT: Mi código de ejemplo:

<asp:Content ID="Content3" ContentPlaceHolderID="BodyContent" runat="Server"> 
<asp:DetailsView ID="dv" runat="server" Height="50px" DataSourceID="ODS" DefaultMode="Insert" 
    AutoGenerateRows="False" OnItemCommand="dv_ItemCommand" OnItemInserted="dv_ItemInserted" 
    DataKeyNames="Id" OnItemUpdated="dv_ItemUpdated" CssClass="DetailsView" 
    > 
    <Fields> 
     <asp:TemplateField HeaderText="Page Name:"> 
      <ItemTemplate> 
       <asp:Label ID="txtPageName" runat="server" Text="<%#Bind('PageName') %>" /> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:TextBox ID="txtPageName" runat="server" Text="<%#Bind('PageName') %>" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Parent:"> 
      <ItemTemplate> 
       <asp:Label ID="txtParentPageName" runat="server" Text='<%#Bind("ParentPageName") %>' /> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList runat="server" ID="lstParentPage" DataSourceID="ParentPageODS" 
        AppendDataBoundItems="true" DataTextField="PageName" DataValueField="Id" SelectedValue="<%#Bind('ParentPage') %>" 
        AutoPostBack="True"> 
        <asp:ListItem Text="-Root-" Value="" /> 
       </asp:DropDownList> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="After..."> 
      <ItemTemplate> 
       <asp:Label ID="txtPreviousPage" runat="server" Text='<%#Bind("PageOrder") %>' /> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList runat="server" ID="lstPageOrder" AppendDataBoundItems="true" DataTextField="PageName" DataSourceID="PageOrderODS" DataValueField="PageOrder" EnableViewState="False" SelectedValue='<%# DataBinder.Eval (Container.DataItem, "PageOrder") %>'> 
        <asp:ListItem Text="-First-" Value="" /> 
       </asp:DropDownList> 
       <asp:ObjectDataSource ID="PageOrderODS" runat="server" SelectMethod="SelectByParent" 
        TypeName="SirM2X.Pages"> 
        <SelectParameters> 
         <asp:ControlParameter ControlID="lstParentPage" Name="ParentPage" PropertyName="SelectedValue" /> 
        </SelectParameters> 
       </asp:ObjectDataSource> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Dummy Page?"> 
      <ItemTemplate> 
       <asp:Label runat="server" ID="txtDummyPage" Text="<%#Bind('IsDummyText') %>" /> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:CheckBox ID="chkIsDummy" runat="server" Checked="<%#Bind('IsDummy') %>" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField ShowHeader="False"> 
      <EditItemTemplate> 
       <asp:Button ID="btnUpdate" runat="server" CausesValidation="True" CommandName="Update" 
        Text="<%$Resources:Resources, Update %>" /> 
       &nbsp;<asp:Button ID="btnCancel" runat="server" CausesValidation="False" CommandName="Cancel" 
        Text="<%$Resources:Resources, Cancel %>" /> 
      </EditItemTemplate> 
      <InsertItemTemplate> 
       <asp:Button ID="btnInsert" runat="server" CausesValidation="True" CommandName="Insert" 
        Text="<%$Resources:Resources, Insert %>" /> 
       &nbsp;<asp:Button ID="btnCancel" runat="server" CausesValidation="False" CommandName="Cancel" 
        Text="<%$Resources:Resources, Cancel %>" /> 
      </InsertItemTemplate> 
      <ItemTemplate> 
       <asp:Button ID="btnEdit" runat="server" CausesValidation="False" CommandName="Edit" 
        Text="<%$Resources:Resources, Edit %>" /> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Fields> 
</asp:DetailsView> 
<asp:ObjectDataSource ID="ODS" runat="server" DeleteMethod="DeleteRow" InsertMethod="InsertRow" 
    SelectMethod="SelectRow" TypeName="SirM2X.Pages" UpdateMethod="UpdateRow" OnInserting="ODS_Inserting" 
    OnUpdating="ODS_Updating"> 
    <DeleteParameters> 
     <asp:Parameter Name="Id" Type="Int32" /> 
    </DeleteParameters> 
    <InsertParameters> 
     <asp:Parameter Name="PageName" Type="String" /> 
     <asp:Parameter Name="CreatedBy" Type="String" /> 
     <asp:Parameter Name="ParentPage" Type="Int32" /> 
     <asp:Parameter Name="PageOrder" Type="Int32" /> 
     <asp:Parameter Name="IsDummy" Type="Boolean" /> 
    </InsertParameters> 
    <SelectParameters> 
     <asp:QueryStringParameter Name="Id" QueryStringField="ID" Type="Int32" /> 
    </SelectParameters> 
    <UpdateParameters> 
     <asp:Parameter Name="Id" Type="Int32" /> 
     <asp:Parameter Name="PageName" Type="String" /> 
     <asp:Parameter Name="ParentPage" Type="Int32" /> 
     <asp:Parameter Name="PageOrder" Type="Int32" /> 
     <asp:Parameter Name="IsDummy" Type="Boolean" /> 
     <asp:Parameter Name="DeleteState" Type="Boolean" /> 
    </UpdateParameters> 
</asp:ObjectDataSource> 
<asp:ObjectDataSource ID="ParentPageODS" runat="server" SelectMethod="SelectAll" 
    TypeName="SirM2X.Pages"></asp:ObjectDataSource> 

+0

¿Puedes darnos la fuente de la página completa? Este problema solo ocurre cuando tienes controles en cascada dentro de una plantilla, y mi entendimiento es que DataBinder.Eval es esencialmente lo mismo que simplemente Eval. – pseudocoder

+0

@pseudocoder Pensé que hacen lo mismo. Sin embargo, recientemente descubrí que son ligeramente diferentes en el caso de las listas desplegables en cascada. He adjuntado mi código y está funcionando perfectamente. – M2X

1

Aquí es cómo lo hice ...

<asp:SqlDataSource ID="sqldsDDPlant" runat="server" ConnectionString="<%$ ConnectionStrings:SeedTrackerConnectionString %>" 
    SelectCommand="SELECT * FROM [Plant] ORDER BY [Plant]"></asp:SqlDataSource> 

<asp:SqlDataSource ID="sqldsDDType" runat="server" ConnectionString="<%$ ConnectionStrings:SeedTrackerConnectionString %>" 
    SelectCommand="SELECT * FROM [Type] ORDER BY [Type]" FilterExpression="PLID = '{0}'"> 
     <FilterParameters> 
      <asp:ControlParameter Name="plantParam" ControlID="DVSeedTracker$ddPlant" PropertyName="SelectedValue" /> 
     </FilterParameters> 
</asp:SqlDataSource> 

     <asp:TemplateField HeaderText="Plant"> 
      <InsertItemTemplate> 
       <asp:DropDownList ID="ddPlant" runat="server" AutoPostBack="true" SelectedValue='<%# Bind("PLID") %>' 
       DataSourceID="sqldsDDPlant" DataTextField="Plant" DataValueField="PLID" AppendDataBoundItems="True"> 
        <asp:ListItem></asp:ListItem> 
       </asp:DropDownList> 
       <asp:RequiredFieldValidator 
        id="RequiredFieldValidator2" 
        runat="server" 
        ControlToValidate="ddPlant" 
        Display="Static" 
        ErrorMessage="*Required" CssClass="RequiredField" />     
      </InsertItemTemplate> 
     </asp:TemplateField> 

     <asp:TemplateField HeaderText="Type"> 
      <InsertItemTemplate> 
       <asp:DropDownList ID="ddType" runat="server" 
       DataSourceID="sqldsDDType" DataTextField="Type" DataValueField="TYPID" AppendDataBoundItems="False"> 
        <asp:ListItem></asp:ListItem> 
       </asp:DropDownList> 
        <asp:RequiredFieldValidator 
        id="RequiredFieldValidator3" 
        runat="server" 
        ControlToValidate="ddType" 
        Display="Static" 
        ErrorMessage="*Required" CssClass="RequiredField" />         
      </InsertItemTemplate> 
     </asp:TemplateField> 
Cuestiones relacionadas