2010-06-29 93 views

回答

6

UPDATE 这是一个完整的工作示例。这里发生了一些事情:

  1. 使用替换控件的回调来呈现您需要的usercontrol的输出。
  2. 使用覆盖VerifyRenderingInServerForm和EnableEventValidation的自定义页面类来加载控件,以防止在usercontrol包含需要表单标记或事件验证的服务器控件时引发错误。

这里的标记:

<asp:Substitution runat="server" methodname="GetCustomersByCountry" /> 

这里的回调

public string GetCustomersByCountry(string country) 
{ 
    CustomerCollection customers = DataContext.GetCustomersByCountry(country); 

    if (customers.Count > 0) 
     //RenderView returns the rendered HTML in the context of the callback 
     return ViewManager.RenderView("customers.ascx", customers); 
    else 
     return ViewManager.RenderView("nocustomersfound.ascx"); 
} 

这里的辅助类来呈现用户控制

public class ViewManager 
{ 
    private class PageForRenderingUserControl : Page 
    { 
     public override void VerifyRenderingInServerForm(Control control) 
     { /* Do nothing */ } 

     public override bool EnableEventValidation 
     { 
      get { return false; } 
      set { /* Do nothing */} 
     } 
    } 

    public static string RenderView(string path, object data) 
    { 
     PageForRenderingUserControl pageHolder = new PageForUserControlRendering(); 
     UserControl viewControl = (UserControl) pageHolder.LoadControl(path); 

     if (data != null) 
     { 
      Type viewControlType = viewControl.GetType(); 
      FieldInfo field = viewControlType.GetField("Data"); 
      if (field != null) 
      { 
       field.SetValue(viewControl, data); 
      } 
      else 
      { 
       throw new Exception("ViewFile: " + path + "has no data property"); 
      } 
     } 

     pageHolder.Controls.Add(viewControl); 
     StringWriter result = new StringWriter(); 
     HttpContext.Current.Server.Execute(pageHolder, result, false); 
     return result.ToString(); 
    } 
} 

看到这些相关的问题:

+0

太棒了!谢谢 – mohamadreza 2010-07-25 08:05:43

+0

-1参考资料来源:http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for -non_2D00_UpdatePanel-scenarios.aspx – 2012-09-10 16:22:05

-1

相当某些你不能做到这一点 - Substitution控件将允许你插入一个字符串转换为outputcached页。
如果您考虑服务器控件的整个输出,这可能是一个<table>,这会破坏您的精心制作的标记和/或需要加载<script>注入页面的东西 - 而注入单个字符串是相对简单的东西。

0

一个Micah的回答漏掉的是,替代函数必须static,接受HttpContext参数,并返回一个东西string。有关更多信息,请参阅this msdn page

我也扩展了Micah的辅助类,使它更加灵活一些。

标记

<asp:Substitution ID="Substitution1" MethodName="myFunction" runat="server" /> 

再次实行

public static string myFunction(HttpContext httpContext){ 
    ViewManager vm = new ViewManager(); 

    //example using a Button control 

    Button b = new Button(); 
    b.Text = "click me"; //we can set properties like this 

    //we can also set properties with a Dictionary Collection 
    Dictionary<string,object> data = new Dictionary<string,object>(); 
    data.add("Visible",true); 

    String s = vm.RenderView(b,data); //don't do anything (just for example) 

    //we can also use this class for UserControls 
    UserControl myControl = vm.GetUserControl("~mypath"); 

    data.clear(); 
    data.add("myProp","some value"); 

    return vm.RenderView(myControl,data); //return for Substitution control 
} 

using System.IO; 
using System.ComponentModel; 
public class ViewManager 
{ 
    private PageForRenderingUserControl pageHolder; 
    public ViewManager() 
    { 
     pageHolder = new PageForRenderingUserControl(); 
    } 

    public UserControl GetUserControl(string path) 
    { 
     return (UserControl)pageHolder.LoadControl(path); 
    } 

    public string RenderView(Control viewControl, Dictionary<string, object> data) 
    { 
     pageHolder.Controls.Clear(); 
     //Dim viewControl As UserControl = DirectCast(pageHolder.LoadControl(Path), UserControl) 

     if (data != null) { 
      Type viewControlType = viewControl.GetType(); 


      dynamic properties = TypeDescriptor.GetProperties(viewControl); 

      foreach (string x in data.Keys) { 
       if ((properties.Item(x) != null)) { 
        properties.Item(x).SetValue(viewControl, data[x]); 
       } 
      } 
     } 

     pageHolder.Controls.Add(viewControl); 
     StringWriter result = new StringWriter(); 
     HttpContext.Current.Server.Execute(pageHolder, result, false); 
     return result.ToString(); 
    } 

    private class PageForRenderingUserControl : Page 
    { 
     public override void VerifyRenderingInServerForm(Control control) 
     { 
      // Do nothing 
     } 

     public override bool EnableEventValidation { 
      get { return false; } 
      // Do nothing 
      set { } 
     } 
    } 

} 

由于Micah代码

相关问题