2009-08-17 6 views
3

J'ai 2 contrôles utilisateur sur ma page. Un est utilisé pour la recherche, et l'autre est utilisé pour l'édition (avec quelques autres choses).Comment configurer un GridView CommandField pour déclencher la mise à jour de page complète dans UpdatePanel

Le contrôle utilisateur qui fournit la fonctionnalité de recherche utilise GridView pour afficher les résultats de la recherche. Cette GridView a un CommandField utilisé pour l'édition (showEditButton = "true").

Je voudrais placer le GridView dans un UpdatePanel afin que la pagination à travers les résultats de recherche sera lisse. Le fait est que lorsque l'utilisateur clique sur le lien Edit (le champ CommandField), j'ai besoin de préformer une publication en pleine page afin que le contrôle de l'utilisateur de recherche puisse être masqué et que le contrôle utilisateur d'édition puisse être affiché.

Edit: la raison pour laquelle je dois faire une publication pleine page est parce que le contrôle utilisateur de modifier est en dehors de l'UpdatePanel que mon GridView est dans Il est non seulement en dehors de la UpdatePanel, mais il est dans un utilisateur complètement différent. contrôle.

Je ne sais pas comment ajouter le CommandField en tant que déclencheur de publication sur une page entière au UpdatePanel. Le PostBackTrigger (qui est utilisé pour indiquer que les contrôles provoquent une publication en pleine page) prend un ControlID en tant que paramètre; Cependant, le CommandButton n'a pas d'ID ... et vous pouvez voir pourquoi j'ai un problème avec ça.

Mise à jour sur quoi d'autre j'ai essayé de résoudre le problème: J'ai pris une nouvelle approche pour résoudre le problème.

Dans ma nouvelle approche, j'ai utilisé un TemplateField au lieu d'un CommandField. J'ai placé un contrôle LinkButton dans le TemplateField et lui ai donné un nom. Pendant l'événement RowDataBound de GridView, j'ai récupéré le contrôle LinkButton et l'ai ajouté aux Triggers du UpdatePanel.

C'est le balisage ASP pour le UpdatePanel et le GridView

<asp:UpdatePanel ID="SearchResultsUpdateSection" runat="server"> 
    <ContentTemplate> 
    <asp:GridView ID="SearchResultsGrid" runat="server" 
     AllowPaging="true" 
     AutoGenerateColumns="false"> 
     <Columns> 
     <asp:TemplateField> 
      <HeaderTemplate></HeaderTemplate> 
      <ItemTemplate> 
      <asp:LinkButton ID="Edit" runat="server" Text="Edit"></asp:LinkButton> 
      </ItemTemplate> 
     </asp:TemplateField> 
     <asp:BoundField ...... 
     </Columns> 
    </asp:GridView> 
    </ContentTemplate> 
</asp:UpdatePanel> 

Dans mon code VB.NET. J'ai implémenté une fonction qui gère l'événement RowDataBound de GridView. Dans cette méthode, je trouve le LinkButton pour la ligne liée, créer un PostBackTrigger pour le LinkButton, et l'ajouter aux Triggers du UpdatePanel. Cela signifie qu'un PostBackTrigger est créé pour chaque LinkButton "edit" dans le GridView Edit: cela n'a pas créé un PostBackTrigger pour chaque LinkButton "edit" car l'ID est le même pour tous les LinkButtons dans le GridView. Au lieu de gérer l'événement RowEditing de GridView à des fins d'édition, j'utilise plutôt RowCommand.

Private Sub SearchResultsGrid_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles SearchResultsGrid.RowCommand 
     RaiseEvent EditRecord(Me, New EventArgs()) 
End Sub 

Cette nouvelle approche ne fonctionne pas du tout parce que tous les linkbuttons dans les GridView ont le même ID. Après avoir lu l'article MSDN sur le UpdatePanel.Triggers Property, j'ai l'impression que les déclencheurs ne peuvent être définis que de façon déclarative. Cela signifierait que tout ce que j'ai fait dans le code VB ne fonctionnerait pas.

Tout conseil serait grandement apprécié.

Merci,

-Frinny

+0

Pourquoi avez-vous besoin d'une publication de page pour la visibilité, sauf si vous recevez des informations du serveur à des contrôles spécifiques? GridView dans UpdatePanel dont le mode de mise à jour défini sur Toujours (par défaut) peut actualiser n'importe quoi dans les options de commande. Je n'ai pas compris pourquoi vous insistez pour une publication? – Myra

+0

J'insiste sur une publication en pleine page parce que le contrôle utilisateur utilisé pour l'édition est en dehors du UpdatePanel dans lequel se trouve GridView. – Frinavale

+0

En fait, ce n'est même pas sous le même contrôle. Le UpdatePanel est dans le contrôle utilisateur "search" et le contrôle utilisateur "edit" ne fait pas partie du contrôle utilisateur "search" de l'utilisateur. – Frinavale

Répondre

2

Pour contourner ce problème, je mis en place un contrôle d'appel personnalisé que je placé au-dessus du GridView mais toujours dans le UpdatePanel. Lorsque le contrôle de pagination est utilisé, GridView est mis à jour de manière asynchrone. J'ai défini GridView en tant que PostBackTrigger pour le UpdatePanel. Maintenant, chaque contrôle dans GridView provoque une publication en pleine page. Ce qui signifie que le contrôle d'édition entraînera une publication en pleine page, mais le tri sera également effectué.

Je me sens un peu vaincu ici, mais au moins j'ai une solution semi-fonctionnelle.

Je suis toujours intéressé par les solutions suggérées par n'importe qui qui pourraient éclairer la résolution du problème.

-Frinny

7

Pour enregistrer une commande comme un déclencheur pour une publication, utilisez RegisterPostBackControl Méthode de ScriptManager.

 If editLink IsNot Nothing Then 
      ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(editLink) 
     End If 

Cette méthode fonctionne également pour les contrôles ajoutés dynamiquement dans d'autres contrôles. J'ai eu le même problème avec mon GridView. J'ai enregistré linkButton et imageButton d'une ligne TemplatedField.

j'utiliser le gestionnaire de RowCreated Gridview à la place du conducteur RowDataBound: RowCreated se concentre sur l'analyse syntaxique de la définition de la ligne Gridview et la création de la structure de contrôle de la ligne Gridview, RowDataBound se concentre sur les données se lient à des contrôles de la ligne créée dans le RowCreated. RowCreated est également appelé automatiquement dans les deux cas init et postback, mais RowDataBound n'est invoqué que lorsque DataBind est appelé. code

<asp:GridView ID="ContactsGridView" runat="server" AutoGenerateColumns="False" 
     DataSourceID="ContactsContainerDataSource" EnableViewState="false" 
     DataKeyNames="CompanyID,ContactId" AllowSorting="True" AllowPaging="true" 
     OnRowCreated="ContactsGridView_RowCreated" PageSize="10" CssClass="GridSimple" 
     OnRowCommand="ContactsGridView_RowCommand"> 
     <Columns> 
       <asp:TemplateField HeaderStyle-CssClass="large" HeaderText="Contact" SortExpression="ContactNom"> 
       <ItemTemplate> 
        <asp:ImageButton ID="PreviewImageButton" runat="server" ImageUrl="../images/picto_pdf.gif" 
         CommandName="PreviewContact" CommandArgument=<%#Eval("ContactCode") %> BorderWidth="0" 
         ToolTip="View Pdf Document" /> 
        <asp:LinkButton ID="ContactNamePreviewLinkButton" runat="server" CommandName="Select" 
         CommandArgument='<%#Eval("ContactCode") %>'><%#Eval("ContactName")%></asp:LinkButton> 
       </ItemTemplate> 
      </asp:TemplateField> 
     </Columns> 
    </asp:GridView> 




    protected void ContactsGridView_RowCreated(object sender, GridViewRowEventArgs e) 
    { 
     if (e.Row.RowType == DataControlRowType.DataRow) 
     { 
      //Register download buttons as PostBack controls (instead of AsyncPostback because of their updatepanel container)) 
      ImageButton ib = (ImageButton)e.Row.FindControl("PreviewImageButton"); 
      if (ib != null) ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(ib); 
      LinkButton lb = (LinkButton)e.Row.FindControl("ContactNamePreviewLinkButton"); 
      if (lb != null) ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(lb); 
     } 

    } 
    protected void ContactsGridView_RowCommand(object sender, GridViewCommandEventArgs e) 
    { 
     if (e.CommandName == "PreviewContact") 
     { 

      _presenter.OnPreviewContactClicked((string)e.CommandArgument); 
     } 
    } 
+0

Cette méthode fonctionne correctement pour les contrôles qui ne sont pas ajoutés dynamiquement dans d'autres contrôles ... Par exemple, vous ne pouvez pas utiliser cette méthode pour enregistrer un lien ou un bouton dynamiquement généré dans un GridView. C'est la raison pour laquelle j'ai posté cette question: c'est le problème. S'il vous plaît relire le fil pour plus de détails sur pourquoi et ce que j'ai essayé de faire pour contourner cela. – Frinavale

+0

Je l'ai essayé et ça marche. Assurez-vous simplement d'utiliser l'événement 'RowCreated' et non l'événement 'RowDataBound'. THX – chris6523

0

Vous ne pouvez pas ajouter des déclencheurs au panneau de mise à jour en utilisant soit RegisterPostBackControl ou en ajoutant une nouvelle PostBackTrigger à la collection déclenche à moins que vous le faites avant que la charge de la page.

Il doit être fait dans le Oninitcomplete ou onInit

2

ce poste a fonctionné pour moi, il utilise rowCreated et ScriptManager link text

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) 
{ 
    LinkButton lnk = e.Row.FindControl("LinkButton1") as LinkButton; 
    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 

     if (lnk != null) 
     { 
      ScriptManager1.RegisterPostBackControl(lnk); 
     } 
     //PostBackTrigger pb = new PostBackTrigger(); 

     //pb.ControlID = lnk.UniqueID; 

    } 

} 

LinkButton lnk = gvMFDWise.FindControl("lnkbtn") as LinkButton; 
if (e.Row.RowType == DataControlRowType.DataRow) 
{ 
if (lnk != null) 
{ 
ScriptManager scriptManager2 = ToolkitScriptManager.GetCurrent(Page); 
scriptManager2.RegisterPostBackControl(lnk); 
} 

} 
1

Vous pouvez écrire ces codes également dans Page_load hors de publication. Chaque postback ils ont réassigné et il devrait fonctionner je pense

0

Je poste la solution du lien Brandon Culley fourni, je l'ai juste employé et c'est la bonne manière de faire ceci et fonctionne magnifiquement. Son lien pointe vers une version C# du code, je poste la version que j'ai utilisée pour VB. Voici the link encore au cas où quelqu'un l'aurait manqué.

Lorsque la ligne est créée dans gridview (l'événement RowCreated), trouvez votre bouton de lien dans cette ligne et l'enregistrer comme un contrôle postback via ScriptManager - cela lui permettra de faire un postback complet lorsque vous cliquez dessus:

Protected Sub gridMusicLibrary_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridMusicLibrary.RowCreated 

    'clicking the link button needs to do a full 
    'postback outside of the update panel 

    Dim lbtn As LinkButton = e.Row.FindControl("YourLinkButtonControlId") 

    If e.Row.RowType = DataControlRowType.DataRow Then 

     ScriptManager1.RegisterPostBackControl(lbtn) 

    End If 

End Sub 
Questions connexes