Welcome Guest Search | Active Topics | Sign In | Register

DataBinding ContextMenu in a user control Options
Laurynas
Posted: Tuesday, April 6, 2010 3:54:38 AM
Rank: Advanced Member
Groups: Member

Joined: 3/23/2010
Posts: 35
Hello,

I've been struggling with ContextMenu control added to a user control (.ascx) - it is never binding when used this way and the user control is loaded via Page.LoadControl. Everything works fine when using ContextMenu control directly in the .aspx page or when using any ASP data bound control, like the ASP Menu in test.ascx.

Am I missing something here or is this a bug in ContextMenu?

DataBind.aspx:
Code: HTML/ASPX
<%@ Page Language="C#" Debug="true" %>

<script runat="server">
    void OnPreRender (object sender, EventArgs e)
        {
        Control testControl = Page.LoadControl ("~/test.ascx");
        test.Controls.Add (testControl);
        }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>DataBind test</title>
</head>
<body>
    <form runat="server">
    <asp:PlaceHolder runat="server" ID="test" OnPreRender="OnPreRender"></asp:PlaceHolder>
    </form>
</body>
</html>


test.ascx:
Code: HTML/ASPX
<%@ Control Language="C#" AutoEventWireup="true" %>
<%@ Register TagPrefix="eo" Assembly="EO.Web" Namespace="EO.Web" %>

<asp:XmlDataSource runat="server" ID="menuSource" XPath="/*/*">
    <Data>
    <Menu>
        <MenuItem title="test1">
            <MenuItem title="test2">
                <MenuItem title="test3"></MenuItem>
            </MenuItem>
        </MenuItem>
        <MenuItem title="test4"></MenuItem>
    </Menu>
    </Data>
</asp:XmlDataSource>
<eo:ContextMenu runat="server" DataSourceID="menuSource" ContextControlID="tree">
</eo:ContextMenu>
<asp:Menu runat="server" DataSourceID="menuSource"></asp:Menu>
<asp:TreeView runat="server" ID="tree" DataSourceID="menuSource">
</asp:TreeView>



EDIT: Updated DataBind.aspx source. Data binding does not work when loading user controls with Page.LoadControl.

Thanks,
Laurynas
eo_support
Posted: Tuesday, April 6, 2010 8:41:12 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Please add the following code into the user control's Page_Load handler:

Code: C#
ContextMenu1.ContextControlID = tree.ClientID;
ContextMenu1.DataBind();


The first line is necessary because ContextControlID is the full ID of the client DOM element, not the server control's ID. The server control's ID and ClientID is the same without user control, but they are different when you use a user control. The second line is needed if the menu is dynamically loaded.

Thanks!
Laurynas
Posted: Tuesday, April 6, 2010 9:13:31 AM
Rank: Advanced Member
Groups: Member

Joined: 3/23/2010
Posts: 35
This is the workaround I currently use, but why is it not working like any other data bound control? Data binding manually throws away the benefits of caching and rebinding only when data source changes.

The ASP.NET life cycle overview also suggests that controls with DataSourceID set should bind automatically - see http://msdn.microsoft.com/en-us/library/ms178472.aspx and http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basedataboundcontrol.datasourceid.aspx
eo_support
Posted: Tuesday, April 6, 2010 9:36:27 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Yes. We are aware of that. The menu (and context menu) does automatically bind to data source if it is inserted into the page before Page_Load, this is why if you place the menu statically in the page it works fine. It will also work if you dynamically load the control inside Page_Init. But if the menu is dynamically loaded in or after Page_Load, then it won't automatically bind to the data source.

I believe this is an implementation restriction. Because it is required that you load your control before Page_Load (usually inside Page_Init) in order to have server side event working, this is usually not a problem. For example, if you place a standard ASP.NET Button inside your test.ascx, you will NOT be able to handle that button's server side click event because you loaded the user control too late. Because unable to handle server event is a big issue, so user often find dynamic loading after Page_Load is not as useful.

If possible you can change your OnPreRender to OnInit, that way you will no longer need to call contextMenu1.DataBind() explicitly. (Note that you will still need the first line that sets the ContextControlID property). We will look into the issue at the same time to see if we can enable automatic binding after Page_Load.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.