2010-08-06 12 views
4

J'utilise DetailsView pour insérer des lignes dans la base de données. La ligne contient les champs id, subcategory_id etc. Je souhaite remplir dynamiquement la liste déroulante ddl_subcategories, qui est utilisée dans TemplateField. La valeur de l'élément sélectionné de la première liste déroulante ddl_categories est utilisée comme paramètre pour générer la collection pour ddl_subcategories. Je l'essaie avec UpdatePanel, mais la méthode DataBind renvoie l'erreur "Les méthodes de liaison de données telles que Eval(), XPath() et Bind() ne peuvent être utilisées que dans le contexte d'un contrôle de databound.".Comment lier des données à DropDownList dans UpdatePanel à l'intérieur DetailsView

Il y a un code de formulaire web

<asp:DetailsView ID="dvw" runat="server" Height="50px" Width="125px" 
    AutoGenerateRows="False" DataSourceID="ods" 
    DefaultMode="Insert" DataKeyNames="Section_id" 
    OnDataBound="dvw_DataBound" OnItemUpdated="dvw_ItemUpdated" 
    OnItemCommand="dvw_ItemCommand"> 
    <Fields> 
    <asp:TemplateField HeaderText="Category" > 
     <ItemTemplate> 
       <asp:DropDownList ID="ddl_categories" runat="server" AutoPostBack="true" DataSourceID="ods_categories" 
        DataTextField="Name" DataValueField="Category_id" OnSelectedIndexChanged="category_select_index_changed"/> 
     </ItemTemplate> 
    </asp:TemplateField>    

    <asp:TemplateField HeaderText="Subcategory" > 
     <ItemTemplate> 
      <asp:UpdatePanel runat="server" UpdateMode="Conditional"> 
       <ContentTemplate> 
        <asp:DropDownList ID="ddl_subcategories" runat="server"        
          SelectedValue='<%# Bind("Subcategory_id") %>' /> 
       </ContentTemplate> 
       <Triggers> 
        <asp:AsyncPostBackTrigger ControlID="ddl_categories" EventName="SelectedIndexChanged" /> 
       </Triggers> 
      </asp:UpdatePanel> 
     </ItemTemplate> 
    </asp:TemplateField> 
... 
</Fields> 
</asp:DetailsView> 

Il fait partie de derrière le code:

protected void category_select_index_changed(object sender, EventArgs e) 
{ 
    DropDownList ddl_categories = (DropDownList)dvw.FindControl("ddl_categories"); 
    List<SUBCATEGORY> sections = SUBCATEGORY.Select_all_by_parameters(Int32.Parse(ddl_categories.SelectedValue));//Select all subcategories by id of category 
    DropDownList ddl_subcategories= (DropDownList)dvw.FindControl("ddl_subcategories"); 

    ddl_subcategories.DataSource = sections; 
    ddl_subcategories.DataTextField = "Name"; 
    ddl_subcategories.DataValueField = "Subcategory_id"; 
    ddl_subcategories.DataBind(); 
} 

Quelle est mon erreur? Merci.

+0

Avez-vous tout le code? Je ne vois pas ddl_subcategories dans votre codebehind – MCain

+0

Dans this page est votre réponse. Vous devez utiliser correctement de DetailsView. –

+0

Dans this page est votre réponse. vous devez utiliser correctement à partir de DetailsView. –

Répondre

0

Essayez d'envelopper l'ensemble DetailsView avec le panneau de mise à jour pour voir si cela fait une différence ...

1

Le problème est que lorsque vous êtes la liaison de données dans le menu déroulant des sous-catégories, il n'y a pas de contexte DataBinding (voir here pour plus info, faites attention aux commentaires de David Fowler). Je ne pense pas que le UpdatePanel est le problème car le comportement est le même avec ou sans (et si vous enveloppez l'ensemble DetailsView dans un UpdatePanel).

Une solution consiste à charger les éléments individuellement au lieu de lier les données à la commande. Cela semble un peu maladroit, je l'admets, mais ça marche.

protected void category_select_index_changed(object sender, EventArgs e) 
{ 
    DropDownList ddl_categories = (DropDownList)dvw.FindControl("ddl_categories"); 
    IEnumerable<SUBCATEGORY> sections = new SUBCATEGORY[] { new SUBCATEGORY() { Name = "First " + ddl_categories.SelectedValue, Subcategory_id = "1" }, new SUBCATEGORY() { Name = "Second", Subcategory_id = "2" } }; 
    DropDownList ddl_subcategories = (DropDownList)dvw.FindControl("ddl_subcategories"); 

    ddl_subcategories.Items.Clear(); 
    foreach (SUBCATEGORY cat in sections) 
    { 
     ddl_subcategories.Items.Add(new ListItem(cat.Name, cat.Subcategory_id)); 
    } 
} 

Une meilleure option serait de ne pas utiliser Bind dans le contrôle, et situé juste à la valeur dans les paramètres de ObjectDataSource sur Insérer/Mettre à jour.

Mise à jour: Vous pouvez définir la valeur ObjectDataSource directement. Ajoutez un gestionnaire d'événements pour l'OnInserting (ou OnUpdating au besoin) comme suit:

protected void ods_OnInserting(object sender, ObjectDataSourceMethodEventArgs e) 
{ 
    DropDownList ddl_subcategories = (DropDownList)dvw.FindControl("ddl_subcategories"); 
    e.InputParameters["Subcategory_id"] = ddl_subcategories.SelectedValue; 
} 

je ne peux pas tester réellement ce moment, mais il devrait être proche.

+0

J'ai essayé de cette façon. Les champs de liste déroulante ont été remplis correctement. Mais le formulaire a envoyé une valeur nulle à partir de dropdownlist. Quelle est la raison? Encore une question. Est-il possible de définir une valeur dans ObjectDataSource par programme? – greatromul

+0

Si je n'utilise pas le panneau de mise à jour, ddl_subcategories renvoie la valeur correcte. Mais si je n'utilise pas le panneau de mise à jour, je ne pourrai pas réaliser le comportement des contrôles sans publication. – greatromul

+0

Si j'utilise un AJAX pur (services web et js) sans panneau de mise à jour, cela fonctionne. Mais c'est intéressant pourquoi cela ne fonctionne pas avec le panneau de mise à jour. – greatromul

1

Retirez le Bind("DBFieldName") et ajoutez la ligne suivante à la YourDetailsView_ItemInserting comme ce qui suit:

e.Values["DBFieldName"] = 
    ((DropDownList)YourDetailsView.Rows[1].FindControl("ddl_categories")).SelectedValue; 

Note: Ne pas oublier de remplacer les lignes [1] à votre index de champ Dropdown templete.

Questions connexes