2011-02-09 194 views
3

我创建了一个名为“Actions”的内部属性的UserControl,它是“Action”对象的列表。代码如下所示:自定义控件的内部属性的ASP.Net绑定属性

[ParseChildren(true)] 
public class MyLink : UserControl 
{ 
    readonly List<Action> _actions = new List<Action>(); 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    public List<Action> Actions 
    { 
     get { return _actions; } 
    } 

    public string Text { get;set; } 
    public string Url { get;set; } 
    public string MenuName { get; set; } 

    protected override void Render(HtmlTextWriter writer) 
    { 
     //Build link 
     StringBuilder sb = new StringBuilder(); 
     sb.Append(@" 
      <table class=""myLink""> 
       <tr> 
        <td class=""myLinkLeft""><a href=" + Url + @">" + Text + @"</a></td> 
        <td class=""myLinkRight " + MenuName + @"_trigger"">&nbsp;</td> 
       </tr> 
      </table> 
     "); 

     //Build actions 
     sb.Append("<ul id=\"" + MenuName + "_actions\" class=\"contextMenu\">"); 

     foreach (Action action in _actions) 
     { 
      sb.Append("<li class=\"" + action.CssClass + "\"><a href=\"#" + action.Url + "\">" + action.Text + "</a></li>"); 
     } 

     sb.Append("</ul>"); 

     writer.Write(sb.ToString()); 
    } 
} 

public class Action : UserControl 
{ 
    public string Url { get; set; } 
    public string Text { get; set; } 
    public string ImageUrl { get; set; } 
    public string CssClass { get; set; } 
} 

如果我当时把这个代码在我一个的DataRepeater内ASPX,它工作正常:

<uc1:MyLink runat="server" Url="/" Text='<%#DataBinder.Eval(Container.DataItem,"Text") %>' MenuName="contextMenu" id="contextMenu"> 
    <Actions> 
     <uc1:Action runat="server" Url="http://mysite.com" Text="MyUrl" /> 
     <uc1:Action runat="server" Url="http://google.com" Text="Google" /> 
    </Actions> 
</uc1:MyLink> 

但是,如果我尝试将数据绑定到的属性动作元素,像这样:

<uc1:MyLink runat="server" Url="/" Text='<%#DataBinder.Eval(Container.DataItem,"Text") %>' MenuName="contextMenu" id="contextMenu"> 
    <Actions> 
     <uc1:Action runat="server" Url='<%#DataBinder.Eval(((RepeaterItem)Container.Parent).DataItem,"Url") %>' Text="MyUrl" /> 
     <uc1:Action runat="server" Url="http://google.com" Text="Google" /> 
    </Actions> 
</uc1:MyLink> 

我只是得到实际的文字 “<%#DataBinder.Eval的(((的RepeaterItem)Container.Parent).DataItem,” URL “)%>” 分配给Url属性,而不是e按照我的预期评估服务器表达。

我已经GOOGLE了几个小时,但似乎无法找到其他人试图做到这一点。任何想法,为什么这不工作,以及如何解决它?

感谢, 比约恩·

回答

0

我结束了对最内层的数据绑定使用标记,然后在绑定的控制中处理替换。因此,ASPX代码如下所示:

<uc1:MyLink runat="server" Url="/"> 
    <Actions> 
     <uc1:Action Url="/Page.aspx?cpr=##cpr##&opgaveId=##id##" /> 
     <uc1:Action Url="/Test.aspx" /> 
    </Actions> 
</uc1:MyLink> 

和添加的CS这样的代码:

protected override void OnInit(EventArgs e) 
{ 
    DataBinding += BindData; 
} 

public void BindData(object sender, EventArgs e) 
{ 
    MyLink pl = (MyLink) sender; 
    IDataItemContainer container = (IDataItemContainer) pl.NamingContainer; 
    foreach (Action action in _actions) 
    { 
     action.Url = ReplaceTokens(action.Url, container); 
     action.Text = ReplaceTokens(action.Text, container); 
    } 
} 

private static string ReplaceTokens(string text, IDataItemContainer container) 
{ 
    Regex re = new Regex("##.*?##", RegexOptions.Compiled | RegexOptions.Singleline); 
    StringBuilder sb = new StringBuilder(text); 

    foreach (Match m in re.Matches(text)) 
    { 
     string tokenValue = DataBinder.GetPropertyValue(container.DataItem, m.Value.Substring(2, m.Value.Length - 4), "{0}"); 
     sb.Replace(m.Value, tokenValue); 
    } 
    return sb.ToString(); 
} 
0

在你的aspx设置DataRepeater.Datasource的集合或静态或从数据库中获取列表...

,而不是使用的DataRepeater尽量使内部的循环列出你已经重新必须创建它,并创造新的动力作用,并且在Page_Load中或page_init

Action a; 
foreach(object x in objects) 
{ 
    a= new Action(); 
    a.Url = ... ; 
    a.Text = ... ; 
    MyLink.Actions.Add(a); 
} 

问候

+0

我不太明白你的意思了,对不起。我自己解决了,我会在这里发布答案。 – Bjoern