【问题标题】:ASP.Net binding attributes of a custom control's inner property自定义控件内部属性的 ASP.Net 绑定属性
【发布时间】:2011-06-24 02:29:52
【问题描述】:

我创建了一个带有名为“Actions”的内部属性的 UserControl,它是一个“Action”对象列表。代码如下所示:

[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; }
}

如果我随后将此代码放在我的 aspx 中的 DataRepeater 中,它可以正常工作:

<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>

但是,如果我尝试将数据绑定到 Action 元素的属性,如下所示:

<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>

我只得到分配给 Url 属性的实际文本“”,而不是我预期的评估的服务器表达式.

我已经用谷歌搜索了几个小时,但似乎找不到其他人试图这样做。任何想法为什么这不起作用以及如何解决它?

谢谢, 比约恩

【问题讨论】:

    标签: c# asp.net data-binding user-controls nested


    【解决方案1】:

    您将 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);
    }
    

    问候

    【讨论】:

    • 我不太确定我明白你的意思,抱歉。我自己解决了,我会在这里发布答案。
    【解决方案2】:

    我最终使用令牌进行最内部的数据绑定,然后在绑定时在我的控件中处理替换。所以 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();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-29
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多