Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set a variable on a _Layout page?

I have a view and I want to use a layout page. In the layout page I want to have a conditional banner which some of the view will turn on/off. Just wondering how I can do this?

I have this in the _Layout.cshtml page...

@if (ShowBanner){

   <h1>banner</h1>

}

I'm wondering how I can turn this on/off from my MVC View page? Or whether this is the right thing to do at all? I mean if I declare that variable in the View page surely the master doesn't know about it? How do the two communicate through c#? Do I use the Viewbag? Rather not.

I know with forms its all about referencing the Page or Master member, just cant quite seem to see it with MVC...

Any help much appreciated...

Thanks Pete

like image 282
Exitos Avatar asked Apr 10 '12 19:04

Exitos


1 Answers

I'm with you, Exitos: I avoid using ViewBag too. Aside from the silly name, I dislike the weak typing that comes along with it. There is a solution, but it's kind of involved, so bear with me.

First, create a class to store the "display hints" that are to be passed to the layout. I creatively call this class "DisplayHints":

public class DisplayHints {
  // anything that you want passed from a view to the layout goes here
  public bool ShowBanner { get; set; }
}

Then, create a class deriving from WebViewPage<T> that will be the new base class of your views. Note how we have a property called DisplayHints that's stored in ViewData (which is available to the controller, the view, and the layout):

public abstract class MyViewPage<T> : WebViewPage<T> {
  public DisplayHints DisplayHints {
    get {
      if( !ViewData.ContainsKey("DisplayHints") )
        ViewData["DisplayHints"] = new DisplayHints();
      return (DisplayHints)ViewData["DisplayHints"];
    }
  }
}

As a commenter pointed out below, ViewData is weakly-typed, just like ViewBag. However, there's no way I know of to avoid storing something in ViewData/ViewBag; this just minimizes the number of weakly-typed variables to one. Once you've done this, you can store as much strongly-typed information in DisplayHints as you want.

Now that you have a base class for your views, in Web.config, we need to tell MVC to use your custom base class:

<pages pageBaseType="MyNamespace.Views.MyViewPage">

It sounds like a lot of trouble, but you gain some serious functionality for all this work. Now in your view, you can set any display hint you want as follows:

@{ DisplayHints.ShowBanner = true; }

And in your layout, you can access it just as easily:

@if( DisplayHints.ShowBanner ) {
  <div>My banner....</div>
}

I hope this helps!

like image 184
Ethan Brown Avatar answered Oct 14 '22 23:10

Ethan Brown