2010-02-28 32 views
2

比方說,我有我從數據庫檢索像字符串:
「Lorem存有悲坐阿梅德,consetetur sadipscing elitr,SED直徑nonumy eirmod tempor invidunt UT labore等{{超鏈接| navigateurl ='/ foo.aspx '}} dolore magna aliquyam。「如何從字符串動態呈現asp.net控件?

現在可以將此字符串分配給標籤的文本屬性。
我想是解析{{超鏈接| navigateurl =「/ foo.aspx」}}

<asp:HyperLink ID="IDLink" runat="server" Text="foo" NavigateUrl="/foo.aspx"/> 

替換它,並指定整個文本,包括超鏈接 - 控制的標籤。

這可能嗎?我想我可以使用反射來創建控件並設置屬性。 (超鏈接控制只是一個例子) 但我可以設法將asp.net控件重新插入到字符串中以確保超鏈接呈現爲服務器控件?

我希望你明白我想要什麼。如果沒有,請隨時發表評論。

EDIT1:

什麼叫 「轉讓整個 文本,包括超鏈接 - 控制 的標籤。」 是什麼意思?你能否解釋一下, 這樣做的理由是什麼?

我認爲它不會將控件分配到字符串中,因爲asp.net控件不能適合字符串。

經過一番思考後,我找到了一種方法來實現我的目標。這將是創建一個佔位符(我把它命名爲A)。其中一些文字控制將被添加。另外我會創建一個佔位符(我將它命名爲B),將我的超鏈接添加到B中,並將A添加到B. 但我認爲是過度殺傷的方法。

我之所以開始考慮這個問題,是爲了獲得對Server.MapPath的訪問權限,而無需替換字符串中的出現。我希望能夠在我的CMS中使用相對路徑,這些路徑會像超鏈接中的NavigateUrl屬性一樣呈現。 不過我認爲我的問題與動態創建值得思考

+0

什麼叫'「分配整個文本,包括超鏈接 - 控制的標籤。」意思'?你能否解釋一下,這樣做的原因? – 2010-02-28 14:02:47

回答

4
public class Program 
    { 
     static void Main(string[] args) 
     { 
      ParserBase parser = new ParserBase(); 

      Console.WriteLine(parser.DynamicRenderControl<HyperLink>(parser.Parse(""))); 
      Console.ReadLine(); 
     } 
    } 

    public class ParserBase 
    { 
     public virtual Dictionary<string, string> Parse(string stringToParse) 
     { 
      //... 
      // parse the stringToParse 
      //... 
      Dictionary<string, string> parsedPropertiesValues = new Dictionary<string, string>(); 
      parsedPropertiesValues.Add("NavigateUrl", @"http://www.koolzers.net"); 
      return parsedPropertiesValues; 
     } 

     protected virtual void SetProperty<T>(T obj, string propertyName, string value) where T : WebControl 
     { 
      typeof(T).GetProperty(propertyName).SetValue(obj, value, null); 
     } 


     public string DynamicRenderControl<T>(Dictionary<string, string> parsedPropertiesValues) where T : WebControl, new() 
     { 
      StringBuilder sb = new StringBuilder(); 
      using (T control = new T()) 
      { 
       foreach (KeyValuePair<string, string> keyValue in parsedPropertiesValues) 
       { 
        SetProperty<T>(control, keyValue.Key, keyValue.Value); 
       } 

       using (StringWriter tw = new StringWriter(sb)) 
       { 
        using (HtmlTextWriter w = new HtmlTextWriter(tw)) 
        { 
         control.RenderControl(w); 
        } 
       } 

      } 
      return sb.ToString(); 
     } 
    } 
+0

不錯的一個。雖然沒有渲染子控件並將html輸出添加回字符串中。 – citronas 2010-02-28 14:59:42

+0

你是一個天才;) – citronas 2010-03-05 19:36:11

+0

這就是我一直在尋找!:) – 2015-01-22 07:42:47

1

我相信這是可能的,如果您將文本分成2個標籤而不是一個。我寫了一個快速示例來演示。從數據庫中解析字符串時,如果在動態控制之前和之後都有文本,則只需設置DynamicControl的BeginText和EndText屬性。

public class DynamicControl 
{ 
    public String BeginText { get; set; } 
    public String EndText { get; set; } 
    public String ControlName { get; set; } 
    public Dictionary<String, String> ControlProperties { get; set; } 
} 

public partial class _Default : System.Web.UI.Page 
{ 
    protected override void OnInit(EventArgs e) 
    { 
     base.OnInit(e); 
     //read strings from db 
     var dynamicControlStrings = GetStringsFromDB(); 
     //parse strings into list of dynamicControls 
     var dynamicControls = ParseStringsToDynamicControls(dynamicControlStrings); 
     foreach (var dynamicControl in dynamicControls) 
     { 
      CreateControl(dynamicControl.BeginText, dynamicControl.EndText, dynamicControl.ControlName, dynamicControl.ControlProperties); 
     } 
    } 

    private void CreateControl(string beginText, string endText, string controlName, Dictionary<String, String> controlProperties) 
    { 
     var beginLabel = new Label() 
     { 
      Text = beginText 
     }; 

     var dynamicControl = GenerateDynamicControl(controlName, controlProperties);   

     var endLabel = new Label() 
     { 
      Text = endText 
     }; 

     var span = new HtmlGenericControl("span"); 
     span.Controls.Add(beginLabel); 
     span.Controls.Add(dynamicControl); 
     span.Controls.Add(endLabel); 

     form1.Controls.Add(span);   
    } 

    //you would create your dynamic control here (such as the hyperlink) based on the control name and use reflection to set the properties 
    private WebControl GenerateDynamicControl(string controlName, Dictionary<String, String> controlProperties) 
    {   
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

    }  
} 
+0

是的,這樣的想法進入了我的腦海。你怎麼看,這會有多高效? – citronas 2010-02-28 14:46:53

+1

反思肯定比直接訪問某個對象慢,但我認爲這篇博文總結了很多常見的誤解http://www.west-wind.com/weblog/posts/351.aspx。我假設你不會每頁自動生成數十萬個控件,所以你應該沒問題。儘管如此,您可能想要考慮動態控件令牌。如果你正在計劃使用類似Activator.CreateInstance(...)的東西,你會希望在你的令牌中有完整的類型名稱來讓你自己更容易。 – 2010-02-28 14:56:34