2015-05-01 2 views
2

Я читал сообщения и ссылки, а также статьи о viewstate и statebag, а также обратную передачу и создание страниц.Застрял в динамических элементах управления, Viewstate и Postback. Упрощенный пример

Я довольно приличный любитель, но этот человек просто не погружается, может ли кто-нибудь показать мне пример того, как это можно сделать?

ОК, вот что я пытаюсь сделать с этим примером

Создайте таблицу, в которой левая колонка имеет LinkButtons

При каждом LinkButton нажатии открывает кучу Imagebuttons в правой колонке

Каждый IMAGEBUTTON затем всплывает сообщение

проблема является ImageButton не вызывает сообщение

здесь передний конец:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="simple.aspx.vb" Inherits="simple" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>simple</title> 
</head> 
<body> 
<form id="form1" runat="server"> 

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> 

<asp:Table id="MainTable" runat="server"> 
<asp:TableRow> 

<asp:TableCell ID ="cell1" BackColor="LightBlue" /> 

<asp:TableCell ID ="cell2" BackColor="LightBlue" /> 

</asp:TableRow> 
</asp:Table> 

</form> 
</body> 
</html> 

и вот код:

Partial Class simple 
Inherits System.Web.UI.Page 

Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init 

    Dim NewTableButton As LinkButton = New LinkButton 
    NewTableButton.Text = "Text Created from 1st SQL Query" 
    AddHandler NewTableButton.Click, AddressOf LoadContacts 

    cell1.Controls.Add(NewTableButton) 

End Sub 

Protected Sub LoadContacts(sender As Object, e As System.EventArgs) 

    Dim TextPassedfromLinkButton As String = sender.text.ToString 

    Dim imgGear As New ImageButton 
    imgGear.ImageUrl = "../graphics/gear.jpg" 
    imgGear.AlternateText = "Text Created from 2nd SQL Query using the " _ 
& TextPassedfromLinkButton & " as a query parameter" 
    AddHandler imgGear.Click, AddressOf message 

    cell2.Controls.Add(imgGear) 

End Sub 

Protected Sub message(ByVal sender As Object, ByVal e As System.EventArgs) 

    Dim strText As String = sender.text.ToString 
    Dim alertString As String = "alert('" & strText & "');" 
    ScriptManager.RegisterStartupScript(Me, [GetType](), "showalert", alertString, True) 

End Sub 

End Class 

Вот исходный вид после нажатия на кнопку, которая должна всплывающее сообщение

<table id="MainTable"> 
<tr> 
<td id="cell1" style="background-color:LightBlue;"><a href="javascript:__doPostBack(&#39;ctl03&#39;,&#39;&#39;)">Text Created from 1st SQL Query</a></td> 
<td id="cell2" style="background-color:LightBlue;"><input type="image" name="ctl04" src="../graphics/gear.jpg" alt="Text Created from 2nd SQL Query using the Text Created from 1st SQL Query as a query parameter" /></td> 
</tr> 
</table> 

Так в то же время я получил это на работу (обновлено 10:49 est)

Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init 

    Dim NewTableButton As LinkButton = New LinkButton 
    NewTableButton.Text = "Text Created from 1st SQL Query" 
    'AddHandler NewTableButton.Click, AddressOf LoadContacts 
    AddHandler NewTableButton.Click, Function() LoadContacts(NewTableButton.Text) 

    cell1.Controls.Add(NewTableButton) 

    If IsPostBack Then 
     LoadContacts(NewTableButton.Text) 
    End If 

End Sub 

Private Function LoadContacts(strText As String) As Integer 

    Dim TextPassedfromLinkButton As String = strText 

    Dim imgGear As New ImageButton 
    imgGear.ID = "uniquename" 
    EnableViewState = False 
    imgGear.ImageUrl = "../graphics/gear.jpg" 
    imgGear.AlternateText = "Text Created from 2nd SQL Query using the " & TextPassedfromLinkButton & " as a query parameter" 
    AddHandler imgGear.Click, AddressOf message 

    cell2.Controls.Add(imgGear) 

    Return 0 

End Function 

Единственная проблема в том, я получаю 2 Одинаковые imgGears

duplicate buttons http://reinsmith.net/graphics/simple1.png message displayed http://reinsmith.net/graphics/simple2.png

ответ

1

Проблема здесь вы инстанцировании кнопку imgGear во время обработчика событий другой кнопки.

Это кажется логичным для этого, но обработчик событий для imgGear никогда не будет запущен, если imgGear будет создан и добавлен в дерево управления слишком поздно в жизненном цикле страницы, например. в обработчике событий или во время OnPreRender.

Очень сложно добиться того, что вы пытаетесь сделать, используя стандартные методы .NET. Я никогда не справлялся с этим. Вы также можете заметить, что текстовое поле, добавленное во время обработчика события, обычно не сохраняет его значение при обратной передаче, опять же потому, что оно слишком поздно добавлено в жизненный цикл страницы.

Вам действительно нужно определить контекст во время OnInit или CreateChildControls, потому что кнопка, созданная и добавленная в дерево управления на этой фазе , будет активирована обработчик обработчика.

Я разработал работу вокруг, хотя ... как и большинство работ обходного это не красиво ... но вы можете получить из жесткого места:

Во время OnInit вы можете сказать, если ваша кнопка вызвала postback, если это переменная-член. Intialise NewTableButton в contructor ... тогда вы можете определить, было ли нажато во время OnInit ...

Private NewTableButton as Button 

    Public Sub New() 
     MyBase.New() 
     NewTableButton = New LinkButton 
     NewTableButton.Text = "Text Created from 1st SQL Query" 
    End Sub 

    Protected Overrides Sub OnInit(e As EventArgs) 
     MyBase.OnInit(e) 
     cell1.Controls.Add(NewTableButton) 
     If Not IsNothing(Page.Request(NewTableButton.UniqueID)) Then 
      ' Create and add imgGear Button 
      LoadContacts 
     End If 
    End Sub 

Однако, текстовое поле/раскрывающийся значения недоступны в OnInit с использованием стандартных методов ... так, вы, возможно, придется а) Отложите чтение их до OnPreRender, или б) Используйте страницу. Request (Control.UniqueID), чтобы прочитать значение входных элементов управления во время OnInit.

Это одна из самых больших проблем, которые я имею с веб-разработки .Net, это вызывает головные боли, и я не люблю работу обходные ...

Я люблю знать, есть ли альтернатива этому обходной путь, но это единственный способ добиться того, чего вы пытаетесь достичь.

+0

ОК, теперь вот забавная часть. Это упрощенный пример. То, что я действительно пытаюсь сделать, это сначала создать набор кнопок ссылок из SQL-запроса с именами клиентов. Затем, когда щелкнуть LinkButton, выберите индивидуальное имя клиента и отобразите записи с именем клиента. например, индивидуальные контакты у каждого клиента. Затем для каждого контакта создайте ссылку или кнопку, чтобы ИЗМЕНИТЬ этот индивидуальный контакт в модальном всплывающем окне. Таким образом, переопределение может работать, если я могу обнаружить отдельный элемент управления, который отправил запрос и вытащил из него какую-то переменную, что имеет смысл? – mreinsmith

+0

Чувак, теперь ты изменил вопрос. Я помог вам разобраться в оригинальной проблеме и дал вам обходной путь. Было бы неплохо, если бы вы проявили свою признательность, а не меняли вопрос. –

+0

Приношу свои извинения, я ценю это и работаю (я думаю). У меня было много пожаров, чтобы потушить эти последние несколько дней и смогли вернуться к нему. Надеюсь, я смогу сегодня. Еще раз спасибо, а не преступление, предназначенное специально для тех, кто смог ответить! – mreinsmith

0

Проблема здесь в отношении жизненного цикла страницы и способа подключения. Когда вы уже на этапе обработчика событий жизненного цикла страницы, слишком поздно подключать события для новых элементов управления. Для этого вам нужно сделать что-то раньше.

Чтобы решить эту проблему, я могу представить себе 3 возможных способа сделать это более удобным для Webforms.

  1. Используйте подход, основанный на данных, создавая элемент управления ретранслятора, DataGridView или аналогичный и привязывая результаты вашего запроса Sql к этому. Часть этого решения может включать в себя запись некоторого необработанного html/javascript для использования с ретранслятором в сочетании с WebMethod, чтобы ваши события были в основном на стороне клиента и вообще не вызывали полных обратных передач. Учитывая, что мы уже знаем, что у вас есть SQL-запрос, это кажется наиболее естественным.
  2. Создайте элементы управления заполнителем, которые пусты и имеют свойство Visible, установленное для False для каждого возможного управления, в котором вы нуждаетесь. Затем во время выполнения назначьте данные существующим элементам управления и установите только Visible на True для тех элементов управления, которые вы фактически используете. Это часто лучший вариант, когда вы знаете, что будет относительно небольшое количество предметов с максимальной верхней границей.
  3. Создайте собственный элемент управления, который инкапсулирует концепцию ImageButton/Message/Event в единый элемент управления.

Кроме того, ваш комментарий к другому ответу предполагает, что вы можете рассмотреть отдельную страницу для просмотра/редактирования отдельного клиента и просмотра всех клиентов (возможно, с параметром querystring). На этой странице, для модального всплывающего окна, я поместил это в div, где эти данные и все остальные для поддержки всплывающего окна - уже загружены в начале страницы и просто используют javascript, а не код сервера, изменить страницу DOM, чтобы показать или скрыть всплывающее окно.

+0

Я обновил основной вопрос, чтобы показать свой прогресс – mreinsmith