Я много боролся с тем, как показать модальную панель при нажатии кнопки внутри сетки.
В контексте: у меня есть строка данных со строковым полем, которое может содержать простой текст или изображение в кодировке base 64, поэтому я использую настраиваемый шаблон, чтобы определить, когда показывать необработанный контент или кнопку «Просмотреть изображение». Это изображение будет открыто на модальной панели, которая должна подниматься по нажатию кнопки.
Это панель, которую я создал как элемент управления (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>
А это страница и ASPxGridView, где я хочу это использовать:
<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>
<!-- Some data filter controls -->
<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" />
Компонент кода:
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's Visible property to True
// UpdatePanel1.Update(); <-- Tryin' force it to work with no success
}
}
Создание шаблона ButtonColumn:
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);
}
}
}
Вызов метода по нажатию кнопки btnShowImage
работает нормально. Но когда я делаю тот же вызов одной кнопкой ImageButton (или кнопкой) внутри сетки, это не работает. Оба вызова достигают метода ShowImage.
Любая помощь будет оценена по достоинству. Спасибо вам всем.
EDIT 1: GridView инкапсулирован в GridViewWrapper
(там я создаю столбцы динамически, используя комбинацию свойств класса, полученных путем отражения, и сохраненных метаданных), этот класс имеет слишком много кода, чтобы поделиться здесь, и я не думаю причина в этом. Кроме того, я выполнил в режиме отладки и прошел через него шаг за шагом каждый соответствующий метод внутри этого.
Метод добавления столбца:
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
});
Я убедился, что метод ShowImage
работает, но он ведет себя так, как будто метод UpdatePanel1
не был обновлен.