Master Pages - Strongly-Typed control access

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Boris Yeltsin

    Master Pages - Strongly-Typed control access

    OK, on my Master Page I have a control:

    <a id="hypTabAccou nt" href="#" runat="server"> Account</a>

    Now, in the code-behind (Root.master.vb ) I can refer to it simply thus:

    hypTabAccount.I nnerText = "blah"

    Now, what I want is the same in a content page that uses the Master Page. I
    have a Master Type in my Content page:
    <%@ master masterpagefile= "~/Root.master" language="VB"
    codefile="Home. master.vb" inherits="Home_ Master" %>
    <%@ mastertype virtualpath="~/Root.master" %>

    I can access *properties* on the Master Page in a strongly typed way, but..

    Is there a way of accessing *controls* in strongly-typed way (any solution
    including some crazy reflection code is permissible) without using
    FindControl?

    Thanks!
  • Steven Cheng[MSFT]

    #2
    RE: Master Pages - Strongly-Typed control access

    Hi Boris,

    I've seen some other threads you posetd in the newsgroup and have posetd
    some suggestion there.

    As for the question about referencing control in Master page through
    Strong-typed means, I've ever found many thread discussing on this in the
    newsgroup or other community.

    IMO, to locate a certain control on the page, if it is not directly
    referenced through a page variable, the reasonable means is to use
    "FindContro l" method to locate it(from Page or some other nested
    namingcontainer ). This is because Control collection is the only reliable
    way to navigate to any sub controls in the page's control Tree. Generally,
    I will use the ASP.NET page's output trace to inspect control tree so as to
    get how I should write code to find that control. You can turn on the
    output trace for page in the @Page directive like:

    <%@ Page Trace="true" ......... %>

    You can find the control tree of the whole page in the output trace:

    #Reading ASP.NET Trace Information



    For your scenario here, to access the control(in master page) from content
    page by strong-typed means, what I would do is defining some public
    properties in the master page which will do the control locating task and
    return the certain control's instance. e.g.

    suppose we have the following template in master page(control.ma ster):
    ========control .master======== =====
    <form id="form1" runat="server">
    <div>
    <table border="0" cellpadding="0" cellspacing="0" style="width:
    100%; height: 100%">
    <tr>
    <td style="height: 80px;width:100p x">
    <asp:Image ID="imgLogo" runat="server"
    ImageUrl="http://www.asp.net/i/www_asp_net_log o.gif" />
    </td>
    <td>
    <asp:Label ID="lblSubject " runat="server" Text="Default
    Subject" Font-Size="30"></asp:Label>
    </td>
    </tr>
    <tr>
    <td valign="top" colspan="2">
    <asp:contentpla ceholder id="ContentPlac eHolder1" runat="server">
    </asp:contentplac eholder>
    </td>
    </tr>
    </table>
    </div>
    </form>
    =============== =====

    and in the master's codebehind, we define two public properties to expose
    the two controls in it

    =========master code behind========= ======

    public partial class Master_control : System.Web.UI.M asterPage
    {
    public Label SubjectLabel
    {
    get
    {
    return lblSubject;
    }
    }

    public Image LogoImage
    {
    get
    {
    return imgLogo;
    }
    }

    ............... .........
    }


    =============== ===============


    Thus, in the content page which applied this master page(and reference it
    through @MasterType directive), we can use the following code to access the
    controls in master page as strong-typed objects:

    =============== =============== ===

    protected void Page_Load(objec t sender, EventArgs e)
    {
    if (!IsPostBack)
    {
    Master_control master = Page.Master as Master_control;

    master.SubjectL abel.Text = "Customized Sujbect";
    master.LogoImag e.ImageUrl =
    "http://www.msnbc.msn.c om/images/msnbc/logo01.gif";
    }
    }

    =============== =============== ========


    In addition, if you do not want to always @MasterType directive(which will
    affect page's dynamic compilation sequence), you can consider define a
    separate interface, and let your master page class implement this
    interface, e.g:


    public interface IMasterHelper
    {
    public control GetControlByID( string id);
    }


    public partial class Master_control : System.Web.UI.M asterPage,
    IMasterHelper
    {
    ....
    public Control GetcontrolByID( string id)
    {
    return Page.FindContro l(id);
    }
    }


    Thus, in content page, you can convert Page.Master to that interface type
    and then query control through the interface methods.

    Just some of my consideration, hope this helps you some.


    Sincerely,

    Steven Cheng

    Microsoft MSDN Online Support Lead



    This posting is provided "AS IS" with no warranties, and confers no rights.

    Comment

    • Steven Cheng[MSFT]

      #3
      RE: Master Pages - Strongly-Typed control access

      Hello Boris,

      Have you got any further progress or ideas on this issue or does my
      suggsetion helps a little? If there is anything else we can help, please
      feel free to post here.

      Sincerely,

      Steven Cheng

      Microsoft MSDN Online Support Lead

      This posting is provided "AS IS" with no warranties, and confers no rights.

      Comment

      • Boris Yeltsin

        #4
        RE: Master Pages - Strongly-Typed control access

        Hi Steven,

        I was really looking for a way to directly access the controls, i.e.:
        Master.Page.MyC ontrol.CssClass = "hello"

        But without creating a property, which is doubling everything up.

        Someone did point out to me that the only reason I can't access the controls
        is that I'm being rather thick, and that they are of course declared
        "Protected" . I'd forgotten about that since moving to ASP.NET2.0 where the
        partial classes hide the declarations of all the controls.

        So, my question is now a bit more esoteric.

        Is there a way to either:
        a) Turn off the partial classes for a single page
        or
        b) Over-ride some of the controls - to get them declared as "Public" rather
        than "Protected"

        I hope that question makes some sense :)

        - Boris

        "Steven Cheng[MSFT]" wrote:
        Hi Boris,
        >
        I've seen some other threads you posetd in the newsgroup and have posetd
        some suggestion there.
        >
        As for the question about referencing control in Master page through
        Strong-typed means, I've ever found many thread discussing on this in the
        newsgroup or other community.
        >
        IMO, to locate a certain control on the page, if it is not directly
        referenced through a page variable, the reasonable means is to use
        "FindContro l" method to locate it(from Page or some other nested
        namingcontainer ). This is because Control collection is the only reliable
        way to navigate to any sub controls in the page's control Tree. Generally,
        I will use the ASP.NET page's output trace to inspect control tree so as to
        get how I should write code to find that control. You can turn on the
        output trace for page in the @Page directive like:
        >
        <%@ Page Trace="true" ......... %>
        >
        You can find the control tree of the whole page in the output trace:
        >
        #Reading ASP.NET Trace Information

        >
        >
        For your scenario here, to access the control(in master page) from content
        page by strong-typed means, what I would do is defining some public
        properties in the master page which will do the control locating task and
        return the certain control's instance. e.g.
        >
        suppose we have the following template in master page(control.ma ster):
        ========control .master======== =====
        <form id="form1" runat="server">
        <div>
        <table border="0" cellpadding="0" cellspacing="0" style="width:
        100%; height: 100%">
        <tr>
        <td style="height: 80px;width:100p x">
        <asp:Image ID="imgLogo" runat="server"
        ImageUrl="http://www.asp.net/i/www_asp_net_log o.gif" />
        </td>
        <td>
        <asp:Label ID="lblSubject " runat="server" Text="Default
        Subject" Font-Size="30"></asp:Label>
        </td>
        </tr>
        <tr>
        <td valign="top" colspan="2">
        <asp:contentpla ceholder id="ContentPlac eHolder1" runat="server">
        </asp:contentplac eholder>
        </td>
        </tr>
        </table>
        </div>
        </form>
        =============== =====
        >
        and in the master's codebehind, we define two public properties to expose
        the two controls in it
        >
        =========master code behind========= ======
        >
        public partial class Master_control : System.Web.UI.M asterPage
        {
        public Label SubjectLabel
        {
        get
        {
        return lblSubject;
        }
        }
        >
        public Image LogoImage
        {
        get
        {
        return imgLogo;
        }
        }
        >
        ............... .........
        }
        >
        >
        =============== ===============
        >
        >
        Thus, in the content page which applied this master page(and reference it
        through @MasterType directive), we can use the following code to access the
        controls in master page as strong-typed objects:
        >
        =============== =============== ===
        >
        protected void Page_Load(objec t sender, EventArgs e)
        {
        if (!IsPostBack)
        {
        Master_control master = Page.Master as Master_control;
        >
        master.SubjectL abel.Text = "Customized Sujbect";
        master.LogoImag e.ImageUrl =
        "http://www.msnbc.msn.c om/images/msnbc/logo01.gif";
        }
        }
        >
        =============== =============== ========
        >
        >
        In addition, if you do not want to always @MasterType directive(which will
        affect page's dynamic compilation sequence), you can consider define a
        separate interface, and let your master page class implement this
        interface, e.g:
        >
        >
        public interface IMasterHelper
        {
        public control GetControlByID( string id);
        }
        >
        >
        public partial class Master_control : System.Web.UI.M asterPage,
        IMasterHelper
        {
        ....
        public Control GetcontrolByID( string id)
        {
        return Page.FindContro l(id);
        }
        }
        >
        >
        Thus, in content page, you can convert Page.Master to that interface type
        and then query control through the interface methods.
        >
        Just some of my consideration, hope this helps you some.
        >
        >
        Sincerely,
        >
        Steven Cheng
        >
        Microsoft MSDN Online Support Lead
        >
        >
        >
        This posting is provided "AS IS" with no warranties, and confers no rights.
        >
        >

        Comment

        • Steven Cheng[MSFT]

          #5
          RE: Master Pages - Strongly-Typed control access

          Thanks for the followup Boris,

          Now I've got what you want is directly expose the control member in the
          MasterPage as public. Due to the ASP.NET 2.0 page's new compilation model,
          we can not directly specify the control member properties in page's
          codebeind.

          So far what I can get is using a Base class for our page(which contains the
          public control member variable) and also use the "CodeFileBaseCl ass"
          attribute in @Page/@Master directive to associate this base page class. In
          such case, the ASP.NET runtime will check whether there is any control's ID
          identical to any page member variable in the base class. If exists, the
          control is linked to the variable in base class at dynamic compilation
          time.

          #@ Page


          For example, suppose we define a base master page class as below(define a
          public variable to expose a Label control on the master page):

          #put in App_code folder
          =============== ====
          public class BaseMasterPage : MasterPage
          {
          public Label lblMessage;

          ............... .........
          }
          =============== ===============


          Then, in our actual master page, we use it as base class:

          ==============
          public partial class Master_control : BaseMasterPage
          {
          ..............
          }
          ===============

          Also, in the .master file, we need to associate the base page in the
          @Master directive as below:

          =============== ===========

          <%@ Master .............. CodeFile="contr ol.master.cs"
          Inherits="Maste r_control" CodeFileBaseCla ss="BaseMasterP age" %>

          =============== ========

          After that, we can directly use this field (in base master class) to
          reference the control in content page.

          =============== =============
          protected void Page_Load(objec t sender, EventArgs e)
          {
          Master_control master = Page.Master as Master_control;

          master.lblMessa ge.Text = "Modified Message: " +
          DateTime.Now.To LongTimeString( );

          }
          =============== =============


          Anyway, I still think define a public property(which encapsulate the code
          to find control and return it ) will be better since it can help us add
          some customized code or error handling code. Also, for those control which
          is not directly refereneable by page variable (may be contained in other
          control as child control), the above approach won't work.

          Sincerely,

          Steven Cheng

          Microsoft MSDN Online Support Lead


          This posting is provided "AS IS" with no warranties, and confers no rights.







          Comment

          Working...