【问题标题】:Getting a scriptmanager into a dynamically rendered page让脚本管理器进入动态呈现的页面
【发布时间】:2011-02-07 12:29:23
【问题描述】:

我们正在像这样动态渲染用户控件:

public string RenderControl(string pathcontrol)
{
    string html;

    var page = new Page();
    var control = page.LoadControl(path);            
    page.Controls.Add(control);

    // do stuff to the control (give it some data to work on)

    using (var writer = new StringWriter())
    {
        HttpContext.Current.Server.Execute(page, writer, false);
        html = writer.ToString();
    }

    return html;
}

这使我们在正常呈现页面时可以像在呈现对 ajax 调用的响应时一样使用相同的用户控件。但是,当添加本身包含 scriptmanagerProxy 的控件时,我们会遇到新的 Page 对象不包含 ScriptManager 或 ScriptManager 需要在其中运行的 HtmlForm 的问题。

有没有办法解决这个问题?

你的 安德烈亚斯

【问题讨论】:

    标签: asp.net ajax user-controls html-rendering


    【解决方案1】:

    正如其他人所说,如果您的 Page 对象已完成,您可以轻松地动态添加 ScriptManger [Add ScriptManager to Page Programmatically?

    您可以尝试使用BuildManager.CreateInstanceFromVirtualPath() 创建 Page 对象吗?您的问题可能是您如何创建该对象。除了更新 Page 对象之外,创建新页面还有很多工作。

    例如。

    Page page 
           = BuildManager.CreateInstanceFromVirtualPath("~/Test.aspx", typeof(Page))
    

    有关更多背景信息,另请参阅 http://www.west-wind.com/weblog/posts/120530.aspx

    【讨论】:

    • 谢谢!我得到了这个工作,但最终呈现的输出现在包含
    • 我获取了渲染的字符串并剥离了我不需要的所有内容,留下了所需的标记,甚至在响应中使用 ScriptManager 注册的 javascript 块。谢谢!
    【解决方案2】:

    你可以这样做吗:

    page.Form.Controls.AddAt(0, New ScriptManager())
    

    编辑:我认为您还需要将控件添加到页面的表单中,而不仅仅是页面本身,对吧?据我了解,表单是使用页面创建的,但如果不是,您应该可以这样做:

    page.Form = new HtmlForm()
    

    您可能还需要执行以下操作:

    page.Controls.Add(page.Form)
    

    【讨论】:

    • page.Form在页面上为null,page.Form不可设置(只有getter)
    • page.Form 是在 OnInit 处理程序期间从 HtmlForm 实例内部设置的,因此您需要在创建 HtmlForm 时设置其 Page 属性。
    【解决方案3】:

    当然,诀窍是将它添加到页面的 Init 事件处理程序中。您可以使用:

    Page.Init += delegate {
    
      // check for script manager
      if( ScriptManager.GetCurrent(Page) == null ) {
    
        ScriptManager m = new ScriptManager();
        m.ScriptMode = ScriptMode.Release;
        Page.Form.Controls.AddAt(0, m);
    
      }
    
    }
    

    如果可以,我建议您避免向您的页面动态添加表单。例如,上面的代码 sn -p 假设页面上已经存在一个表单。

    更新

    当然,感谢安德烈亚斯指出这一点。这是一个更新。因此,Page.Form 没有设置器 - 但您是正确的,因为您可以将新的 HtmlForm 添加到 Controls 集合中。添加后,Page.Form 属性不再为空。如上所示,这将允许您动态添加 ScriptManager。下面是一个代码示例,展示了这种工作方式(ASPX 文件是一个简单的页面没有服务器端表单):

    public partial class Pages_Test_DynamicFormSample : Page {
    
        protected void Page_Init(object sender, EventArgs e) {
    
            Controls.Add( new HtmlForm() );
    
            ScriptManager m = new ScriptManager();
            m.ScriptMode = ScriptMode.Release;
            Form.Controls.AddAt(0, m);
    
        }
    
        protected void Page_Load(object sender, EventArgs e) {
    
            // ScriptManager test
            var t1 = new System.Web.UI.WebControls.TextBox();
            var t2 = new System.Web.UI.WebControls.TextBox();
            Form.Controls.Add( t1 );
            Form.Controls.Add( t2 );
    
            ScriptManager.GetCurrent(Page).SetFocus( t2 );
    
        }
    
    }
    

    享受 - 顺便说一句,显然不需要将 ScriptManager 的 ScriptMode 设置为 Release。我们这样做只是为了避免在 ASP.NET 脚本运行时的 Debug 版本中发现一些 JavaScript 错误。

    【讨论】:

    • 当我们在代码中更新页面时,问题是该页面上没有表单,因此您的 sn-p 中的假设是错误的。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签