I struggled a lot with how to show the modal panel when clicking on a button inside the grid.
In context: I have a data string with a string field that can contain plain text or a basic 64-encoded image, so I use a custom template to determine when to show the original content or the “View Image” button. This image will be opened on the modal panel, which should rise when the button is pressed.
This is the panel that I created as a control (ascx):
<asp:Panel ID="pnlModalOverlay" runat="server" Visible="true" CssClass="Overlay"> <asp:Panel ID="pnlModalMainContent" runat="server" Visible="true" CssClass="ModalWindow"> <div class="WindowTitle"> <asp:Label ID="lbTitle" runat="server" /> </div> <div class="WindowBody"> <asp:Panel ID="pnlContent" runat="server" Visible="true"> <asp:Image ID="imgContent" runat="server" CssClass="ImageView" /> </asp:Panel> <div class="Button"> <asp:Button ID="btnOk" runat="server" class="btn btn-default " Text="Close" OnClientClick="loadingPanel.Show();" /> </div> </div> </asp:Panel> </asp:Panel>
And this is the page and ASPxGridView where I want to use it:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true"> <ContentTemplate> <div style="margin-top: 12px;"> <asp:Button type="button" ID="btnShowImage" AutoPostBack="true" class="btn btn-default navbar-right" Text="Show Image" runat="server" Style="margin-left: 5px;" OnClientClick="loadingGridPanel.Show();" /> </div> <MyWorkspace:AlertModal ID="alertModal" runat="server" Visible="false" /> <MyWorkspace:ImageModal ID="imageModal" runat="server" Visible="false" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="mainGrid" /> </Triggers> </asp:UpdatePanel> <MyWorkspace:GridViewWrapper ID="mainGrid" runat="server" Visible="true" />
Codebihind:
public partial class MyPage : System.Web.UI.Page { protected override void OnInit(EventArgs e) { base.OnInit(e); btnShowImage.Click += new EventHandler(ShowImage); // This call works fine } protected void Page_Load(object sender, EventArgs e) { try { if (!IsPostBack) { mainGrid.CanEditItems = true; mainGrid.CustomTemplates.Add(new CustomColumnTemplate { columnName = "Id", template = new LinkColumn(CreateParentLink, "Go to parent") }); mainGrid.CustomTemplates.Add(new CustomColumnTemplate { columnName = "Value", template = new ButtonColumn(ShowImage, "View Image") }); // This one doesn't works } } catch (Exception ex) { modalAlerta.Show("Page_Load", ex.Message, false, false, ""); } } void ShowImage() { modalImagem.Show(); // Set Modal Visible property to True // UpdatePanel1.Update(); <-- Tryin' force it to work with no success } }
Creating a ButtonColumn Template:
public class ButtonColumn : System.Web.UI.ITemplate { private Action action; private string controlId; private string tooltip; public ButtonColumn(Action onClick, string toolTip) { this.action = onClick; this.controlId= "btnShowImage"; this.tooltip = toolTip; } public void InstantiateIn(System.Web.UI.Control container) { GridViewDataItemTemplateContainer gridContainer = (GridViewDataItemTemplateContainer)container; if (System.Text.RegularExpressions.Regex.IsMatch(gridContainer.Text, "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$")) { ImageButton button = new ImageButton(); button.ID = idControle; button.ImageUrl = "/Images/html5_badge_64.png"; button.Width = 20; button.Height = 20; button.ToolTip = tooltip; button.Click += (s, a) => { if (onClick != null) onClick(); }; container.Controls.Add(button); } else { Label label = new Label() { Text = gridContainer.Text, ToolTip = tooltip }; container.Controls.Add(label); } } }
Calling a method by pressing the btnShowImage button works fine. But when I make the same call with a single ImageButton (or button) inside the gridview, it does not work. Both calls reach the ShowImage method.
Any help would be greatly appreciated. Thanks to everyone.
EDIT 1: GridView is encapsulated in a GridViewWrapper (there I dynamically build columns using a combination of class properties obtained by reflection and saved metadata), this class has too much code to exchange here, and I don't think that is the reason. In addition, I performed in debug mode and passed step by step each corresponding method inside this.
Method for adding a column:
CustomColumnTemplate customTemplate = CustomTemplates.FirstOrDefault(f => f.columnName == metadata.ColumnIdName); gridView.Columns.Add(new GridViewDataColumn() { FieldName = metadata.ColumnIdName, VisibleIndex = GetVisibleIndexByColumnIdName(metadata.ColumnIdName), Caption = metadata.Caption, Width = new Unit(DefaultColumnWidth, UnitType.Pixel), DataItemTemplate = customTemplate == null ? null : customTemplate.template });
I made sure that the ShowImage method ShowImage taken, but it behaves like UpdatePanel1 not updated