2

In a previous post I had trouble setting the styles on my views in the same way that they do it on the telerik demo site by selecting the style from a dropdown. This was answered however I now have a new but related problem.

I have multiple pages on my site (as is common to MVC) and each of these pages have many telerik controls on them. Allowing the user to style the site using predefined css done for me is great and saves me a lot of work.

The problem is that when I move from page to page, the combo box that telerik uses resets to its default value, thus resetting the styles on the site everytime the user changes a pages (not ideal).

I have tried using sessions to store the state, but there is no way to detect postback like with standard aspx development. So I cant do something like:

if(isPostBack)
{
    if(string.isNullOrEmpty(Session["MyTheme"]+""))
    {
        Session["MyTheme"]="black";
    }
    else
    {
        Session["myTheme"]=//Some combo box selected value
    }
}

Even if I could, the combo box onChange event is handled via JavaScript but the Telerik control requires C# Razor and try as I mgiht, I cant get them to talk and share a simple value.

Ultimately all I want to do, is allow the user pick a theme from the combo box and from then on, that theme is remembered throughout the site until they next change it.

I have tried query strings and sessions, but neither work as I cant access them in JavaScript. Aparently they are used on the server side only.

I have tried cookies but that doesnt work because I cant access them in C# Razor. Aparently they are client side only.

Below is my code:

<head>
@(
  Html.Telerik().StyleSheetRegistrar()
                .DefaultGroup(group => group
                .Add("telerik.common.css")
                .Add(string.IsNullOrEmpty(@Html.ViewContext.HttpContext.Request.QueryString["theme"]) ? "telerik.black.css" : "telerik."[email protected]["theme"]+".css").Combined(true).Compress(true)
                ))
</head>


<body>
                    @(
                        /* TELERIK COMBOBOX */

                        Html.Telerik().ComboBox()
                        .Name("cbxTheme")
                        .SelectedIndex(0)
                        .ClientEvents(events => events.OnChange("cbxTheme_onChange"))
                        //.BindTo((IEnumerable<DropDownItem>)ViewData["Files"])
                        .Items(item =>
                            {
                                item.Add().Text("black");
                                item.Add().Text("common");
                                item.Add().Text("default");
                                item.Add().Text("forest");
                                item.Add().Text("hay");
                                item.Add().Text("metro");
                                item.Add().Text("office2007");
                                item.Add().Text("office2010black");
                                item.Add().Text("office2010blue");
                                item.Add().Text("office2010silver");
                                item.Add().Text("outlook");
                                item.Add().Text("rtl");
                                item.Add().Text("simple");
                                item.Add().Text("sitefinity");
                                item.Add().Text("sunset");
                                item.Add().Text("telerik");
                                item.Add().Text("transparent");
                                item.Add().Text("vista");
                                item.Add().Text("web20");
                                item.Add().Text("webblue");
                                item.Add().Text("windows7");
                            })
                    )

@(Html.Telerik().ScriptRegistrar().DefaultGroup(group => group.Combined(true).Compress(true)))

</body>

<script type="text/javascript">
function cbxTheme_onChange()
{
    var selectedItemText = $("#cbxTheme").data("tComboBox").text();
    //var selectedItemValue = $("#cbxTheme").data("tComboBox").value();
    window.location.href = window.location.protocol
                         + '//'
                         + window.location.host
                         + window.location.pathname
                         + '?theme='
                         + selectedItemText;
}
</script>

As I explained, for the most part it works fine. Execpt when I click on a likn to another page. Then everything gets set back to a preset default.

Ideally what I am looking for is a way to do a postback when a new item is selected in the combo box (like in the JavaScript). The style is changed so the whole page needs to be refreshed anyway. This works. But when I move to another page, it resets to a default style. So I need a way to store the selected style either client side or server side (preferred as my pages are loaded this way).

I have read this can be done by using a controller but it is not clear how. I would like the controller method if possible, because I am going to use a controller to load a list of CSS styles dynamically allowing the user to download additional styles and they will be added to the list automatically. So anything along this line would be great.

1 Answer 1

2

You can create a static class with a static property which will act as a global property.

public static class MyTheme
{
    public static string MyGlobalTheme { get; set; }
}

or you could you the Application class.

Application["MyTheme"] = "black";

You could put this code in _Layout.cshtml. If your project name is TProj and your static class is in a folder called Objects, it would look like this.

_Layout.cshtml

@{
  if (@Html.ViewContext.HttpContext.Request.QueryString["theme"] != null)
  {
    TProj.Objects.MyTheme.MyGlobalTheme = Html.ViewContext.HttpContext.Request.QueryString["theme"];
  }
  else
  {
    if (TProj.Objects.MyTheme.MyGlobalTheme == null)
    {
      TProj.Objects.MyTheme.MyGlobalTheme = "black";
    }
  }
}

Now in after this in _Layout.cshtml, you can use the string @TreasuryReportsMvc.Objects.MyTheme.MyGlobalTheme, which should stay the same even when you go to another page. _Layout.cshtml may not be the best place for this logic. You should think about where it makes the most sense for your project.

Be aware that global variables are frowned on by many. This question has a good discussion of Asp.Net MVC global variables.

Sign up to request clarification or add additional context in comments.

11 Comments

I dont mean to sound silly, and thanks for the answer. But where do I put the code. I get errors if I put it in the layout.cshtml and other errors if I put it in a base controller, and yet again more errors if I put it into another controller.
I updated the answer to try to make it clearer how to use it.
No, problem. I don't care if you don't accept the answer, but I am trying to be helpful. This is working for me. If you explain how it is not working, I can try to help.
In the example above TProj is the name of my project. You should replace that with the name of your project. Objects is a folder I created where I put the class "MyTheme". _Layout.cshtml needs to know where your class is, but it will be different on your machine.
Thanks again for your help daniel. I got it working. Silly me was using a wrong string. I used the string out of the combo box and query string instead of doing "telerik" + my query string + ".css".
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.