2011-02-09 2 views
3

Я создал UserControl с внутренним свойством, называемым «Actions», который представляет собой список объектов «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; } 
} 

Если я затем поместить этот код в моем 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> 

Однако, если я пытаюсь связать данные с атрибутами Действие таких элементов, как так:

<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 как я и ожидал.

Я искал это в течение нескольких часов, но, похоже, не может найти кого-то другого, пытающегося это сделать. Любые идеи, почему это не работает и как обойти это?

Спасибо, Бьорна

ответ

0

Я закончил тем, что использовал токены для самой внутренней привязки данных, а затем обрабатывал замену в моем контроле на bind. Таким образом, код 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

установить DataRepeater.Datasource в вашем ASPX в коллекцию или статический список или получить из базы данных ...

вместо того, чтобы использовать 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

Смежные вопросы