我创建了一个UserControl,其内部属性称为“Actions”,它是一个“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""> </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>
但是,如果我尝试将数据绑定到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>
我只是得到实际文本“&lt;%#DataBinder.Eval(((RepeaterItem)Container.Parent).DataItem,”Url“)%&gt;”分配给Url属性,而不是我期望的评估服务器表达式。
我用谷歌搜索了几个小时,但似乎找不到其他任何人试图这样做。任何想法为什么这不起作用以及如何解决它?
谢谢, 比约恩
答案 0 :(得分:0)
将aspx中的DataRepeater.Datasource设置为集合或静态列表或从数据库中获取...
而不是使用DataRepeater尝试在该列表中创建一个循环,您必须创建它并创建新的动态Action,并在page_load或page_init
中Action a;
foreach(object x in objects)
{
a= new Action();
a.Url = ... ;
a.Text = ... ;
MyLink.Actions.Add(a);
}
此致
答案 1 :(得分: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();
}