views:

61

answers:

3

I have a Web Site project, and within it I have a user Web Control defined in an ascx file.

The control is added to the Site.Master, and it shows up correctly on the page and everything is fine.

I need to override some of the control's fields on one of the pages that derive from Site.Master.

// In OnLoad:
MyControlName control = (MyControlName) Page.Master.GetBaseMasterPage().FindControl("controlID"));

The issue is that MyControlName doesn't register as a valid Type on the child page. If I add a second instance of the control to the child page directly, the above works as needed, but if the control isn't placed directly on the page, and instead is only defined in the master page, the type is undefined. The control is not in a namespace, and is defined within the project, so I don't know why it is having such an issue location the appropriate type.

If I put a breakpoint in the OnLoad, the type listed for the control is ASP.my_control_name_ascx, but using that does not work either.

Why can't the child class reference the correct type? Can I fix this?

Thanks!

A: 

I take it GetBaseMasterPage() is your own method? What happens if you try:

MyControlName control = (MyControlName)Page.Master.FindControl("controlId");

?

Matthew Abbott
Yes, it is our own function. We have a site master, and section masters. Not all of the section masters necessarily inherit from the site master, so that function just runs up to the 'highest' master page.That code works correctly if there is a second instance of the control placed on the page. ie, it locates the control on the master and updates the state of the master page's control, but only if the child page has an instance of the control on it. Otherwise, the compiler says that it is an unknown Type. So it is just a type resolution issue, not a functionality issue.
turtle
Quick (pedantic) point about that code sample; you'd need to bracket Page.Master to get the typecast: MyControlName control = ((MyControlName) Page.Master).FindControl("controlId");
Owen Blacker
I don't see why, Page.Master is a property of type MasterPage, which inherits from Control, which has the FindControl method. You only need to cast the result, which is the result of the FindControl method, you don't need to bracket further.
Matthew Abbott
A: 

The control does not have global scope over the entire project. It will only be selectable as a type on pages where the control is registered. So you have to register the control on the child page:

<%@ Register src="WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %>

You will need to add a register tag like above to the top of your child aspx page.

The other option is you could create an interface for the control which exposes the properties or methods you want to access, and put the interface in app_code or some other globally accessible place, then have the control implement the interface, and cast the control to the interface.

Chris Mullins
A: 

Not a direct answer to your question, but you might find the @MasterType directive useful.

If you add a line like

<%@ MasterType TypeName="ClientName.SiteName.MasterPages.SiteMaster" %>

to the top of your ASPX page, you should be able to refer to the master page in code without having to cast it. This might make it easier for the code to find your control, perhaps?

You could end up with a line like:

// In Page.OnLoad:
MyControlName control = Page.Master.MyControl;

and then expose a new property in your master page that wraps the FindControl call:

// In Site.master.cs
internal MyControlName MyControl
{
    get { this.FindControl("controlID"); }
}

Hope this helps!

Owen Blacker