views:

36

answers:

1

I want to make panels Visibility true or false based on a result of a Func.

I have a page with controls as in the following code:

<asp:Panel ID="Panel2" runat="server">
    <asp:Panel ID="Panel3" runat="server">
        <c:PermissionPanel ID="P1" runat="server" ValidationGroup="Val1">
            Validation Group 1 - OK
        </c:PermissionPanel>
    </asp:Panel>
</asp:Panel>

<c:PermissionPanel ID="P2" runat="server" ValidationGroup="Val1">
    Validation Group 1 - OK
</c:PermissionPanel>

<hr />

<c:PermissionPanel ID="P3" runat="server" ValidationGroup="Val2">
    Validation Group 2 - OK
</c:PermissionPanel>

<asp:Panel ID="Panel4" runat="server">
    <asp:Panel ID="Panel1" runat="server">
        <c:PermissionPanel ID="P4" runat="server" ValidationGroup="Val2">
            Validation Group 2 - OK
        </c:PermissionPanel>
    </asp:Panel>
</asp:Panel>

In short I have 4 PermissionPanel that can be inside other controls.

The code of the PermissionPanel is the following:

public class PermissionPanel : Panel
{
    public delegate bool OnValidate();
    public event OnValidate Validate;

    public string ValidationGroup { get; set; }

    protected override void OnPreRender(EventArgs e)
    {
        this.Visible = (Validate != null ? Validate() : false);

        base.OnPreRender(e);
    }
}

I want to get all PermissionPanels from the page and add an event on each accordingly to its group, for example:

protected void Page_Load(object sender, EventArgs e)
{
    // Magic code here. Linq is very welcome
    // GetPageControls<PermissionPanel>("Val1").AddEvent(() => return true);
    // GetPageControls<PermissionPanel>("Val2").AddEvent(() => return false);
}

The code above would make all panels with ValidationGroup == Val1 visible while Val2 would not be rendered.

So the questions are: How can I achieve this? Is there a better way of doing it?


In short I want to add a Func that will be a validation method allowing the panels to be shown or not. A real example is:

// If post owner is the logged user, show controls like edit and delete
() => return (user != null && user.ID == post.UserID);
+2  A: 

There is two ways that I´m aware of: searching or self-registering. In searching you´ll get every control in the control hierarchy starting by the page, recursively and checking if it is a PermissionPanel.

The second way, self-registering which I like you´ll update PermissionPanel to register itself in a list inside Page.Items and register your validation handler only for controls in this list.

On PermissionPanel you can do something like that:

protected override void CreateChildControls()
{
     base.CreateChildControls();

     List <PermissionPanel> panels;

     if (Page.Items["PermissionPanels"] == null)
         Page.Items["PermissionPanels"] = panels = new List <PermissionPanel>();
     else
         panels = Page.Items["PermissionPanels"] as List <PermissionPanel>;

     panels.Add(this);
}

And on page OnPreRender you can iterate over Page.Items["PermissionPanels"] and registering validation handlers according to your validation group.

Augusto Radtke
I guess that's the most efficient way. I've noted that I need to be careful if using inside a `Repeater` or other list control. If I add the event on the `ItemDataBound` I need to check it the current control is parent of a control in my list of controls. But that's it, I've implemented this method. Thank you!
BrunoLM