locked
CSS Adapter - AdapterEnabled property doesn't work completely RRS feed

  • Question

  • User1183693555 posted

    Hi,

    I have a problem with the CSS menu adapter and MOSS.

    Once i set for a specific menu control the property  AdapterEnabled="false" - the menu is not rendered with ui/ul anymore but still, the tables from the menu are replaced with div and spans - thing wich breaks my HTML.

    Do you have a solution to tell the adapter to not do any operations to an control or to a set of pages from a specifc folder (which contains the control) ?

     

    Thank you. 

     

    Wednesday, May 2, 2007 4:54 AM

All replies

  • User-534056067 posted

    The good news is that, strictly speaking, the answer is "yes." The bad news is that it is really tricky to do. I'll try to guide you through it if you wish but you have to be prepared to do some tough coding. Are you up for it?

    If so, let me give you some background. First, I'm going to wiggle out of any and all blame. Yes, I wrote these adapters (through RMT 1.0) so their limitations are mine. But I had to work within the .Net framework, which has its own limitations! One of those is that adapters can't be set on a per-control-per-page-or-folder basis. Period. The framework doesn't support it. Trust me. I know the guys who wrote the framework. I worked with them. They are super-bright but they, too, have to build in some boundaries when they write code. Besides, I double checked by reading the pertinent chunks of IL (assembly) code in .Net framework DLLs and confirmed that the current logic won't support per-control-per-page adapter adjustments... unless you do some pretty heavy coding work... which I will describe...

    To start, let's convince ourselves that I'm not full of hot air when I say that this can actually be accomplished. Check out this posting http://forums.asp.net/thread/1481968.aspx. Notice that I gave a very vague description of the solution to Gav on 06-30-2006, 8:10 AM:

    ...experiment with using something like the code you see in the kit's App_Code\SiteSpecific\DynamicAdaptersPage.cs file.  Take a look at its OnPreInit and OnUnload methods.  Do you see how they disable and restore the adapters under some conditions.  You could do likewise in the OnPreInit and OnUnload of your specific page.  Rather than disabling and restoring all adapters, however, you page could try to disable just the TreeView adapter.

    Incredibly, Gav comes back and says:

    ...That worked a treat! It disabled it just for this page.

    So at least you can go into the work knowing that it can be accomplished.

    The pertinent chunks of code that you need to clone, modify and add to your page originally look like this (in DynamicAdaptersPage.cs):

        public class DynamicAdaptersPage : System.Web.UI.Page
        {
            private Hashtable _adaptersOrig = new Hashtable();

            private bool _compatible = false;
            public bool Compatible
            {
                get { return _compatible; }
            }

            public override string StyleSheetTheme
            {
                get
                {
                    return (Request.Cookies["PreferredTheme"] != null) ? Request.Cookies["PreferredTheme"].Value : base.StyleSheetTheme;           
                }
                set
                {
                    base.StyleSheetTheme = value;
                }
            }

            protected override void OnPreInit(EventArgs e)
            {
                if (IsPostBack && (Request.Form["__EVENTTARGET"] != null) && (Request.Form["__EVENTTARGET"].IndexOf("adaptersenabled", StringComparison.OrdinalIgnoreCase) > -1))
                {
                    CSSFriendly.Context.Enabled = !CSSFriendly.Context.Enabled;
                }

                DetermineCompatibility();
                if (_compatible && (!CSSFriendly.Context.Enabled))
                {
                    DisableAdapters();
                }

                base.OnPreInit(e);
            }

            protected override void OnUnload(EventArgs e)
            {
                base.OnUnload(e);

                if (_compatible)
                {
                    RestoreAdapters();
                }
            }

            //////////////////////////////////////////////////////////////////////////////////////////////       

            protected void DisableAdapters()
            {
                _adaptersOrig.Clear();

                foreach (DictionaryEntry entry in HttpContext.Current.Request.Browser.Adapters)
                {
                    _adaptersOrig.Add(entry.Key, entry.Value);
                }

                HttpContext.Current.Request.Browser.Adapters.Clear();
            }

            protected void RestoreAdapters()
            {
                foreach (DictionaryEntry entry in _adaptersOrig)
                {
                    HttpContext.Current.Request.Browser.Adapters.Add(entry.Key, entry.Value);
                }

                _adaptersOrig.Clear();
            }

            private bool DetermineCompatibility()
            {
                _compatible = false;
                foreach (DictionaryEntry entry in HttpContext.Current.Request.Browser.Adapters)
                {
                    if (entry.Value.ToString().IndexOf("CSSFriendly", StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        _compatible = true;
                        break;
                    }
                }

                return _compatible;
            }
        }

    If I were you, I'd reduce this to something like this:

        public class MyPage : System.Web.UI.Page
        {
            private Hashtable _adaptersOrig = new Hashtable();

            protected override void OnPreInit(EventArgs e)
            {
                DisableAdapters();
                base.OnPreInit(e);
            }

            protected override void OnUnload(EventArgs e)
            {
                base.OnUnload(e);

                if (_compatible)
                {
                    RestoreAdapters();
                }
            }

            //////////////////////////////////////////////////////////////////////////////////////////////       

            protected void DisableAdapters()
            {
                _adaptersOrig.Clear();

                foreach (DictionaryEntry entry in HttpContext.Current.Request.Browser.Adapters)
                {
                    _adaptersOrig.Add(entry.Key, entry.Value);
                }

                HttpContext.Current.Request.Browser.Adapters.Clear();
            }

            protected void RestoreAdapters()
            {
                foreach (DictionaryEntry entry in _adaptersOrig)
                {
                    HttpContext.Current.Request.Browser.Adapters.Add(entry.Key, entry.Value);
                }

                _adaptersOrig.Clear();
            }

        }

    This disables all adapters for this whole page. If you wanted to disable just some of the adapters (like all TreeView adapters) then you'd need to change the logic in DisableAdapters so it skipped disabling some of them through some decision-making logic.

    I encourage you to give this a try or write back for more help. It's a interesting problem to solve, one that many other developers have asked about on this forum. You are in good company.

    Thursday, May 3, 2007 10:39 AM
  • User-1207404732 posted

    Hi,

    I found another work around to this problem.

    The problem beeing that we want just some controls to be affected by the CSS Friendly Adapters, I made new user controls that just inherit themselves from the original ones and those are the ones I specify in the CSSAdapter.browser as having to be converted into CSS Friendly controls.

    In this case I would have done this:

    in CssMenu.cs (from a Web User Control Library Project): 

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace BasicWebControls
    {
    public class CssMenu : Menu
    {

    }
    }

     
     

    in  CSSAdapter.browser (From a Website Project)
     

    <browsers>
    <browser refid="Default">
    <controlAdapters>
    <adapter controltype="BasicWebControls.CssMenu"
    adapterType="CSSFriendly.MenuAdapter" />
    </adapter>
    </controlAdapters>
    </browser>
    </browsers>
     
    Hope it helps !
     
    Tuesday, October 16, 2007 2:57 AM
  • User-387095454 posted

    You can also just replace the Adapter in your code like this:

    protected override void OnPreInit(EventArgs e)
    {
        HttpContext.Current.Request.Browser.Adapters["System.Web.UI.WebControls.Menu, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"] = "Supertext.Adapters.iUiMenuAdapter";
        base.OnPreInit(e);
    }

    protected override void OnUnload(EventArgs e)
    {
        base.OnUnload(e);

        HttpContext.Current.Request.Browser.Adapters["System.Web.UI.WebControls.Menu, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"] = "CSSFriendly.MenuAdapter";
    }

    More on my blog.

    Tuesday, November 11, 2008 6:05 PM