Accessing different Masterpages from Base Class - c#

I have an application that uses 2 master pages. One for main pages and one for Popup pages. These both inherit from Masterpages
public partial class MainMasterPage : System.Web.UI.MasterPage
{
UserBO objUser = null;
public UserBO GetCurrentUser()
{
UserBO userBO = new UserBO();
.....
.....
return userBO;
}
}
public partial class PopupMasterPage : System.Web.UI.MasterPage
{
UserBO objUser = null;
public UserBO GetCurrentUser()
{
UserBO userBO = new UserBO();
.....
.....
return userBO;
}
}
So far so good. So my content pages all Inherit from a base class. The base class has a method that
calls the GetCurrentUser from the Base class.
public class BasePage : Page
{
//.....
protected UserBO GetCurrentUserFromMasterPage()
{
this.Master
Elsa.MasterPages.MainMasterPage master = (Elsa.MasterPages.MainMasterPage )this.Master;
return master.GetCurrentUser();
}
}
So here you can see that the base page casts the MasterPage and then calls GetCurrentUser.
Just for background... The masterpages get current user logged into the system and then draws itself using the info. If the user is in the session it gets it otherwise it loads from the database. I dont want the content pages to do the same so I wanted the base page to always get the current user for the content page from the master.
However my problem is, that because there is 2 master pages and all web pages are derived from Base
page.. I need to be able to cast to the correct master.
public partial class MyMainPage : Elsa.Pages.BasePage
{
private long _userId = -1;
public partial class MyPopupPage : Elsa.Pages.BasePage
{
private long _userId = -1;
If I put in the MasterType directive I can call the method in the content page for the correct Master.
But I dont want to call it from the content as its common method so I need it in the base.
So does anyone know how to handle this. I was thinking on deriving the BasePage again for a PopupBasePage and over writing the GetCurrentUserFromMasterPage() to cast to the popup master.
Or do I pass something into the BasePage constructor to tell it what to cast to.
I want to keep the impact to all my web pages to a minium as I have a lot of web pages.
Thanks M

You can insert an extra MasterPage as the base class for your 2 current ones:
public partial class SiteMasterPage : System.Web.UI.MasterPage
{
....
// GetCurrentUser
}
public partial class MainMasterPage : SiteMasterPage
{
....
}
public partial class PopupMasterPage : SiteMasterPage
{
}
This will allow you to implement other common features and markup (include of CSS files) in one place as well.

Does it make sense for you
using Reflection:
Master.GetType().GetMethod("GetCurrentUser").Invoke();

Do this :-
public class MasterPageBase : MasterPage
{
public PageBase PageBase { get { return (PageBase)this.Page; } }
}
public class PageBase : Page
{
// Do your Extensions Here..
}
All Pages there after Inherit from PageBase.

Related

How to Implement IDataErrorInfo within a WPF Page (A Partial Class)

It's my first experience with WPF. And I'm developing an Inventory Management System. My design model has single Window, in which a frame loads different Pages while clicking on different buttons. While adding a new Inventory into the Database, I want to ensure Data Validation. I choose IDataErrorInfo in this regard. I have to implement the interface but unable to implement just writing as public partial class AddInventoryPage : Page, IDataErrorInfo. This shows error. The signature of the class is as following
public partial class AddInventoryPage : Page
I also tried as under but unable to achieve the functionality. Even I put a breakpoint within IDataErrorInfor part but the control doesn't go there.
namespace IMS
{
public partial class AddInventoryPage : IDataErrorInfo
{
//code here
}
public partial class AddInventoryPage : Page
{
//code here
}
}
As My Inventory module is completed except Data Validation, and I'm working on the Sales module; it's not a solution to change my design model. Moreover, I'm not using any Design Pattern like MVVM. It's straight.
Looking forward to a solution.
example with a validation against the property 'Name'
public class AddInventoryPage : IDataErrorInfo
{
public string Name { get; set; }
public string Error => null;
public string this[string columnName]
{
get
{
switch(columnName)
{
case nameof(Name):
if (Name == string.Empty) return "Name can not be empty";
}
return string.Empty;
}
}
}

Nested Master Pages and Inheritance

I created a nested master page. The parent master page A inherits from System.Web.UI.MasterPage. The child master page B inherits from A.
I then created a web content page C which uses master page B, and inherits from System.Web.UI.Page.
From the web content page C I am able to access variables and methods from within both master pages. However the problem lies in accessing the parent master page variables and methods.
The problem is that a NullReferenceException is being raised. Variables and methods are not being initialised.
What is a possible solution?
public partial class ParentMasterPage : System.Web.UI.MasterPage
{
internal Button btn_Parent
{
get { return btn; }
}
}
public partial class ChildMasterPage : ParentMasterPage
{
internal Button btn_Child
{
get { return btn; }
}
}
public partial class WebContentPage : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
Button tempA = Master.btn_Child; //WORKS
Button tempB = Master.btn_Parent; //NULL REFERENCE EXCEPTION
}
}
A nested master page does not inherit it's parent master page's type. Instead it composes itself such that the NestedMasterType.Master property is an instance of the parent master page. The NestedMasterType type still inherits from System.Web.UI.MasterPage.
So this is right:
public partial class ChildMasterPage : System.Web.UI.MasterPage
This is wrong:
public partial class ChildMasterPage : ParentMasterPage
You would then access the (parent) Master of the (child) Master of a Page (that uses the child master) like this:
Button tempA = ((ChildMasterPage)this.Master).btn_Child;
Button tempB = ((ParentMasterPage)this.Master.Master).btn_Parent;
Note: This answer assumes that you mean that ChildMasterPage is a nested master page, that uses a Master directive similar to the below:
<%# Master MasterPageFile="~/ParentMasterPage.Master" Inherits="ChildMasterPage"...
A Page only has a reference to it's immediate master and it's variables, you would have to traverse up the object graph to the main master page i.e.
var parentMaster = (ParentMasterPage)Page.Master.Master;
parentMaster.SomeProperty = ...;
Alternatively, you could bridge the gap between the 2 by implementing the same property in your ChildMasterPage i.e.
internal Button btn_Parent
{
get { return ((ParentMasterPage)Master).btn_Parent; }
}
This would mean the code you currently have would work, however, it sort of defeats the purpose of having a main master page.

Access Master Page public method from user control/class/page

I am to access a method on my master page. I have an error label which I want to update based on error messages I get from my site.
public string ErrorText
{
get { return this.infoLabel.Text; }
set { this.infoLabel.Text = value; }
}
How can I access this from my user control or classes that I set up?
To access the masterpage:
this.Page.Master
then you might need to cast to the actual type of the master page so that you could get the ErrorText property or make your master page implement an interface containing this property.
Page should contain next markup:
<%# MasterType VirtualPath="~/Site.master" %>
then Page.Master will have not a type of MasterPage but your master page's type, i.e.:
public partial class MySiteMaster : MasterPage
{
public string ErrorText { get; set; }
}
Page code-behind:
this.Master.ErrorText = ...;
Another way:
public interface IMyMasterPage
{
string ErrorText { get; set; }
}
(put it to App_Code or better - into class library)
public partial class MySiteMaster : MasterPage, IMyMasterPage { }
Usage:
((IMyMasterPage )this.Page.Master).ErrorText = ...;

How can I make a user control extend a class that extends UserControl?

I want to attempt an MVC design for my little app.
I have a normal Csharp class ViewBase which extends UserControl. It's a single .cs file.
I have multiple classes that I want to extend ViewBase. These are actual UserControls so they have a code behind .cs file and a .xaml file.
However, CSharp tells me that for these classes, their base class "differs from declared in other parts".
Is what I want to do possible at all? What am I doing wrong?
Note that I did not modify my XAML files, so they still use tags.
Here is the relevant code:
// This gives the error in question and ViewBase is underlined
// "Base class of LoginView differs from declared in other parts"
public partial class LoginView : ViewBase {
public LoginView(Shell shell, ControllerBase controller) : base(shell, controller) {
InitializeComponent();
}
}
// This one is a single .cs file
public abstract class ViewBase : UserControl {
public Shell Shell { get; set; }
public ControllerBase Controller { get; set; }
protected ViewBase(Shell shell, ControllerBase controller)
{
Shell = shell;
Controller = controller;
}
}
Note that I did not modify my XAML
files, so they still use tags
That's your problem. You'll need to change:
<UserControl ...>
...
</UserControl>
to
<local:ViewBase xmlns:local="clr-namespace:..."
...
</local:ViewBase>
The problem is you're telling the compiler you're inheriting ViewBase in one place (the .cs file) and UserControl in another (the .xaml file).

How do I reference an ASP.net MasterPage from App_Code

I'm working on a .net 3.5 site, standard website project.
I've written a custom page class in the sites App_Code folder (MyPage).
I also have a master page with a property.
public partial class MyMaster : System.Web.UI.MasterPage
{
...
private string pageID = "";
public string PageID
{
get { return pageID; }
set { pageID = value; }
}
}
I'm trying to reference this property from a property in MyPage.
public class MyPage : System.Web.UI.Page
{
...
public string PageID
{
set
{
((MyMaster)Master).PageID = value;
}
get
{
return ((MyMaster)Master).PageID;
}
}
}
I end up with "The type or namespace name 'MyMaster' could not be found. I've got it working by using FindControl() instead of a property on the MyMaster page, but IDs in the master page could change.
I've tended to do the following with Web Site projects:
In App_Code create the the following:
BaseMaster.cs
using System.Web.UI;
public class BaseMaster : MasterPage
{
public string MyString { get; set; }
}
BasePage.cs:
using System;
using System.Web.UI;
public class BasePage : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (null != Master && Master is BaseMaster)
{
((BaseMaster)Master).MyString = "Some value";
}
}
}
My Master pages then inherit from BaseMaster:
using System;
public partial class Masters_MyMasterPage : BaseMaster
{
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(MyString))
{
// Do something.
}
}
}
And my pages inherit from BasePage:
public partial class _Default : BasePage
I found some background to this, it happens because of the way things are built and referenced.
Everything in App_Code compiles into an assembly.
The rest, aspx files, code behind, masterpages etc, compile into another assemlby that references the App_Code one.
Hence the one way street.
And also why Ben's solution works. Thanks Ben.
Tis all clear to me now.
I realise there are already accepted solutions for this, but I just stumbled across this thread.
The simplest solution is the one listed in the Microsoft website
(http://msdn.microsoft.com/en-us/library/c8y19k6h.ASPX )
Basically it says, your code will work as-is, if you include an extra directive in the child page aspx:
<%# MasterType VirtualPath="~/MyMaster.Master" %>
Then you can directly reference the property in the base MyPage by:
public string PageID
{
set
{
Master.PageID = value;
}
get
{
return Master.PageID;
}
}

Categories

Resources