ASP.NET动态用户控件

时间:2010-01-19 04:15:36

标签: asp.net vb.net gridview postback

我确信这个问题已被问过一百万次,但是我找不到能够解决问题的答案。

我正在以编程方式向PlaceHolder添加一些自定义用户控件,我在一个简单的aspx页面上。所有用户控制Postback的工作正常,除了其上有Gridview的那个。

出于某种原因,在此控件中触发的任何回发都不会在第一次单击时调用指定的事件,但是将来所有点击它都可以正常工作。我不知道为什么会出现这种情况,但我发现了许多解决方案,建议在ascx用户控件中添加一个ID,但这在我的情况下不起作用。

我已经看了第一次点击前后生成的页面的源文件,javascript用于调用回发更改,即

在第一次点击之前:onclick =“javascript:__ doPostBack('tmpControlID $ sgvPrimaryEmploymentHistory','Select $ 0')”

首次点击后:onclick =“javascript:__ doPostBack('OFFHome1 $ tmpControlID $ sgvPrimaryEmploymentHistory','选择$ 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只是一个值为“tmpControlID”的const。

给我带来麻烦的控件有点复杂,我最初使用的是我们创建的自定义GridView控件,但已将其删除并将其替换为标准的asp,以查看问题是否仍然存在,并且确实

任何触发回发的控件按钮都会在第一次失败,以后所有点击都能正常工作。在第一次单击时,将调用Page_Load事件,但就是这样。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

花了太多时间在这上面,我终于解决了。

这与事件的顺序有关,但不是我想到的地方。在将User Control添加到PlaceHolder之前调用FillControl函数。我更改了这个,以便在将用户控件添加到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

感谢大家的帮助。

答案 1 :(得分:0)

嗯......第一个问题的答案很简单:它第一次失败,因为控件的ID(或者更确切地说,在回发脚本中)在后续页面加载时是不同的。它适用于后续点击,因为控件ID保持不变。

现在为什么那样......更加艰难!但这可能与此处的操作顺序有关。

尝试显式设置NewControl的NamingContainer值:

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