代码之家  ›  专栏  ›  技术社区  ›  citronas

如何从字符串动态呈现ASP.NET控件?

  •  3
  • citronas  · 技术社区  · 14 年前

    假设我有一个从数据库中检索的字符串,比如:
    “Lorem Ipsum Dolor Sit Amet,Consetetur Sadipscing Eliter,Sed Diam Nonumy Eirmod Tempor Invidunt ut Laboure et等 超链接导航URL='/foo.aspx' 多洛尔·马格纳·阿利库亚姆。”

    现在可以将此字符串分配给标签的文本属性。
    我要分析的是 超链接导航URL='/foo.aspx' 换成

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

    并将整个文本(包括超链接控件)分配给标签。

    这是可能的吗?我想我可以使用反射来创建控件和设置属性。(超链接控件只是一个示例) 但是,我可以设法将ASP.NET控件插入到字符串中以确保超链接呈现为服务器控制吗?

    我希望你明白我想要什么。如果没有,请随时发表评论。

    Eddi1:

    你说的“分配整个”是什么意思 包含超链接控件的文本 贴上标签。“?你能解释一下吗? 这样做的原因是什么?

    我认为将控件分配到字符串中是行不通的,因为ASP.NET控件不能放入字符串中。

    经过一番思考,我找到了实现目标的方法。那就是创建一个占位符(我将其命名为a)。其中将添加一些文本控件。另外,我会创建一个占位符(我将其命名为B),将我的超链接添加到B,并将A添加到B。 但我认为这是过度杀人的方法。

    我之所以开始考虑这个问题,是为了在不替换字符串中出现的内容的情况下访问server.mappath。我希望能够使用CMS中的相对路径,这些路径可以像来自超链接的navigateurl属性一样呈现。 然而,我认为我关于动态创造的问题值得思考。

    2 回复  |  直到 14 年前
        1
  •  4
  •   garik    14 年前
    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();
            }
        }
    
        2
  •  1
  •   Matt Dearing    14 年前

    我相信这是可能的,如果你把你的文本分成两个标签而不是一个。我写了一个快速的样品来演示。当您从数据库分析字符串时,如果动态控件前后有文本,则不只是设置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)
        {
    
        }    
    }