Thursday, July 31, 2008

GirdView Scrollable and Fixed Header

When using GridView .NET 2.0 Control, One of the most common requirement is to have a vertical scroll bar and a fixed header row so that the user can see what columns mean what wherever they are in the Grid and the second part of this is to select a row. The problem with the selection is, when the page posts back (if no AjaxUpdatePanel is used) the scroll position is not maintained.

GridView does not support these features by default; hence we need to use some HTML work around and javascript to achieve this.



First step is to include a vertical scroll bar.



1. Include a Div tag with overflow style and a fixed height set
2. place your Grid within the div ( Make sure you enough rows to scroll)



Code: Please include opening and closing tags...

div id="DivScroll" style="overflow: auto; height: 200px;"

asp:gridview id="“UsrGrid”…….."

asp:gridview

div



Second step is to make a selection and maintain scroll position: you can use “AutoGenerateSelectButton = true



Now, try selecting, scroll position won’t be maintained.



I saw a post in ASP.NET Forums which used this javascript. Came in very handy.



Include a hidden field on the page and set its value = 0.

input id="hdnScrollTop" runat="server" value="0" type="hidden"



Call the javascript function: SetDiv OnScroll



The div tag should look like:

div id="DivScroll" style="overflow: auto; height: 200px;" onscroll="SetDiv()"



The pretty straightforward script is: (Thanks to http://forums.asp.net/p/1019926/1378289.aspx )



script



window.onload = function(){

var strCook = document.cookie;

if(strCook.indexOf("!~")!=0){

var intS = strCook.indexOf("!~");

var intE = strCook.indexOf("~!");

var strPos = strCook.substring(intS+2,intE);

document.getElementById("DivScroll").scrollTop = strPos;

}

}



function SetDiv()

{

var intY = document.getElementById("DivScroll").scrollTop;



document.cookie = "yPos=!~" + intY + "~!";



}







Ok… Now, How to have a Fixed GridView Header. We have to use CSS. (Since GridView will be rendered as HTML Table and cells in the clientside, CSS helps a great deal here). Include a StyleSheet and have these elements. Thanks to (http://www.codeproject.com/KB/webforms/DataGridFixedHeader.aspx )



.DataGridFixedHeader

{

position: fixed;

top:expression(this.offsetParent.scrollTop-2);





}

In the GridView Element HeaderStyle Include the CSS tag



Your GridView HeaderStyle may look like



headerstyle backcolor="#6B696B" bold="True" height="33px" cssclass="DataGridFixedHeader" verticalalign="Middle" forecolor="White"



Now everything looks solid. Except I noticed that the borders for the table cells are missing, after looking around for a while this one extra CSS made it complete. Include the th tag of table (th – table header) CSS.



.DataGridFixedHeader th

{

position:relative;

border-right-width:1px;

border-right-color:White;

border-left-width:1px;

border-left-color:White;

border-top-width:1px;

border-top-color:White;

border-bottom-width:0px;

border-bottom-color:#6B696B;



}



This will do the trick and make the GridView like the below…







Thanks to ASP.NET Forums, CodeProject and Google. Hope this helps some one

Tuesday, June 10, 2008

Few more tips..

To trim or remove trailing zeros from a decimal

string trimDec = "12.0000";

trimDec.TrimEnd("0.".ToCharArray()) + "%"

Displays 12%

Tip # 2
if you pop open up a window when a button is clicked, the user doesnt close the pop up and clicks on the button again, you may want to close the pop up and re open again... use the code below..

// To see if the window was present and close the pop up
ScriptManager.RegisterStartupScript(this.UpdatePanel1, typeof(string), "closeit", "MyExample.close();", true);

ScriptManager.RegisterStartupScript(this.UpdatePanel2, typeof(string),
"alertScript",
"MyExample = window.open('NewPage.aspx','" + this.ddlvalue.SelectedValue + "','resizable = 1,status=0,toolbar=0,location=0,scrollbars=1,width=800px'); ", true);



Tip #3
To access a public method from a Master page in a child page that is using the master page...

Class Name objName = (Cast it as the class name)Page.Master;

MasterPage ParentMasterPage = (MasterPage)Page.Master;

Convert Hex Value of color and apply to a control

A simple thing...To convert any hex value and apply to a control using code behind, use the below

System.Drawing.ColorConverter ccColorConverter = new System.Drawing.ColorConverter();

txtAAgency.ControlStyle.BackColor = (System.Drawing.Color)ccColorConverter.ConvertFrom("#EEEEEE");

PDF Read, Binary Save

To read a pdf file and store it as an image in DB..

string path = @"\test.pdf";

// Open the stream and read it..
using (FileStream fs1 = File.Open(path, FileMode.Open))
{
byte[] b = new byte[fs1.Length];
while (fs1.Read(b, 0, b.Length) > 0)
{
SqlConnection conn = new SqlConnection();
string env = System.Configuration.ConfigurationManager.AppSettings["KeyValue"];
conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings[env].ConnectionString;

SqlCommand command = new SqlCommand("dbo.save_pdf", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@pdf", b);
try
{
conn.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
}

}

To read an Image from DB and display it in a browser...a very crude way to do, but works!

DataSet ds = _PDF.readPDf(1);
byte[] b = (byte[])ds.Tables[0].Rows[0][9];
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(b);
memoryStream.Position = 0;
Response.ContentType = "application/pdf"; //Instead of pdf, if mentioned doc, then a doc
will open..
Response.BinaryWrite(b);
Response.End();

Open PDF

If you want to open a pdf file in browser or any attachment, you would have used the

Response.AddHeader("Content-Disposition", "attachment; filename=" + TheFileName);

Then you either do a BinaryWrite or a WriteFile. A WriteFile opens in the browser as inline attachment. A binary write opens the attachment with a dialog box to open,save or cancel

When the user opens the attachment, you can sometimes see the IE behaves very strangely and does not open the attachment. However,if you save the attachment the attachment is saved correctly and can be viewed. This can be annoying.

We tried to find a solution to this problem, but it looks like it is a IE 6.0 problem. (Oh Good lord, That IE Dev team!! )

This problem is not new and almost every big company like AmericanExpress,BankofAmerica have this issue. Try downloading a pdf from their site..

One thing that can be done to avoid this is to altogether avoid the open option. this can be done by using this meta tag:
start tag meta name="DownloadOptions" content="noopen" / end tag

Or else, Ask your users to be smart and use browsers like FireFox! :)

I hope Microsoft IE dev team reads my blog and takes care of this issue some day.. Its never the end of the world.

the state information is invalid for this page and might be corrupted error

If you ever encountered this error in FireFox, it is because of the caching issue. See if you have any
response headers added to your code and remove the unnecessary ones. Response.SetCache.NoStore() also works. Overall, this is a firefox bug.

asp net forum link to problem

Infragistics Web Numeric Edit

In numeric edit if you have to get the text box value and do some client side validation..and set some new values...the event we need to target is the _ValueChange. The in built functions are

getValue() and SetValue()

script id="igClientScript" type="text/javascript"

function wneHour_ValueChange(oEdit, oldValue, oEvent){

var newValue = oEdit.getValue();
var a = true;

if(newValue < 1)
{
oEdit.setValue("1");
a = false;
}
if(newValue > 12)
{
oEdit.setValue("12");
a = false;
}

if(newValue > 0 && newValue < 10)
{
var leadingzero = "0";
var newtext = leadingzero + newValue;
oEdit.setValue(newtext);
}

//Not calling this event will create a postback
oEvent.cancel = true;
}
// -->
/script

Infragistics Web Panel

I had to recently implement infragistics web panel. Web panel Infragistics has two client side events, ExpandStateChanging and ExpandStateChanged

If you have to do some simple client side validation on web panels say for example expand one web panel and collapse the rest on the page...without posting back, the key is:

A simple thing..but since it was new, i was searching for while and as they say, if you don't know something..you have to RTFM.. thts exactly what i did and used some commonsense too..

igpnl_getPanelById('<%= household_panel.ClientID %>').setExpanded(false);

where igpnl_getPanelById is an inbuilt infragistics function to find the control.

The regular document.getElementById does not work.

The event setExpanded expands (true) or collapses (false).

script id="igClientScript" type="text/javascript"

function general_panel_ExpandedStateChanging(oWebPanel, oEvent)
{
igpnl_getPanelById('<%= h_panel.ClientID %>').setExpanded(false);
igpnl_getPanelById('<%= e_panel.ClientID %>').setExpanded(false);
igpnl_getPanelById('<%= a_panel.ClientID %>').setExpanded(false);
igpnl_getPanelById('<%= pro_panel.ClientID %>').setExpanded(false);

if (oWebPanel.getExpanded() == true)
document.getElementById('<%= general_panel.ClientID %>').title = "Click arrow to the right to expand and close this description.";
else
document.getElementById('<%= general_panel.ClientID %>').title = "";
//Not calling this will do a postback to the server..
oEvent.cancelPostBack = true;
}
// -->
/script