Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Change MasterPage Programmatically

I have the following code in my ASPX side:

<%@ Page Language="C#" MasterPageFile="~/masterpages/standard.Master" .... %>
<%@ MasterType VirtualPath="~/masterpages/standard.Master" %>

I use the VirtualPath to access properties in my MasterPage. So far, so good.

However, now I have to change masterpages programatically. I know that to change a master page, I have to do on the page_init:

Page.MasterPageFile = "~/masterpages/myNewMasterPage.Master";

But I have no idea, of how to change the VirtualPath.

like image 744
Marco Avatar asked Feb 26 '10 15:02

Marco


2 Answers

I assume you're using MasterType because you need some property (which you would also need if you changed to another master), let's say you are currently using Master.MyButton, move this into a base class and use that type in your @MasterType declaration:

public class MasterBase : MasterPage
{
  public Button MyButton;
}

public class standard : MasterBase
{
}

Now in your page, your MasterType declaration looks like:

<%@ MasterType TypeName="MyNameSpace.MasterBase" %>

Now when you change your virtual path, it doesn't matter, you're accessing properties in the base, same for both master pages.

like image 155
Nick Craver Avatar answered Sep 27 '22 17:09

Nick Craver


To put it shortly, you can't do that.

You see, the "MasterType" directory provides type information, which is used by the compiler at compile time.

When you write something like Page.MasterPage.btn1.Text = "abcd", then the compiler needs to know how to handle that "btn1" part. What is it? Is it a field? A property? A method? A nested class? Or maybe it doesn't exist at all?

To answer these questions, the compiler needs to know the type of the Page.MasterPage expression. And that is exactly what you provide with the "MasterType" directive.

The VirtualPath attribute basically says "go compile that other file first, and the result of its compilation will be the type of this page's Master property". That's how compiler knows.

From all the above, one can draw a conclusion: not only is it impossible to change type of some property at run time, it also doesn't make any sense - the code has already been compiled, you don't need any compile-time information anymore!

So the next question that arises is: why did you want to do this in the first place?

If you just want to use different properties that are declared in different master pages, the you can take Nick Craver and Nathan Taylor's advice and declare a base class that would have all those fields/properties and have all your master pages inherit from that base class, and then have your MasterType directive specify that base class via TypeName attribute.

However, I would only go this way if both master pages are similar in logic, only different in design. That is to say, one page should not have any properties that the other doesn't. Otherwise, it just isn't right to have two subsets of properties/methods/fields in one class (which will be base class) when only one of those subsets is used at any time. And it isn't right to create a common base for two classes when there isn't really a common base there. Aka "bad design". In this case, you should probably rethink your initial design.

If your purpose is some other - please explain, and I will try to come up with some solutions for you.

Good luck with that.

  • Fyodor
like image 40
Fyodor Soikin Avatar answered Sep 27 '22 17:09

Fyodor Soikin