ASP.NET Dynamic User Controls - PullRequest
       6

ASP.NET Dynamic User Controls

3 голосов
/ 19 января 2010

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

Я программно добавляю некоторые пользовательские элементы управления в PlaceHolder, которые есть на простой странице aspx. Все пользователи правильно контролируют работу Postback, за исключением одного, на котором есть Gridview.

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

Я посмотрел на исходный файл для страницы, которая генерируется до и после первого щелчка, javascript, используемый для вызова изменений обратной передачи, т.е.

Перед первым щелчком мыши: onclick = "javascript: __ doPostBack ('tmpControlID $ sgvPrimaryEmploymentHistory', 'Select $ 0')"

После первого щелчка: onclick = "javascript: __ doPostBack ('OFFHome1 $ tmpControlID $ sgvPrimaryEmploymentHistory', 'Select $ 0')"

OFFHome1 - родительский пользовательский элемент управления, который существует на странице aspx. Все остальные элементы управления добавляются в этот элемент-заполнитель, т. Е.

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="OFFHome.ascx.vb" Inherits="UmbracoUserControls.OFFHome" %>
<asp:PlaceHolder ID="phOFFSection" runat="server"></asp:PlaceHolder>

Ничего сложного. Затем в коде позади элементов управления загружаются в заполнитель с помощью следующего:

Private Sub LoadNextOFFStep()
    Dim ControlName As String = "TestControl.ascx"
    phOFFSection.Controls.Clear()
    If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
        Dim NewControl As Object = LoadControl(ControlName)

        With NewControl
            .ID = USERCONTROLNAME
            Dim StepCompleted As Boolean = .FillControl()
            If StepCompleted Then
                Exit Sub
            End If
            Dim AllowSkip As Boolean = .AllowSkip()
            btnSkip.Visible = AllowSkip
        End With
        phOFFSection.Controls.Add(NewControl)
    End If
End Sub

Опять же, ничего слишком сложного. USERCONTROLNAME - это просто const со значением "tmpControlID".

Элемент управления, который доставляет мне проблемы, немного сложен, я изначально использовал созданный нами пользовательский элемент управления GridView, но удалил его и заменил его на стандартный asp, чтобы увидеть, возникает ли проблема по-прежнему, и он делает.

Любая кнопка, на элементе управления которой запускается обратная передача, не будет работать в первый раз, и все последующие нажатия будут работать правильно. При первом щелчке вызывается событие Page_Load, но это так.

Что я делаю не так ??

Ответы [ 2 ]

1 голос
/ 20 января 2010

После слишком большого количества времени, потраченного на это, я наконец-то решил это.

Это было связано с порядком событий, но только не там, где я думал. Функция FillControl вызывалась до того, как пользовательский элемент управления был добавлен в PlaceHolder. Я изменил его, чтобы он вызывался после добавления пользовательского элемента управления в PlaceHolder, и теперь он работает впервые.

В основном код выглядит следующим образом:

Private Sub LoadNextOFFStep()
    Dim ControlName As String = "TestControl.ascx"
    phOFFSection.Controls.Clear()
    If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
        Dim NewControl As Object = LoadControl(ControlName)

        With NewControl
            .ID = USERCONTROLNAME
            Dim AllowSkip As Boolean = .AllowSkip()
            btnSkip.Visible = AllowSkip
        End With
        phOFFSection.Controls.Add(NewControl)
        Dim StepCompleted As Boolean = CType(phOFFSection.Controls(0), Object).FillControl()
        If StepCompleted Then
            LoadNextOFFStep()
            Exit Sub
        End If
    End If
End Sub

Спасибо всем за помощь.

0 голосов
/ 19 января 2010

Что ж ... ответ на первый вопрос прост: первый раз он не работает, потому что идентификатор элемента управления (или, скорее, в сценарии обратной передачи) отличается при последующих загрузках страницы.Он работает при последующих щелчках, потому что идентификатор элемента управления остается неизменным.

Теперь о том, ПОЧЕМУ это ... намного сложнее!Но, вероятно, что-то здесь связано с порядком операций.

Попробуйте явно установить значение NamingContainer для NewControl:

    With NewControl
        .NamingContainer = OffHomeOne; // whatever
        .ID = USERCONTROLNAME
...