Blog - Microsoft .NET, ASP.NET, AJAX and more

Dynamic Control ViewState Problems

by Damien White 7/23/2008 8:08:19 PM

Technorati Tags: ,

The ID Property is Important

I've encountered quite a few developers having ViewState problems with dynamic controls.  Ever have a control get recreated, but the value isn't there on PostBack and you are creating your controls at the correct time?  Frustrating to say the least.  Anyway, even if you follow the correct pattern for creating / recreating dynamic controls, you may either forget (D'oh) or don't set (Double D'oh) an ID for the control.  By not setting an ID, you are relying on ASP.NET to create the control with the same ID.  Sometimes it will, other times it won't... not a gamble you should take.  More...

Shout it kick it on DotNetKicks.com Bookmark and Share
Tags:
Categories: .NET | ASP.NET | C# | CSS
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

AJAX Control Toolkit - Layout Problems

by Damien White 6/11/2008 9:55:07 PM

A real common problem with using the AJAX Control Toolkit revolves around the rendering of the controls.  Taking an example from the ASP.NET Forums, let's say you have a Tab Control on your page.  Everything looks ok, and then you run it.  You notice that there is a weird space towards the bottom of one of your tabs.  D'oh!  What could be wrong?  Well, in general, usually the cause of these types of problems are related to one of two issues, Quirks Mode or CSS conflicts.  In the ASP.NET Forum example above, it was a Quirks Mode issue. More...

Shout it kick it on DotNetKicks.com Bookmark and Share
Tags:
Categories: AJAX | AJAX Control Toolkit | ASP.NET | CSS
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Modal UpdateProgress for UpdatePanel - Revisited

by Damien White 3/13/2008 3:08:22 PM

Back in September 2007, I posted an article which described a way to "disable" an UpdatePanel (or more specifically an entire page) by using a modal UpdateProgress control.  This solution would allow developers to stop users from clicking on other items on the page while the UpdatePanel is processing.  The premise behind this was taking a DIV and stretching it over the top of the page using CSS, and having a message (e.g. "Please Wait") on top of that.  This is achieved by using some simple CSS.  If you want to read the original article, you can view it here:

http://blogs.visoftinc.com/archive/2007/09/10/modalupateprogress.aspx

Since that time, this continues to be one of the most popular posts and many people have wanted to use this solution with IE 6.  Well, the original version showed the message, but not the "blanket" modal DIV in IE 6.  There were also issues with scrollbars where the "blanket" would stay at the top and users could still see the bottom of the page if they scrolled.  I'm happy to say that there is a solution to these issues...  The following techniques were tested in IE 7 (7.0.6001.18000), Firefox 2.0.0.12, and IE 6 (6.0.2900.2180) in Standards Mode.

First, the code is the same, but instead of going back to the old post, here it is again:

<asp:updateprogress associatedupdatepanelid="UPDATEPANELID" 
    id="updateProgress" runat="server">
    <progresstemplate>
        <div id="progressBackgroundFilter"></div>
        <div id="processMessage"> Loading...<br /><br />
             <img alt="Loading" src="images/ajax-loader.gif" />
        </div>
    </progresstemplate>
</asp:updateprogress> 

Pretty simple code… basically the only “custom code” are the two DIVs. The first, progressBackgroundFilter is used to blank out the page. The second, progressMessage, is the message to display. In this case, it’s just text and an animated gif.

Solution for IE 7 and Firefox

Now for the styles, this is where we will fix the problems in the old solution.  First, let's start with IE 7 and Firefox.  The old solution worked well, however it had a problem with scrollbars.  To fix this in modern browsers, we will use the CSS property position: fixed.

#progressBackgroundFilter {
    position:fixed; 
    top:0px; 
    bottom:0px; 
    left:0px;
    right:0px;
    overflow:hidden; 
    padding:0; 
    margin:0; 
    background-color:#000; 
    filter:alpha(opacity=50); 
    opacity:0.5; 
    z-index:1000; 
}
#processMessage { 
    position:fixed; 
    top:30%; 
    left:43%;
    padding:10px; 
    width:14%; 
    z-index:1001; 
    background-color:#fff;
    border:solid 1px #000;
}

The only difference in this code is the position (which I have made bold and underlined in the snippets above).  We are utilizing position: fixed, which means to pin the elements to the viewport regardless of the scroll position.  Previously, we used position: absolute; which caused our "blanket" to position itself relative to the original viewport, but not the entire page, so the problem came about when there are scrollbars.

Fun (not) with IE 6

Now, for IE 6 (Note, it may work in other versions of IE, but I haven't tested it).  The problem with the initial solution was that IE 6 ignored the right and bottom CSS styles.  All we could see was the processMessage DIV, but not the background filter.  A first attempt at fixing this was to add a height and width to the progressBackgroundFilter for anything below IE 7.  A width of 100% stretched it horizontally, but a height of 100% did nothing.  Obviously a fixed height, e.g. 200px worked, but not much use when we don't know the height.  After a bit of research, I came across an article titled "Conflicting Absolute Positions" by Rob Swan, which greatly helped in coming up with a solution.  IE 5 and 6 offer an alternative to just percents and fixed sizes, it allows us to dynamically set styles by using an expression.  An expression is just a JavaScript snippet for a given value.  Have a look at "Conflicting Absolute Positions" for more information on IE's CSS expressions.  Without further ado, here's the complete CSS for IE 6:

body { height: 100%; }

#progressBackgroundFilter 
{
    position:absolute;
    height: expression(document.body.clientHeight + "px");
    width: expression(document.body.clientWidth + "px");
}
#processMessage { 
    position:absolute; 
    top: expression((document.body.clientHeight * .30) + "px")
}

First, as mentioned, IE 6 doesn't understand position: fixed; and reverts back to position: static, so the first step is to set position to absolute only for IE 6 and below in both the #processBackgroundFilter and #processMessage.  The rest of the styles utilize expressions, with the exception of body style above, which I will discuss in a bit.  The premise behind the expressions is to calculate the full page dimensions and position the background filter.  For the message, I wanted to appear in the viewport 30% from the top of the screen like the IE 7 / Firefox counterpart, so that is why there is a calculation for the top.  The thing that doesn't happen with the message that does occur in IE7 and Firefox is that the message "follows" the user if they scroll.  You could do capture the scroll event and move the message, but I feel this is overkill, plus it complicates the simplicity of the "Modal UpdateProgress" solution. 

One thing to note here is that the expressions are using JavaScript, if a user has JavaScript disabled, the CSS expressions do not work.  However, if they don't have JavaScript enabled, the expressions are the least of your problems.  Their overall AJAX experience will be non-existent.  Just note this if you use expressions in other types of applications.

Anyway, in trying to getting this to work I encountered some issues with the JavaScript calculations and getting everything to work in sync.  One thing to note here is that IE 6 is overly sensitive to DOCTYPE declarations making it difficult when dealing with box models (e.g. quirks vs. standards).  On my pages, I use the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

For determining if IE 6 will be rendered in quirks mode vs. standards mode, I typically refer to the Wikipedia's Quirks Mode page and the document type comparison that they have.  I like to work in standards mode since that is what modern browsers use, but the DOCTYPE for XHTML 1.1 isn't in the list, but XHTML 1.0 is, and further down the page it does list XHTML 1.1 as standards rendering.  So, I went over to QuirksMode.com and referenced the article titled "document.body and doctype switching," which was very helpful. 

Originally, I simply had the expressions for just the two elements and this was the result when the browser was maximized:

ModelUpdateProgressRevisted_IE6_WO_Height 
Figure 1 - IE 6 without body { height: 100%; }

Notice the issue with the bottom of the page in Figure 1?  The progressBackgroundFilter doesn't cover everything.  I tried all sorts of stuff, then using the IE Developer Toolbar, I saw what was happening.  since the page I was on was short, the body element only expanded just to the bottom of the content.  I have no idea though why it's still just a tad shorter than the body as shown in Figure 1 (see the bit of darker blue that is peeking out?).  I believe it has to do with body padding and or margins, but my investigation on the topic ended there; I just chalked it up to IE 6 baffling me sometimes.  Anyway, I thought to add the height: 100%; style to the BODY element.  This turned out much better as shown in Figure 2 below.

ModelUpdateProgressRevisted_IE6_With_Height
Figure 2 - IE 6 with body { height: 100%; }

Much better, but your solution to the IE 6 woes may differ to mine.  My basic styles on this site are as follows:

body { margin:0; padding:0;}
#container { margin:10px auto; }

You can see the body has no margin or padding (this would push out the body in IE 6 because it would be 100% + the margin and padding causing the page to scroll when it didn't have to).  I achieve the margin on the top and bottom by assigning these to my outer container which is just a DIV where all the content lies.  Your design may not permit you to do the height: 100% trick, but in my case it was the solution.

IE 6 - Other attempts at a solution (more fun)

When playing around with IE 6, I attempted all sorts of things before using, the one solution that worked about 90% is as follows:

#progressBackgroundFilter 
{
    position:absolute;
    height: expression(document.documentElement.scrollTop + document.documentElement.clientHeight + "px");
    width: expression(document.body.clientWidth + "px");
}
#processMessage { 
    position:absolute; 
    top: expression(document.documentElement.scrollTop + (document.documentElement.clientHeight * .30) + "px")
}

The thinking behind this was to take the window height (which document.documentElement.clientHeight gives us) and then add the scroll top position, which will give us the upper portion if the user scrolls up.  The problem shows itself when the user scrolls down; that area is not covered.  The good thing about this is that I didn't need to mess with the body height, but the solution isn't optimal in the long haul.  Note this solution does work in the maximized state unlike other attempts (e.g. Figure 1 from earlier). 

The purpose for me adding this "solution" is my hope that you, the reader, can come up with a solution that doesn't involve body { height: 100%; }.  Hopefully these attempts may help you come up with something a bit better.  As stated earlier, the height thing can throw off some overall designs that you may have, for example if you have a margin or padding on your body element, your page will be that much longer.

Putting it all together

To get these styles to work with IE 7, Firefox, and IE 6, we need some technique to hide the IE 6 code from the other browsers.  This is easily achieved without hacks and such by using a conditional comment.  Conditional comments allow us to specify CSS code for a certain browser or range of browsers, hiding it from others. 

The syntax for a condition comment follows a standard HTML comment (e.g. <!-- This is a comment -->) so that most browsers will simply ignore it.  Internet Explorer however recognizes the <!--[if IE]> and processes it as part of the page.  You can use specifics such as a straight browser version or a range using "lt" for "Less Than", "gt" for "Greater Than", and you can append an "e" (e.g. "lte" and "gte") for "Or Equal To".

In this case, we want to apply the IE 6 specific CSS to anything less than IE 7 (so the syntax is <!--[if lt IE 7]>).  Here is snippet of what my HEAD section looks like, complete with conditional comment:

<head>
    <title>Visoft Inc.</title>
    <link href="styles.css" rel="stylesheet" type="text/css" />
    <!--[if lt IE 7]> <style type="text/css">@import "ie6.css";</style><![endif]-->
</head>

The IE 6 specific logic resides in the file ie6.css while everything else is in styles.css.  Since the IE 6 specific stuff comes after the generic stuff, the styles will be overridden only for IE 6.

The end results

You've already seen a snapshot of IE 6, so here is what IE 7 and Firefox look like:

ModelUpdateProgressRevisted_IE7
Figure 3 - IE 7 with the Modal UpdateProgress

ModelUpdateProgressRevisted_Firefox  
Figure 4 - Firefox with the Modal UpdateProgress

With this revised solution you should be able to use this approach in more designs where you need to disable the rest of the controls from the user.  I feel that this is a nicer option that hiding content on the page or whatnot to achieve the same thing.  The user's experience is very important to the success of an application in the user's eyes, so the nicer the UI, the better your application is perceived.    

Shout it kick it on DotNetKicks.com Bookmark and Share

AJAX Control Toolkit - Tab Control - Themes

by Damien White 9/26/2007 8:56:50 PM

There seems to be a lot of issues on the ASP.NET Forums with "Theming" the AJAX Control Toolkit's Tab Control. There are lots of requests for samples (one example), but there are limited resources out there. Looking at the Tabs sample page, you will find information on Theming, but it's pretty basic. You will find the various styles that affect the tabs on the bottom of the sample page. Even with this, it leaves something out and people have problems.   I believe the thing that throws people off is how the sample states "If your CssClass does not provide values for any of those then it falls back to the default value."; the default value for the tabs are extremely basic.  The style you most frequently see is the XP tab style (more on this later).

I feel you should begin by looking at the structure of the tab HTML to truly understand how it works. If you are curious about the other HTML structure, check out Firebug. The power of Firebug is truly amazing; this is a sample screenshot but doesn't even come close to paying Firebug justice:

[If anyone from the Microsoft IE team is listening; PLEASE give us this power in IE7 or IE8, the Internet Explorer Developer Toolbar is ok, but it just feels crippled next to Firebug and "Firebug Lite" doesn't fill any of the real gap.]

Let's take a closer look at the tab structure:

01 <span id="..." class="ajax__tab_active">
02   <span class="ajax__tab_outer">
03     <span class="ajax__tab_inner">
04       <span id="..." class="ajax__tab_tab">Tab 1</span>
05    </span>
06  </span>
07 </span>

 

As you can see, a tab is constructed of nested <span> tags. The class ajax__tab_outer defines the right side of the tab, the class ajax__tab_inner defines the left side of the tab, and finally ajax__tab_tab defines the middle of the tab as this image shows:

 

 

Now that we understand the tab structure, let's work on some styles. In this example, we'll clone the tab styles of Internet Explorer 7 (IE7) under Windows XP. The easiest way to create new styles is to copy that of the ajax__tab_xp which is the default style that you typically see. Browsing the source of the Tab control (which you can download from Codeplex), navigate to the AjaxControlToolkit\Tabs folder and open up Tabs.css. You will find a section called xp theme; this is what we are copying. Looking at the CSS you'll see that the effects for the tab are created using images and for the IE7 style, we will do the same. So in copying the XP style, we create the following images:

  • tab-line.gif – Used to underline the header
  • tab-right – The right side of the inactive tab
  • tab-left – The left side (outer) of the inactive tab
  • tab – The inner portion (tab) of the inactive tab
  • tab-right-hover – The right side of the hover tab
  • tab-left-hover – The left side (outer) of the hover tab
  • tab-hover – The inner portion (tab) of the hover tab
  • tab-right-active – The right side of the active tab
  • tab-left-active – The left side (outer) of the active tab
  • tab-active – The inner portion (tab) of the active tab

 

…and finally create the styles (I have separated the background declarations from the other styles just for simplicity of listing and discussions)

First the backgrounds; this is a carbon copy of the ajax__tab_xp with just our new images replacing the embedded ones.

/* IE theme – Backgrounds */

.visoft__tab_xpie7 .ajax__tab_header {
     
background:url(tab-line.gif) repeat-x bottom;
}

.visoft__tab_xpie7 .ajax__tab_outer    {
     
background:url(tab-right.gif) no-repeat right;
}

.visoft__tab_xpie7 .ajax__tab_inner    {
    
background:url(tab-left.gif) no-repeat;
}

.visoft__tab_xpie7 .ajax__tab_tab {
    
background:url(tab.gif) repeat-x;
}

.visoft__tab_xpie7 .ajax__tab_hover .ajax__tab_outer {
    
background:url(tab-hover-right.gif) no-repeat right;
}

.visoft__tab_xpie7 .ajax__tab_hover .ajax__tab_inner {
    
background:url(tab-hover-left.gif) no-repeat;
}

.visoft__tab_xpie7 .ajax__tab_hover .ajax__tab_tab {
    
background:url(tab-hover.gif) repeat-x;
}

.visoft__tab_xpie7 .ajax__tab_active .ajax__tab_outer {
    
background:url(tab-active-right.gif) no-repeat right;
}

.visoft__tab_xpie7 .ajax__tab_active .ajax__tab_inner {
    
background:url(tab-active-left.gif) no-repeat;
}

.visoft__tab_xpie7 .ajax__tab_active .ajax__tab_tab {
     background:url(tab-active.gif) repeat-x;
}

 

Finally, the rest of the styles which we'll change a bit from the ajax__tab_xp styles:

.visoft__tab_xpie7 .ajax__tab_header {
    
font-family:verdana,tahoma,helvetica;
    
font-size:11px;
}

.visoft__tab_xpie7 .ajax__tab_outer {
    
height:29px;
}

.visoft__tab_xpie7 .ajax__tab_inner    {
     padding-left:3px;
}

.visoft__tab_xpie7 .ajax__tab_tab {
    
padding:8px 40px;
     margin:0;
}

.visoft__tab_xpie7 .ajax__tab_body
    
font-family:verdana,tahoma,helvetica
    
font-size:10pt;
    
border:1px solid #999999;
    
border-top:0;
    
padding:8px;
    
background-color:#ffffff;
}

Most of the styles are arbitrary (and most are copies from the ajax__tab_xp styles), but the two import styles that effect the tab are the height and padding, underlined in the sample above. The height matches that of the tab images while the padding increases the width and centers the text vertically and horizontally. You could set different left and right paddings to change the text alignment, but in this example we have it centered.

The last thing we need to do is to add the custom CssClass to the Tab Container:

<ajaxcontroltoolkit:tabcontainer id="tabContainer" runat="server" height="300" cssclass="visoft__tab_xpie7">

Finally, everything in place; we get the following tab style:

The three styles are represented in the image: tab, active, and hover. Not a bad reproduction from the original. Obviously, we don't have an image in the header in this example, but this can always be added using the <headertemplate> of the Tab Panel. You can also go a bit farther with the replication and add the thin bar that is below the tabs.

 

 

If you'd like, you can download the files for this sample: Full Solution | CSS and Images Only

Shout it kick it on DotNetKicks.com Bookmark and Share

Modal UpdateProgress for UpdatePanel

by Damien White 9/10/2007 12:08:09 PM

If you are interested in this topic, you should check out the new post: "Modal UpdateProgress for UpdatePanel - Revisited" on this topic.  The solution in this post had some issues that have been corrected in the new post.

UpdateProgress_ModalWait I’ve seen a lot of requests on the ASP.NET forums for ways to display disable an UpdatePanel during an update.  I’ve seen quite a few complex techniques to achieve this, but by using standard controls you can create a nice looking modal progress indicator.  Using the UpdateProgress control, there is an easy way to make the progress indicator modal with little code and a bit of CSS.

 

First, let’s start with the code:

<asp:updateprogress associatedupdatepanelid="UPDATEPANELID" id="updateProgress" runat="server">

    <progresstemplate>

        <div id="progressBackgroundFilter"></div>

        <div id="processMessage"> Loading...<br /><br /><img alt="Loading" src="images/ajax-loader.gif" /></div>

    </progresstemplate>

</asp:updateprogress>   

 

Pretty simple code… basically the only “custom code” are the two DIVs.  The first, progressBackgroundFilter is used to blank out the page.  The second is the message to display.  In this case, it’s just text and an animated gif.

 

The rest of the code is just CSS.  In this example, I am using the id selector approach of CSS to add the styles to the DIVs but you can of course changed these to class names.

#progressBackgroundFilter {
  position:absolute
;
  top:0px
;
  bottom:0px
;
  left:0px
;
  right:0px
;
  overflow:hidden
;
  padding:0
;
  margin:0
;
  background-color:#000

  filter:alpha(opacity=50)
;
 
opacity:0.5
;
  z-index:1000
;
}

 

#processMessage { 
  position:absolute
  top:30%
  left:43%;
  padding:10px;
  width:14%;
  z-index:1001;
  background-color:#fff;
} 

The progressBackgroundFilter is what blanks out the screen.  This operates like standard modal code by simply overlaying a DIV on top of the content using absolute positioning.  The z-index is what sets it to be over the content; this number can be anything, but I set it to 1000 so it would be much higher than any other absolutely positioned object.  The filter is used to set the transparency in IE while the opacity is for FireFox; both set the transparency to half.  Finally, the processMessage styles position a div above the background filter (z-index is set to 1001).  The top, left and width are set to percentages to horizontally center the box and the top is arbitrarily placed 30% from the top.

 

In the inital post, I mistakenly left out some of the CSS properties.  The bold styles are new and they should now work successfully...

 

KNOWN ISSUES:

This technique was tested with IE 7 and FireFox. 

This technique works well when your page doesn't scroll, but has a few problems when there is a scrollbar involved.  The problem is with position:absolute, it can't seem to figure out bottom:0px when you scroll.  One way around this is to use postion:fixed instead, but this has problems in IE6. Even with this, there is no way to overlay the browser's scrollbar.  The only real option is to use JavaScript to position the background and message, such as subModal: http://sublog.subimage.com/articles/2006/01/01/subModal.  Even this doesn't blank out the browser's scrollbars though.

The best condition for making modal items work easily is using a separate container DIV and hiding the browser's scrollbar.  One of my favorite layouts is Stu Nicholls' approach to a fixed layout: http://www.cssplay.co.uk/layouts/fixit.html (also see the rest of his website for some real awesome CSS fun).  With this approach, the overlay can block out the scrollbars as well.

There is a demo of the modal UpdateProgress over at http://www.visoftinc.com/samples/UpdateProgress.aspx.  This demo isn't using the inner container, so you can see the known issue if you shrink the window to have scrollbars appear.  

Shout it kick it on DotNetKicks.com Bookmark and Share