Wrox Programmer Forums
Go Back   Wrox Programmer Forums > ASP.NET and ASP > ASP.NET 2.0 > ASP.NET 2.0 Basics
|
ASP.NET 2.0 Basics If you are new to ASP or ASP.NET programming with version 2.0, this is the forum to begin asking questions. Please also see the Visual Web Developer 2005 forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the ASP.NET 2.0 Basics section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 2nd, 2007, 10:44 AM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default How to tie into controls on a MasterPage?

I have about 4 ImageButtons on a MasterPage that will be used for navigation.

How can I reference these buttons within a particular ContentPage so that I can change images on them depending upon the particular page I am on?

In other words, if I have an about.aspx and a gallery.aspx page that both use the masterpage.master..how can I reference the buttons on the masterpage.master so that I can change the "about" button to appear highlighted--something that would happen on pageload for the about.aspx page.

Any help would be appreciated.

Kind Regards,
Rob

 
Old July 2nd, 2007, 11:36 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Every page in your application is created as a class. gallery.aspx will likely have a class called "gallery". Similar for about.aspx. Therefore you can test for the class type of the Page property of the master page. You could use simple boolean logic to enable/disable a button (or some more complex tests to change appearance). For example, in C# you could do this in your master page:

btnAbout.Enabled = !(this.Page is about);
btnGallery.Enabled = !(this.Page is gallery);

This would enable each button when you are viewing the page of that button.

-Peter
 
Old July 2nd, 2007, 12:26 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Thank you for the reply, I will try messing with that. My issue is that I am designing a site that has 4 buttons at the top of the master for navigation. What I am trying to do is have the current-selected page have it's button text one color (call it light ie light-green, light-red, ect), all the other button's text would be white--then, the mouse-over would change text to grey.

Before I even start to mess with changing the currently selected button text "light"..all I am trying to do now is perform a mouseover--but, should have realized, ImageButton doesn't have a mouseover property--makes sense, since it is a client-operation.

BUT--my issue now becomes I don't know much about JavaScript. I have tried doing (in masterpage.master.vb):

Protected Sub Page_Load (ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
{
  If (Not IsPostBack) Then
     AboutButton.Attributes("OnMouseOver") = "javascript:EvImageOverChange(this, 'in');"
     AboutButton.Attributes("OnMouseOut") = "javascript:EvImageOverChange (this, 'out');"
     ShowsButton.Attributes....
     ShowsButton.Attributes....
     AwardsButton.Attributes...
     AwardsButton.Attributes...
     ArtButton.Attributes...
     ArtButton.Attributes...
  EndIf
End Sub

Then..in in the masterpage.master I have a link to the following JScript.js file:

function EvImageOverChange(name, direction)
{
     switch(direction)
     case 'in' : name.src = "Site_Images/aboutbuttonselecting.jpg"
     break;
     case 'out' : name.src="Site_Images/aboutbuttonwhite.jpg"
     break;
}

What I am trying to do is make this dynamic so I can pass any button to this function..but don't know about strings...I tried:

    case 'in' : name.src = "Site_Images/" + name.ID + "selecting.jpg"

But it doesn't work. Ironically...also...it won't allow me to debug in Visual STudio on the JScript.js file. I might add....it works when I spell out the entire name, but obviouisly I am tied to that one image.

Thoughts?

Thanks SO much!
Rob



 
Old July 2nd, 2007, 12:52 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Planoie,

Ok....I figured out how to solve the mouseover--but not sure the better way to do this. I didn't realize that name.id actually resulted in "ctl00_controlname" So--I simply renamed all my images to have a "ctl100_" in front of them. There must be a property that chops the "ctl100_" from the return of the ID property.

To follow up on your post---how would I do the test for the masterbutton inside a pageload (VB if you could).

In other words....logically thinking....it would be something like:

Protected Sub Page_load (.....)
{
   If (Pagetype = aboutMe) Then
      buttonIAmWantingToChangeSource.src = "picture.jpg"
   EndIf
   Elseif (Pagetype = gallery) Then
      buttonIAmWantingToChangeSource.src = "differentpic.jpg"
   EndElseiF
}

Basically--trying to figure out how to test the pagetype based upon your post.

MUCH THANKS!
Rob

 
Old July 2nd, 2007, 09:06 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Regarding the client side names of the controls:

When you create pages and user controls you give the controls on the page logical names: btnSave, txtName, etc. When .NET renders these controls it generates unique names to emit to the client side HTML. For a simple ASPX with no master page, the IDs you provided (btnSave, txtName) will be what is emitted to the page in the standard HTML form controls. However, as soon as those controls reside in a branch of the ASP.NET page's control tree the framework starts adding on parts to the name as you have seen now. Your page is manipulated by the ASP.NET runtime as an instance of the page class living in the "Controls" collection of a content container inside an instance of the master page class. Thus, "ctl100" is the control ID that belongs to the parent container of the page you are wrapping in the master page. Using the value that you find in browser source HTML is not a good idea because that generated prefix could change with 1 simple little change in your master page. Then all your hard coded client side values are toast.

You have made part of this easier by using the "this" keyword in the JS calls from the button. Now let's consider the other problem: a client side method that will work for several buttons.

One trick I have used is the ability to "hack" the attributes list of server controls. For example, you could add this to your server side code:
Code:
    AboutButton.Attributes("imgName") = "about"
The "imgName" attribute in the document object model is unrecognized, however it doesn't break the HTML. But most importantly, it still gets processed by the document parser and it will show up in the object when accessed by javascript. Therefore, you can do this:
Code:
    function EvImageOverChange(button, direction)
    {
        switch(direction){
            case 'in' : button.src = "Site_Images/" + button.imgName + "selecting.jpg"; break;
            case 'out' : button.src = "Site_Images/" + button.imgName + "white.jpg"; break;
        }
    }
The javascript model will allow you to access this "imgName" attribute you created in the codebehind. You then need only to provide the right image name prefix for the image files and name the file consistantly for your selected and not-selected image versions.

One thing you might encounter: If you are using 3 images for these (i.e. 1 each for on, off and hover) you'll need to save the image's original state. If the image is ON and you hover, you need to restore it to ON when you leave it. Similarly with OFF. Here's another trick I use for this that takes advantage of javascript dynamic object capabilities:

In your 'OnMouseOver' client method, save the current image src to a new synthesized property of the image object itself:

    button.originalSrc = button.src;

Then in the 'OnMouseOut' client method, you can restore it from the saved value:

    button.src = button.originalSrc;

Now you don't even need any real logic in the mouse event methods. You could probably strip it down to just this:
Code:
    function EvImageHover(button)
    {
        button.originalSrc = button.src;
        button.src = "Site_Images/" + button.imgName + "selecting.jpg"; break;
    }
    function EvImageLeave(button){
        button.src = button.originalSrc;
    }
How's that for simplicity!


As far as the codebehind for determining the page: In VB it should be something like this:
Code:
   If (typeof Me.Page is aboutMe) Then
      buttonIAmWantingToChangeSource.src = "picture.jpg"
   EndIf
   Elseif (type Me.Page is gallery) Then
      buttonIAmWantingToChangeSource.src = "differentpic.jpg"
   EndElseiF
If you set all the image/link controls to NOT use viewstate (which you most likely don't need on these) and the OFF image as their default then you simply need only to test for the image that matches the current page so you can set it's "ON" image. All the others will always get created with the default OFF image.

-Peter
 
Old July 2nd, 2007, 11:04 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

I want to thank you very much for all your time!! I am going to print this and then read before bed! :) I wound up doing a very extensive work-around wherein I tied in a directive (read that somewhere) at the page so that I can refer to MasterPage controls from within the contentpage. Then..on each pageload event, I have four navigating buttons that take me to four different pages (link to the site--where buttons are just images, as I am working on my development machine, is www.kofc1913.org/sunsite.aspx )

So..basically, in each pageload, set up, it runs through a bunch of code.

Here's my MasterPage:

<body>
<form id="form1" runat="server" accept="4">
    <div id='main'>
            <div id='header' >
            <img src="Site_Images/Sunbanner.jpg" />
           </div>
        <div id='aboutbutton'>
            <asp:ImageButton ID="AboutButton" runat="server" ImageUrl="Site_Images/ctl00_aboutbuttonwhite.bmp" PostBackUrl="default.aspx" />
        </div>
        <div id='exhibitbutton'>
            <asp:ImageButton ID="ShowsButton" runat="server" ImageUrl="Site_Images/ctl00_showsbuttonwhite.bmp" PostBackUrl="shows.aspx" />
        </div>
        <div id='awardsbutton'>
            <asp:ImageButton ID="AwardsButton" runat="server" ImageUrl="Site_Images/ctl00_awardsbuttonwhite.bmp" PostBackUrl="awards.aspx" />
        </div>
        <div id='artbutton'>
            <asp:ImageButton ID="SunsartButton" runat="server" ImageUrl="Site_Images/ctl00_sunsartbuttonwhite.bmp" PostBackUrl="artgallery.aspx" />
        </div>
        <div id='container'>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
            </asp:ContentPlaceHolder>
        </div>
        <div id='footer'>
            <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="Admin/addpictures.aspx">Login</asp:HyperLink>
            <span style="margin-left:40px">Future Copyright Info</span>
        </div>
    </div>
</form>
</body>


Here's the javascript file:

function EvImageOverChange(name, direction)
    {
        switch(direction)
        {
            case 'in': name.src = 'Site_Images/' + name.id + 'Selecting.bmp';
            break;
            case 'out' : name.src = 'Site_Images/'+ name.id + 'white.bmp';
            break;
            case 'neither' : name.src = 'Site_Images/' + name.id + 'selected.bmp';
            break;
        }
    }

Here's the Page Load for one of the four pages

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not IsPostBack) Then
            Dim aboutButtonToFind As ImageButton
            aboutButtonToFind = CType(Master.FindControl("AboutButton"), ImageButton)
            Dim showsButtonToFind As ImageButton
            showsButtonToFind = CType(Master.FindControl("ShowsButton"), ImageButton)
            Dim awardsButtonToFind As ImageButton
            awardsButtonToFind = CType(Master.FindControl("AwardsButton"), ImageButton)
            Dim sunsartButtonToFind As ImageButton
            sunsartButtonToFind = CType(Master.FindControl("SunsartButton"), ImageButton)
            aboutButtonToFind.Attributes("OnMouseOver") = "javascript:EvImageOverChange(this, 'in');"
            aboutButtonToFind.Attributes("OnMouseOut") = "javascript:EvImageOverChange(this, 'neither');"
            showsButtonToFind.Attributes("OnMouseOver") = "javascript:EvImageOverChange(this, 'in');"
            showsButtonToFind.Attributes("OnMouseOut") = "javascript:EvImageOverChange(this, 'out');"
            awardsButtonToFind.Attributes("OnMouseOver") = "javascript:EvImageOverChange(this, 'in');"
            awardsButtonToFind.Attributes("OnMouseOut") = "javascript:EvImageOverChange(this, 'out');"
            sunsartButtonToFind.Attributes("OnMouseOver") = "javascript:EvImageOverChange(this, 'in');"
            sunsartButtonToFind.Attributes("OnMouseOut") = "javascript:EvImageOverChange(this, 'out');"
            aboutButtonToFind.ImageUrl = "Site_Images/ctl00_aboutbuttonselected.bmp"
        End If
    End Sub

So...for each page, I just change which button does what according to the page it is on.

VERY long code!!

Thanks for all your help--please forgive if I have a question about it in the morning!

Kind Regards,
Rob

 
Old July 3rd, 2007, 01:09 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Rob,

I think you missed part of my explanation. If you put the code in the master page you can reference the images by their object directly and each page doesn't have to do anything special. You don't need to use all those "FindControl" calls because the logic is in the master page.

-Peter
 
Old July 3rd, 2007, 02:00 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

The code I wrote was done before I received your post....I'll take a look at it..as it appears MUCH easier than all the stuff I wrote!

:)
Rob

 
Old July 3rd, 2007, 04:54 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Ok...so I am trying to convert to this way..but:

typeof Me.Page is aboutMe

doesn't work. Somehow I need to convert aboutMe to a "type"

Perhaps something like If (typeof Me.Page is CType (aboutMe, Page))???

Trying to figure out a way to make "aboutMe" into something that can be compared to.

I cannot thank you enough for all of the help...your time is very much appreciated!!

(This is the second site I've worked on--when I was working on my first site there was someone who helped out alot and then I would ship him Amazon.com wishlist items for his help. I never took advantage of this...if this is something you have time to do (I am a father of 4 and have a full time job--so I know how precious time is) then please email [email protected]). For instance, I'm working two other issues as well..in a different posting in this topic with regards to ENTER not working on a login control after username and pass is put on. I've done a bit of research on this--but mystified, as it appears to be an old issue, and I am working with VS 2005. The other issue is in the SQLServer 2005 category. I am VERY unfamiliar with installs. When I was working on my last project--everything was installed in such a way that I could go into management studio and attach my DB to work with it. Well, I had to reload all my software (crash) and now, when I go into SQL management studio (2005) I try to attach, but it cannot go past documents and setting/me/ to see the /desktop/siteihavesetup. Anyways..I won't digress in this forum about that topic.

Anyways..after so many one-on-one help--alot of times..just his time posting in the forums so others could benefit, I'd send him several wishlist items.

Please let me know, as I really do appreciate your help!

As to this--just trying to figure out how to make a "type" that I can use in the boolean test.

Much thanks,
Rob

 
Old July 3rd, 2007, 09:42 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Ok, I think I know what's happening. I suspect you are using the VS2005 web site project type. When you use this all the page classes are separate, that is, they are not in an assembly together because they are compiled on the fly when the page is requested. Therefore you can't reference another page class. If you use a web application project so the page classes are compiled together into an assembly then things work together much better. To verify this I created a super simple web app project with the required code. You can download the zip here:

http://www.geekdork.com/samples/Page...MasterPage.zip

I included the binaries so that you could run the app without having to use visual studio in the event you don't have the web application project extensions installed for VS2005. You'll need to create a virtual directory for the app in IIS to run it however.

Unless you go with a web application project, you might have to use the technique you have already for finding the master page controls to modify them. I'd recommending reading up on and trying out the web application project type though. Scott Guthrie is the authority on that subject: http://webproject.scottgu.com/

-Peter





Similar Threads
Thread Thread Starter Forum Replies Last Post
How to tie to nested GridView inside DataList rsearing ASP.NET 2.0 Basics 6 June 18th, 2011 06:35 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.