Wednesday, May 18, 2011

BMI Calculator in asp.net

Introduction
Designing apps in Microsoft Visual C++ 2005 Express Edition is pretty straight forward. Point this, click that, presto! Place it on form. But seriously, click on the desired component (control), located at the left toolbar of Visual C++ 2005 Express Edition, and draw it at an appropriate location on the form. Components on the form align to rectangular grids, giving your apps a symmetric look.

This simple app demonstrates the ease of creating a simple metrics system BMI calculator in Windows Forms using C++.

BMI
But first: The body mass index is a statistical measure used to estimate a healthy body weight and is the most widely used diagnostic tool and is utilized to identify whether individuals are underweight, overweight or obese.

BMI Determinants
•Underweight = <18.5
•Normal weight = 18.5-24.9
•Overweight = 25-29.9
•Obesity = BMI of 30 or greater
DataGridView
Fast forwarding a bit, we've created a Windows Form, placed a horizontal scrollbar, plus some buttons and textboxes. To have the control respond to mouse clicks, we have to put some code into it. So we double-click on a control and we are presented with an event method. All we have to do is place some code in that control's event method.

Let's click on a hScrollBar and place relevant code in its dataGridView1_CellContentClick( ) section, to have it handle some events.

The hScrollBar1_ValueChanged Event
The hScrollBar1_ValueChanged event is called upon when the scrollbar values change when a user interacts with it by dragging it for instance. As this is being done, the application updates the displays by making calls to setDiagnos() and calculateBMI() to calculate and display the new BMI values.

private: System::Void hScrollBar1_ValueChanged
(System::Object^ sender, System::EventArgs^ e)
{
hScrollBar1->Value=height;
hScrollBar2->Value=Weight;
hScrollBar3->Value=BMI;
}

public: void setDiagnos()
{
double Weight2=BMI*((height/100)*(height/100));
double bmiDiff=0;
if (BMI>=22) bmiDiff=BMI-22; if (BMI<22) bmiDiff=22-BMI;
double preferredWeight=bmiDiff*((height/100)*(height/100));

if ((BMI>=-1)&& (BMI<7)) Diagnos=" BMI under 7 is rare ";
if ((BMI>6) && (BMI<11)) Diagnos=" Health hazrd, Cardiac stress ";
if ((BMI>10) && (BMI<16)) Diagnos=" You are an Anorectic ";
if ((BMI>15) && (BMI<20)) Diagnos=" You should gain weight ";
if ((BMI>19) && (BMI<24)) Diagnos=" You have reached your ideal weight";
if ((BMI>23) && (BMI<28)) Diagnos=" You are in good health ";
if ((BMI>27) && (BMI<32)) Diagnos=" You should loose weight";
if ((BMI>31) && (BMI<42)) Diagnos=" Health hazrd, Cardiac stress";
if (BMI>41) Diagnos=" BMI above 42 is rare";

textBox1->Text= "Actual Weight = "+Weight+" kg ";
textBox2->Text =Diagnos;
textBox3->Text= "Actual Height = "+height+" cm ";
textBox4->Text= "Actual BMI = "+BMI+" bmi";
textBox5->Text= "Weight = "+Weight2+" kg";
textBox8->Text= "Weight difference = "+preferredWeight+" kg";
textBox9->Text= "bmi difference = "+bmiDiff+" bmi";

if (BMI>22){textBox6->Text= "ideal Weight =
"+(Weight-preferredWeight)+" kg";textBox7->Text= "Loose =
"+(preferredWeight) +" kg"; }
else{ textBox6->Text= "ideal Weight = "+(Weight+preferredWeight)+" kg";
textBox7->Text= "Gain = "+(preferredWeight) +" kg"; }

}

public: void calculateBMI()
{
if (height>240)
{
MessageBox::Show( "Max Height is 240" +"\n"+"\n",
"Input Error",MessageBoxButtons::OK ,MessageBoxIcon::Error );
height=tmp1;textBox10->Text=height+"";
}
if (Weight>240)
{
MessageBox::Show( "Max Weight is 240" +"\n"+"\n",
"Input Error",MessageBoxButtons::OK ,MessageBoxIcon::Error );
Weight=tmp2;
textBox11->Text=Weight+"";
}
BMI= Weight/((height/100)*(height/100));
if (BMI>64000) BMI=64000; setDiagnos();
} The getDataFromTextBox() Method
The getDataFromTextBox() method is called upon when data is input from a textbox. And again, the application updates the displays by making calls to setDiagnos() and calculateBMI() to calculate and display the new BMI values.

void getDataFromTextBox()
{
tmp1=height;tmp2=Weight;
//height=atoi(str);
try
{
height=System::Convert::ToInt32(textBox10->Text);
}
catch ( Exception^ e )
{
MessageBox::Show( e->Message +"\n"+"Enter Digits (0-9).\n",
"Input Error",MessageBoxButtons::OK ,MessageBoxIcon::Error );
textBox10->Text=tmp1+"";
height=System::Convert::ToInt32(textBox10->Text);
}
try
{
Weight=System::Convert::ToInt32(textBox11->Text);
}
catch ( Exception^ e )
{
MessageBox::Show( e->Message +"\n"+"Enter Digits (0-9).\n",
"Input Error",MessageBoxButtons::OK ,MessageBoxIcon::Error );
textBox11->Text=tmp2+"";
Weight=System::Convert::ToInt32(textBox11->Text);
}
calculateBMI();
updscb();
}

And that is how easy it is to create a simple BMI calculator in Windows Forms.

Custom editable Datagrid with paging and sorting

This article shows you how to create a custom DataGrid with paging, alternate sorting, and is also completely editable

Details
When I was developing some asp.net pages, I lost a lot of time with Datagrids. The code here is to made that work more simple. Only drag the control to the page, complete some properties, point to the methods that controls the updating, deleting and you have a complete editable grid.

[ToolboxData("<{0}:editableElphGrid runat="\""server\">
")]
//ParseChildren allow to work with templates inside the custom datagrid
[ParseChildren(true)]
public class editableElphGrid : System.Web.UI.WebControls.DataGrid
{
///
/// Points to the method that returns a datatable with data
/// Apunta a la funcion q devolvera un dataTable con los datos
///

public delegate DataTable getData();
///
/// Obtain data event
/// Evento de obtener datos
///

public event getData GetData;
///
/// Points to method(to update data)
/// Apunta a un metodo q nos servira para modificar datos
///

public delegate void updateData(int dataKey,DataGridCommandEventArgs e);
///
/// Update data event
///

public event updateData UpdateData;
///
/// Points to method(delete data)
/// Apunta al metodo q usaremos para eliminar los datos
///

public delegate void deleteData(int dataKey,DataGridCommandEventArgs e);
///
/// delete data event
///

public event deleteData DeleteData;
///
/// Cancel data
///

public delegate void cancelData(int dataKey,DataGridCommandEventArgs e);
///
/// cancel data event
///

public event cancelData CancelData;
///
/// edit data
///

public delegate void editData(int dataKey,DataGridCommandEventArgs e);
///
/// edit data event
///

public event editData EditData;
// Note: the params passed on the delegates
// dataKey: is the DataKey field of the edited/
// canceled/updated/deleted row
// e: for work with the cells of the grid
///
/// First sorting field
/// campo por el q se ordenara en la primera carga
///

private string _cFirst="";
///
/// First sorting field
/// campo por el q se ordenara en la primera carga
///

public string FirstSortingField
{
get
{return _cFirst;}
set
{_cFirst=value;}
}
// Inicializamos el grid
protected override void OnInit(EventArgs e)
{
//paginacion=true
this.AllowPaging=true;
//ordenacion=true
this.AllowSorting=true;
//evento cambio de pagina
//ADD the events
this.PageIndexChanged+=new DataGridPageChangedEventHandler(
cPage_elphGrid);
//evento ordenar
this.SortCommand+=new DataGridSortCommandEventHandler(
Order_elphGrid);
//evento de cargar datos
this.Load+=new EventHandler(elphGrid_Load);
this.EditCommand+=new DataGridCommandEventHandler(Edit_elphGrid);
this.CancelCommand+=new DataGridCommandEventHandler(Cancel_elphGrid);
this.DeleteCommand+=new DataGridCommandEventHandler(Delete_elphGrid);
this.UpdateCommand+=new DataGridCommandEventHandler(Update_elphGrid);
//clear the columns
//limpiamos las columnas
this.Columns.Clear();
//create the editComandColumn an deleteColumn
//creamos las columnas de editar i eliminar
EditCommandColumn col=new EditCommandColumn();
col.ButtonType=ButtonColumnType.LinkButton;
col.CancelText="Cancel";
col.EditText="Edit";
col.UpdateText="Update";
this.Columns.Add(col);
ButtonColumn delCol=new ButtonColumn();
delCol.CommandName="Delete";
delCol.ButtonType=ButtonColumnType.LinkButton;
delCol.Text="Delete";
this.Columns.Add(delCol);
}
private void elphGrid_Load(object sender, EventArgs e)
{
if(!this.Page.IsPostBack)
{
//changed Session object for Viewstate
if(this.AllowSorting&&this._cFirst!="")
this.ViewState.Add("_orderBy",this._cFirst);
this.ViewState.Add("_orderType","ASC");
this.DataSource = CreateDataSet();
this.DataBind();
}
}
private void cPage_elphGrid(object sender,
DataGridPageChangedEventArgs e)
{
//PAging
this.CurrentPageIndex = e.NewPageIndex;
this.DataSource = CreateDataSet();
this.DataBind();
}
private ICollection CreateDataSet()
{
//this.ObtenerDatos call a external function that return data
DataTable dt=this.GetData();
if(this.AllowSorting&&this.ViewState["_orderBy"]!=null)
{
//sort the grid
if(this.ViewState["_orderType"].ToString() == "ASC")
dt.DefaultView.Sort=(string)
this.ViewState["_orderBy"].ToString()+" ASC";
else if(this.ViewState["_orderType"].ToString()=="DESC")
dt.DefaultView.Sort=(string)this.ViewState["_orderBy"]+
" DESC";
}
return dt.DefaultView;
}
public void Order_elphGrid(object sender, DataGridSortCommandEventArgs e)
{
this.ViewState["_orderBy"]=(string)e.SortExpression;
if(this.ViewState["_orderType"].ToString()=="ASC")
this.ViewState["_orderType"]="DESC";
else if(this.ViewState["_orderType"].ToString()=="DESC")
this.ViewState["_orderType"]="ASC";
this.DataSource = CreateDataSet();
this.DataBind();
}
public void Edit_elphGrid(object sender,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
this.EditData(id,e);
this.EditItemIndex=e.Item.ItemIndex;
this.DataSource = CreateDataSet();
this.DataBind();
}
public void Delete_elphGrid(object sender,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
this.DeleteData(id,e);
this.EditItemIndex=-1;
this.DataSource = CreateDataSet();
this.DataBind();
}
public void Update_elphGrid(object sender,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
this.UpdateData(id,e);
this.EditItemIndex=-1;
this.DataSource = CreateDataSet();
this.DataBind();
}
public void Cancel_elphGrid(object sender,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
this.CancelData(id,e);
this.EditItemIndex=-1;
this.DataSource = CreateDataSet();
this.DataBind();
}
}Well, now add the control on a page, and then you must fill the fields .

DataKeyField: That is the key field of the table, the unique identifier of a row. I put because I use that on Database actions, like delete a specific row etc.

And on the tab of Events :- GetData, CancelData, EditData and DeleteData.

Finally you should have something like this.

On the aspx page:

DataKeyField="intId">On the code behind

Collapse | Copy Code
protected elphControls.editableElphGrid EditableElphGrid1;

private void InitializeComponent()
{
this.EditableElphGrid1.DeleteData +=
new elphControls.editableElphGrid.eliminarDatos(this.del);
this.EditableElphGrid1.GetData +=
new elphControls.editableElphGrid.obtenerDatos(this.obt);
this.EditableElphGrid1.EditData +=
new elphControls.editableElphGrid.editarDatos(this.edit);
this.EditableElphGrid1.UpdateData +=
new elphControls.editableElphGrid.actualizarDatos(this.act);
this.EditableElphGrid1.CancelData +=
new elphControls.editableElphGrid.cancelarDatos(this.cncl);
this.Load += new System.EventHandler(this.Page_Load);
}
private System.Data.DataTable obt()
{
OleDbConnection conn=new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data source=E:\\bdProves.mdb");
OleDbDataAdapter adapter=new OleDbDataAdapter("select * from tabla",conn);
adapter.SelectCommand.CommandType=CommandType.Text;
conn.Open();
DataSet ds=new DataSet();
adapter.Fill(ds,"aa");
conn.Close();
conn.Dispose();
return ds.Tables["aa"];
}
private void edit(int dataKey,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//here the logic asociated with edit comand... if you have
}
private void del(int dataKey,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//here the logic asociated with delete comand
}
private void cncl(int dataKey,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//here the logic asociated with Cancel comand
}
private void act(int dataKey,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//here the logic asociated with update comand
}
Update
Changed the session to save the sorting params for a viewstate, now you can have two grids on the same page. Also Changed the declaration of the first sorting field, now this isn't necessary. Thanks to Zanoza.

ASP.NET PhotoBook

Introduction
This ASP.NET application shows thumbnails and photos. It does nothing more and nothing less.

Background
Every year we go on holiday with a couple of friends. After each holiday, we want to share our digital photos. We tried mailing a CD around, but we wanted a better solution. So I volunteered to make a website where everyone can download the photos they want.

I wanted the application to be as simple as possible. Just a webpage with some photos. And no database. I ended up with one webpage with two custom controls.

Using the code
The webpage itself is very simple. It is just plain HTML (with some ASP.NET of course). All formatting of the page is done in CSS.

Also, the code behind the page is simple:

public class _default : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Panel pnlPhotos;
protected Photobook.Photos Photos1;
protected BookTree BookTree1;

private void Page_Load(object sender, System.EventArgs e)
{
Photos1.Holiday = Request.QueryString["Holiday"];
Photos1.By = Request.QueryString["By"]; }
}In my humble opinion, just the two custom controls need some explanation.

BookTree
The BookTree control writes a simple tree to the webpage using
    and
  • elements. The tree is the directory structure under the Photobooks directory. This last directory is a directory under the webpage. The structure is like this:

    [Photobooks]
    [HolidayName]
    [Photographer]
    Thumbnails
    [Photographer]
    Thumbnails
    [HolidayName]
    [Photographer]
    Thumbnails
    [Photographer]
    ThumbnailsThe photos of a particular photographer are placed in the [Photographer] directories. In the Thumbnails directory are thumbnails of the photos with the same name as the photo in the [Photographer] directory.

    In the webpage, the [Photographer] directories will be displayed as links. The HREF they point to is the same page (default.aspx in my case), but with two extra options: Holiday and by. There values are [HolidayName] and [Photographer].

    Photos
    The second control is called photos. This control just shows the images of the photos (JPGs) in a directory. If thumbnails are available in the Thumbnails they will be displayed instead of the photos themselves.

    If a user clicks on one of the thumbnails, the corresponding picture will be displayed in its original size, so the user can save it to his own hard disk.

    Using the controls
    The controls are in the same project as the webpage. The assembly still needs an extra registration in the webpage however. This to register the TagPrefix:

    <%@ Register TagPrefix="cc1" Namespace="Photobook" Assembly="Photobook" %>Putting the controls onto the webpage goes like this:


    If you want to have the controls in the Toolbox, you can just register it. Visual Studio will put an extra reference to the DLL under References. You should delete this extra reference.

Integrated Quiz WebApp with Graphical Score Report

Background
The quiz application demonstrated here allows users to proceed with multi-choice questions like in an IQ Quiz. The database is a simple XML file. The application is a single web user control. The data holder between the pages is the Session bag (Viewstate[ data ]).There are three panels within our quiz user control. They are Quiz panel, Review panel and Score Report panel. I have used my own progress bar control within the Score Report...

Database
Our database is a simple XML file:




Which of the fol....?





<




Using the code
Our quiz user control has four methods:

ShowQuestion(int _qNo)
Review()
ReAnswer()
ShowResult()
The code
First, there are some common member variables:

//create xmlDocument holder
XmlDocument doc=new XmlDocument();
//create empty navigator in order to navigate
//through our XMLDocument
XPathNavigator nav;
//to loop through
XPathNodeIterator nodeItrator;
//hold user Answers
ArrayList historyALst=new ArrayList();
//hold bookmarked Question(s)
ArrayList bookmarkLst=new ArrayList();
//used to replace index 1 by A and 2 by B ....etc
char[] perfix=new char[10] {'A','B','C','D','F','G','H','J','K','L'};
int currentQNo; //current question number
int totalQNumber; // total quiz question number
int totalMarkedQuestion; // total marked questions number
int currentMarkedQuestion; //current bookmarked question number
int markLoop; // the res number of reanswered bookmarked questions
DateTime startTime; // quiz start time
TimeSpan spentTime;
bool isReview; // to indicate the status of current qustion
bool wasChecked=false; //signed as marked Q within Review report.In the page_load(....), do the following:

private void Page_Load(object sender, System.EventArgs e)
{
//load our XML DB
doc.Load(Server.MapPath("quiz.xml"));
//create navigator for loaded xml File
nav=doc.CreateNavigator();

//Is New Quiz?.
if(!IsPostBack)
{
//Yes.
quizPanal.Visible=true;// show quiz screen.

//record start time
startTime=DateTime.Now;
currentQNo=1;
//count and record Total questions Number
//using our XmlDocumentnavigator by passing
//XPath sring of question node ( ...)
totalQNumber=nav.Select("//mc").Count;
//store our data in Session bag
//simply,I use the same name for Sessionbag object
//and member Field..
ViewState["startTime"]=startTime;
ViewState["totalQNumber"]=totalQNumber;
ViewState["currentQNo"]=currentQNo;
ViewState["score"]=0;
//go to first Question
ShowQuestion(currentQNo);
}
}Let's render question number as currentQNo : ShowQuestion(currentQNo);

Render a specific multi-choice question. This method takes question number as parameter, and uses this number within different XPath strings to navigate through our XML nodes:

///
/// Retrive Question and its Choices from
/// XML file and render it to screen
///

/// param name="_qNo">Question Numberv/param
public void ShowQuestion(int _qNo)
{
quizPanal.Visible=true;

//clear any selected radioList item
answersRBL.Items.Clear();
//retrieve Data from session bag and calculate spent time
startTime=(DateTime)ViewState["startTime"];
totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);
spentTime=DateTime.Now.Subtract(startTime);
//XPath String of current question node
//quiz/mc[current question number]
string xPath="quiz/mc["+_qNo.ToString()+"]";

int counter=1;
string str;
//read current Q Text by by using Select() method
//of our navigator by set the XPath string
//as address of current Question text Node:
//quiz/mc[current question number]/question
nodeItrator=nav.Select(xPath+"/question");
nodeItrator.MoveNext();
//display some data
qNoLbl.Text="Q: "+_qNo.ToString()+" / "+totalQNumber.ToString();
questionLbl.Text=_qNo.ToString()+": "+nodeItrator.Current.Value;
spentTimeLbl.Text=spentTime.Minutes.ToString()
+"~"+spentTime.Seconds.ToString();

//answer nodes Xpath string quiz/mc[current question number]/answer
nodeItrator=nav.Select(xPath+"/answer");

while(nodeItrator.MoveNext())
{
str=counter.ToString();
//add new radioBtn to Answers RadioList with perfix A, B..
//with text o the current text node
answersRBL.Items.Add(new ListItem(perfix[counter-1].ToString()
+":"+nodeItrator.Current.Value,str));

//keep correct answer in mind
if(nodeItrator.Current.GetAttribute("correct","")=="Yes")
{
ViewState["correctAnswer"]=counter;
}
counter++;//next
}There are some actions that take place when this method renders bookmarked questions:

//retrieve current status from session bag
isReview=Convert.ToBoolean(ViewState["isReview"]);
//Is Review Bookmarked questions Only?
if(isReview)
{//yes
//disable bookmark checkbox
bookmarkCKBX.Enabled=false;
//dispaly an image to notify user
Image1.Visible=true;
qNoLbl.ForeColor=Color.Red;
RequiredFieldValidator1.Text="Answer The Question !";
}
currentQNo++;//next
ViewState["currentQNo"]=currentQNo;
}//end methodAfter that, the user reviews answers history and is allowed to go back or view score report Review():

///
/// generate Review Report
/// by retrive user answers from historyALst ArrayList
/// and Bookmarked Question(s) from bookmarkLst ArrayList
/// and do user descion
///

public void Review()
{
revisionPanal.Visible=true;

int seqance=0;
string _is="No";
//retrieve marked Questions and answers List
bookmarkLst=(ArrayList)ViewState["bookmarkLst"];
historyALst=(ArrayList)ViewState["historyALst"];
totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);

wasChecked=Convert.ToBoolean(ViewState["wasChecked"]);
//are you marked some questions for review ?
if(!wasChecked){ /* No */ markBtn.Enabled=false;}

//create Answers History report
//
//table header
TableCell c=new TableCell();
TableCell cc=new TableCell();
TableCell ccc=new TableCell();

c.Text="Question No.";
cc.Text="Your Answer";
ccc.Text="Bookmark ?";

TableRow hr=new TableRow();
hr.Cells.Add(c);
hr.Cells.Add(cc);
hr.Cells.Add(ccc);

hr.ForeColor=Color.White;
hr.BackColor=Color.LightSlateGray;

Table1.Rows.Add(hr);

Table1.Font.Bold=true;
//your records
for(int i=1;i<=totalQNumber;i++)
{
//Cell: Q Number
TableCell c1=new TableCell();
c1.Text=i.ToString();
//Cell: your answer A,B, or C...
TableCell c2=new TableCell();
c2.HorizontalAlign=HorizontalAlign.Center;
c2.Text=perfix[Convert.ToInt32(historyALst[i-1])-1].ToString();
//Cell: bookmarked or not
TableCell c3=new TableCell();
for(int n=0;n < bookmarkLst.Count;n++)
{ //Is this Q bookmarked ?
if(Convert.ToInt32(bookmarkLst[n].ToString())==i)
{//Yes
_is=" Yes ";
}
}

c3.Text=_is;
c3.HorizontalAlign=HorizontalAlign.Center;//align=center
_is=" No ";//Re-Assign
TableRow r=new TableRow();
r.Cells.Add(c1);
r.Cells.Add(c2);
r.Cells.Add(c3);
r.ForeColor=Color.SlateGray;
//
//Just, Table template
if(seqance % 2 != 0)
{
r.BackColor=Color.Gainsboro;
}

//display it
Table1.Rows.Add(r);

eqance++;//next ..
}//end for
}//end methodIf the user decides to go back, then ReAnswer():


///
/// generate a list of bookmarked questions
/// and fire ShowQuestion() for first one
/// according to some rules
///

public void ReAnswer()
{
quizPanal.Visible=true;

isReview=true;
//retrieve data
bookmarkLst=(ArrayList)ViewState["bookmarkLst"];

totalMarkedQuestion=bookmarkLst.Count;
currentMarkedQuestion=Convert.ToInt32(bookmarkLst[0]);
//store data
markLoop=1;
ViewState["markLoop"]=markLoop;
ViewState["isReview"]=isReview;
ViewState["totalMarkedQuestion"]=totalMarkedQuestion;
ViewState["currentMarkedQuestion"]=currentMarkedQuestion;
//Show first marked question
ShowQuestion(currentMarkedQuestion);
}//end methodIn the end, call the Score report: ShowResult()

///
/// generate Score Report
/// by some simple calculations
///

public void ShowResult()
{
resultPanal.Visible=true;
//retrieve data
int score=Convert.ToInt32(ViewState["score"]);
totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);
startTime=(DateTime)ViewState["startTime"];
spentTime=DateTime.Now.Subtract(startTime);

//set own Progress Bar Max. Value
progressBar.Total=totalQNumber*100;
//set your score as progressed value
progressBar.Value=score*100;

//display some data:
//
//date
dateLbl.Text=DateTime.Now.ToUniversalTime().ToShortDateString();
//total Q number
totalQNoREsLbl.Text=totalQNumber.ToString();
//Total Score (as Total Question number * 100 )
totalScoreLbl.Text=(totalQNumber*100).ToString();
//Your Score (as your correct answers * 100)
scoreLbl.Text=(score*100).ToString();
//number of correct answers
correctAnswersLbl.Text=score.ToString();
//passing score
passingScoreLbl.Text=(totalQNumber*100/2).ToString();
//Time Spent
timeTakenLbl.Text=spentTime.Hours.ToString()
+":"
+spentTime.Minutes.ToString()
+":"
+spentTime.Seconds.ToString()
+"Hr(s).";


//Success or ...!
if((score*100/totalQNumber)<50)
{
gradeLbl.ForeColor=Color.Red;
gradeLbl.Text="Failed";
}
else
{
gradeLbl.ForeColor=Color.Green;
gradeLbl.Text="Success";
}
}//end methodDone ..........!

Chat Application for your website using asp.net

Introduction
And why not, how to create an easy chat room for your web site? Well, the best way is to use a nice database to store messages; however, for demo purposes, I'll use a static array. I know, you won't be able to use it in your web farm. Take this article as the concept, not as a solution. This simple web chat program is intended to work in any browser supporting iFrame.

Also, you can select multiple chat rooms. Why not extend from there and more from channel to channel.

Background
Some months ago, I was looking for a complete on-line customer service ASP.NET control to make my life easier, did not find anything interesting, so I built my own.

Using the code
Replace this class if you are using a database to save the messages:

Collapse | Copy Code
public class Chat
{
static protected ArrayList pArray = new ArrayList();


static public void AddMessage(string sDealer,
string sUser, string sMsg)
{
string sAddText = sDealer + "~" + sUser + "~" + sMsg;
pArray.Add(sAddText);

if ( pArray.Count > 200 )
{
pArray.RemoveRange(0,10);
}
}

static public string GetAllMessages(string sDealer)
{
string sResponse = "";

for (int i=0; i< pArray.Count; i++)
{
sResponse = sResponse +
FormatChat(pArray[i].ToString(), sDealer);
}

return(sResponse);
}

static private string FormatChat(string sLine, string sDealer)
{
int iFirst = sLine.IndexOf("~");
int iLast = sLine.LastIndexOf("~");

string sDeal = sLine.Substring(0, iFirst);
if ( sDeal != sDealer)
return("");

string sUser = sLine.Substring(iFirst+1, iLast-(iFirst+1));

string sMsg = sLine.Substring(iLast+1);

string sRet = "" + sUser + ": " + sMsg + "";

return(sRet);
}
}The above code reads and writes from the static array like in a database. The code only allows having 200 messages in the array, after that it deletes the top 10 at the time.

The Chat page is pretty simple; this is the code behind aspx.cs:

Collapse | Copy Code
public class ChatWin : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TB_ToSend;
protected System.Web.UI.WebControls.Button BT_Send;

private void Page_Load(object sender, System.EventArgs e)
{
if ( Page.IsPostBack == false )
{
if ( Request.Params["Channel"] != null )
Session["ChatChannel"] =
Request.Params["Channel"].ToString();
else
Session["ChatChannel"] = "1";

}
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
this.BT_Send.Click +=
new System.EventHandler(this.BT_Send_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

public string GetChatPage()
{
return("TheChatScreenWin.aspx");
}

private void BT_Send_Click(object sender, System.EventArgs e)
{
string sChannel = "";
string sUser = "";

if ( Request.Params["Channel"] != null )
sChannel = Request.Params["Channel"].ToString();
else
sChannel = "1";

if ( Request.Params["User"] != null )
sUser = Request.Params["User"].ToString();
else
{
Random pRan = new Random();
int iNum = pRan.Next(9);
sUser = "Annonymouse" + iNum;
}


if ( TB_ToSend.Text.Length > 0)
{
PageModule.Chat.AddMessage(sChannel,
sUser,
TB_ToSend.Text);

TB_ToSend.Text = "";
}
}
}When the SEND button is clicked, it calls the function AddMessage that adds a row into the end of the static array.

The page inside the iframe tag refreshes every 4 seconds without refreshing your actual page.

Introduction to Building FireFox Add-ons/Extensions

Introduction
FireFox Add-ons is a very popular feature to the browser, it allows a user to add more to the browser or even modify the behavior, often in the form of extra toolbars, context menus, themes or UI to customize the browser.

Extension is an installable file having an .XPI extension. Many of us are aware and use many of the well know extensions. To name a few, we have Web Developer, FoxyTunes, Firebug, and Screengrab.

So let’s start with the basics of extension development.

What Should We Know for the Development?
•XUL (XML User-interface Language)
•HTML
•JavaScript
•Basic XML
•CSS
Introduction to XUL
XUL (pronounced ‘zool’) is a XML based cross-platform language for describing user interfaces of FireFox extensions. It was developed to make the Mozilla browser development faster and easier.
It is an XML language so all features available to XML are also available to XUL. With XUL, an interface can be implemented and modified quickly and easily. XUL has all the advantages of other XML languages. For example, XHTML or other XML languages such as MathML or SVG can be inserted within it. Also, text displayed with XUL is easily localizable, which means that it can be translated into other languages with little effort.

What Can You Develop using XUL?
•Input controls such as textboxes and checkboxes
•Toolbars with buttons or other content
•Menus on a menu bar or pop up menus
•Tabbed dialogs
•Trees for hierarchical or tabular information
•Keyboard shortcuts
How XUL is Handled in the Browser (Mozilla / FireFox)?
In Mozilla, XUL is handled much in the same way that HTML or other types of content are handled. When you type the URL of an HTML page into the browser's address field, the browser locates the web site and downloads the content.

The rendering engine takes the content in the form of HTML source and transforms it into a document tree.
The tree is then converted into a set of objects that can be displayed on the screen. CSS, images and other technologies are used to control the presentation.
XUL functions in much the same way. The same CSS properties may be used to style both HTML and XUL, and many of the features can be shared between both. You can load both from either your local file system, from a web page or from an extension.

Given below is a simple example of an XUL file of a ‘Hello World’ status bar extension/add-on. Have a look:

Collapse | Copy Code


xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<-- Adds a new panel onto the statusbar -->


label="Hello World"
tooltiptext="Statusbar tip"/>


XUL files can be referenced with a regular HTTP URL (or any type of URL) just like HTML files. However, packages that are installed into Mozilla's chrome system can be referenced with special chrome URLs.
The basic syntax of a chrome URL is:

Collapse | Copy Code
chrome://// The FireFox browser window URL is chrome://browser/content/browser.xul. Try typing this URL into the location bar in FireFox!
The text is the package name, such as browser or editor. The is either 'content', 'skin' or 'locale' depending on which part you want. 'file.xul' is simply the filename.

For understanding more on XUL and its elements UI design; I suggest a very nice tutorial which can be found here. You can write your code using any HTML editors, even Notepad still providing you with a simple online editor for XUL click here.

Extension/Package Organization
Each extension is a mixture of many XUL files, JavaScript files, components, CSS files. You can find your installed extension files following the path “C:\Documents and Settings\user\Application Data\Mozilla\Firefox\Profiles\5byzdqqy.default\extensions”. You will see the list of all the extensions installed in your FireFox browser. Open the files. The JAR files can be easily opened by first changing the .jar file extension to .zip and unzipping using the normal zip utilities.

The general structure for the extension package is:

Extension name --> chrome --> content
locale
skin
defaults -->preferences-->preference.js
chrome.manifest
install.rdf


The files for a package are usually combined into a single JAR file or ZIP file. A JAR file may created and examined using a ZIP utility. There are usually three different parts to a package, although they are all optional. Each part is stored in a different directory. These three sets are the content, the skin and the locale, described below. A particular package might provide one or more skins and locales, but a user can replace them with their own. In addition, the package might include several different applications each accessible via different chrome URLs. The packaging system is flexible enough so that you can include whatever parts you need, and allow other parts, such as the text for different languages, to be downloaded separately.

Content
It contains the XUL and JS files. Many XUL files have a script file associated with them, and some may have more than one.

Locales
Contains each language folders having files that specify text used by the package but for a specific language. The locale structure is similar to the others, so we leave and move further.

Default Files
Default files that you use to seed a user's profile or preferences with should be placed in defaults/ under the root of your extension's folder hierarchy. Default preferences .js files should be stored in defaults/preferences/ - when you place them here, they will be automatically loaded by Firefox's preferences system when it starts so that you can access them using the Preferences API.

Manifest Files
A chrome.manifest file describes a package and maps its location on disk to a chrome URL. The manifest files in the chrome directory will be examined when a Mozilla application starts up to see what packages are installed.

A brief example of manifest file is given below:

Collapse | Copy Code
content helloworld jar:chrome/ helloworld.jar!/content/
overlay chrome://browser/content/browser.xul chrome://helloworld/content/overlay.xul
style chrome://global/content/customizeToolbar.xul chrome:// helloworld/skin/style.css
(used when toolbars and toolbarbuttons are applied)Install.rdf
An Install Manifest is the file an Add-on Manager-enabled XUL application uses to determine information about an add-on as it is being installed. It contains metadata identifying the add-on, providing information about who created it, where more information can be found about it, which versions of what applications it is compatible with, how it should be updated, and so on. The format of the Install Manifest is RDF/XML.

Collapse | Copy Code

xmlns:em="http://www.mozilla.org/2004/em-rdf#">

sample@indianic.net
1.0
2




{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
2.0
3.0.*




Sample Application
Sample for the code project
Hirva
www.indianic.com

A brief description of all the tags can be found here.

Read Gmail inbox using .net

Introduction

This is a protocol (a set of commands) used by an email client to connect to and retrieve email(s) from the mailbox on the remote server. We will develop the code that connects to the POP3 server and sends commands to retrieve the list of emails on the server, and then later, using an ASP.NET page, display the list to the user. To demonstrate the code, we will be connecting to Gmail's POP3 server using SSL (Secure Sockets Layer). To connect to your own POP3 mail server, you can either use the secure connection (SSL) if your mail server supports it or connect in unsecure mode. The code is simple to understand and by looking at it you will learn a lot about how network programming is done in the .NET environment.

Basic POP3 Commands

Following is a list of commonly used POP3 commands:

USER - Takes one argument i.e., the email address of the user trying to connect to his/her mailbox. Example usage:

USER youremail@xyz.com
PASS - Takes one argument i.e., the password of the user. Example usage:

PASS yourpassword
STAT - Returns the number of emails in the mailbox and the number of bytes all the emails are taking on the server. Example usage:

STAT
TOP - Takes two arguments i.e., the sort number of the email on the server and the number of lines of text to retrieve from the body of the email. Example usage:

TOP 1 10
RETR - Takes one argument i.e., the sort number of the email on the server and returns all the headers and lines from the body of the email. Example usage:

RETR 1
DELE - Takes one argument i.e., the sort number of the email on the server and deletes it. Example usage:

DELE 1
RSET - Resets any DELE commands given above. The emails marked to be deleted by DELE command are unmarked. Example usage:

RSET
QUIT - Closes the user session with the server. Example usage:

QUIT




Steps
Create a new WebPage in VS 2005.
Step 1
Create a Class file named as Pop3.cs.
Paste this code into Pop3.cs:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Web; using System.Xml;
namespace Prabhu
{
public class Pop3Client : IDisposable
{
public string Host { get; protected set; }
public int Port { get; protected set; }
public string Email { get; protected set; }
public string Password { get; protected set; }
public bool IsSecure { get; protected set; }
public TcpClient Client { get; protected set; }
public Stream ClientStream { get; protected set; }
public StreamWriter Writer { get; protected set; }
public StreamReader Reader { get; protected set; }
private bool disposed = false;
public Pop3Client(string host, int port, string email,
string password): this(host, port, email, password, false){}
public Pop3Client(string host, int port, string email,
string password, bool secure)
{
Host = host;
Port = port;
Email = email;
Password = password;
IsSecure = secure;
}
public void Connect()
{
if (Client == null)
Client = new TcpClient();
if (!Client.Connected)
Client.Connect(Host, Port);
if (IsSecure)
{
SslStream secureStream =
new SslStream(Client.GetStream());
secureStream.AuthenticateAsClient(Host);
ClientStream = secureStream;
secureStream = null;
}
else
ClientStream = Client.GetStream();
Writer = new StreamWriter(ClientStream);
Reader = new StreamReader(ClientStream);
ReadLine();
Login();
}
public int GetEmailCount()
{
int count = 0;
string response = SendCommand("STAT");
if (IsResponseOk(response))
{
string[] arr = response.Substring(4).Split(' ');
count = Convert.ToInt32(arr[0]);
}
else
count = -1;
return count;
}
public Email FetchEmail(int emailId)
{
if (IsResponseOk(SendCommand("TOP " + emailId + " 0")))
return new Email(ReadLines());
else
return null;
}
public List FetchEmailList(int start, int count)
{
List emails = new List(count);
for (int i = start; i < (start + count); i++)
{
Email email = FetchEmail(i);
if (email != null)
emails.Add(email);
}
return emails;
}
public List FetchMessageParts(int emailId)
{
if (IsResponseOk(SendCommand("RETR " + emailId)))
return Util.ParseMessageParts(ReadLines());
return null;
}
public void Close()
{
if (Client != null)
{
if (Client.Connected)
Logout();
Client.Close();
Client = null;
}
if (ClientStream != null)
{
ClientStream.Close();
ClientStream = null;
}
if (Writer != null)
{
Writer.Close();
Writer = null;
}
if (Reader != null)
{
Reader.Close();
Reader = null;
}
disposed = true;
}
public void Dispose()
{
if (!disposed)
Close();
}
protected void Login()
{
if (!IsResponseOk(SendCommand("USER " + Email))
|| !IsResponseOk(SendCommand("PASS " + Password)))
throw new Exception("User/password not accepted");
}
protected void Logout()
{
SendCommand("RSET");
}
protected string SendCommand(string cmdtext)
{
Writer.WriteLine(cmdtext);
Writer.Flush();
return ReadLine();
}
protected string ReadLine()
{
return Reader.ReadLine() + "\r\n";
}
protected string ReadLines()
{
StringBuilder b = new StringBuilder();
while (true)
{
string temp = ReadLine();
if (temp == ".\r\n" || temp.IndexOf("-ERR") != -1)
break;
b.Append(temp);
}
return b.ToString();
}
protected static bool IsResponseOk(string response)
{
if (response.StartsWith("+OK"))
return true;
if (response.StartsWith("-ERR"))
return false;
throw new Exception("Cannot understand server response: " +
response);
}
}
public class Email
{
public NameValueCollection Headers { get; protected set; }
public string ContentType { get; protected set; }
public DateTime UtcDateTime { get; protected set; }
public string From { get; protected set; }
public string To { get; protected set; }
public string Subject { get; protected set; }
public Email(string emailText)
{
Headers = Util.ParseHeaders(emailText);
ContentType = Headers["Content-Type"];
From = Headers["From"];
To = Headers["To"];
Subject = Headers["Subject"];
if (Headers["Date"] != null)
try
{
UtcDateTime =Util.ConvertStrToUtcDateTime
(Headers["Date"]);
}
catch (FormatException)
{
UtcDateTime = DateTime.MinValue;
}
else
UtcDateTime = DateTime.MinValue;
}
}
public class MessagePart
{
public NameValueCollection Headers { get; protected set; }
public string ContentType { get; protected set; }
public string MessageText { get; protected set; }
public MessagePart(NameValueCollection headers, string messageText)
{
Headers = headers;
ContentType = Headers["Content-Type"];
MessageText = messageText;
}
}
public class Util
{
protected static Regex BoundaryRegex = new Regex("Content-Type:
multipart(?:/\\S+;)" + "\\s+[^\r\n]*boundary=\"?
(?" + "[^\"\r\n]+)\"?\r\n",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
protected static Regex UtcDateTimeRegex = new Regex(@"^(?:\w+,\s+)?
(?\d+)\s+(?\w+)\s+(?\d+)\s+
(?\d{1,2})" + @":(?\d{1,2}):
(?\d{1,2})\s+(?\-|\+)
(?" + @"\d{2,2})(?
\d{2,2})(?:.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static NameValueCollection ParseHeaders(string headerText)
{
NameValueCollection headers = new NameValueCollection();
StringReader reader = new StringReader(headerText);
string line;
string headerName = null, headerValue;
int colonIndx;
while ((line = reader.ReadLine()) != null)
{
if (line == "")
break;
if (Char.IsLetterOrDigit(line[0]) &&
(colonIndx = line.IndexOf(':')) != -1)
{
headerName = line.Substring(0, colonIndx);
headerValue = line.Substring
(colonIndx + 1).Trim();
headers.Add(headerName, headerValue);
}
else if (headerName != null)
headers[headerName] += " " + line.Trim();
else
throw new FormatException
("Could not parse headers");
}
return headers;
}
public static List ParseMessageParts(string emailText)
{
List messageParts = new List();
int newLinesIndx = emailText.IndexOf("\r\n\r\n");
Match m = BoundaryRegex.Match(emailText);
if (m.Index < emailText.IndexOf("\r\n\r\n") && m.Success)
{
string boundary = m.Groups["boundary"].Value;
string startingBoundary = "\r\n--" + boundary;
int startingBoundaryIndx = -1;
while (true)
{
if (startingBoundaryIndx == -1)
startingBoundaryIndx =
emailText.IndexOf(startingBoundary);
if (startingBoundaryIndx != -1)
{
int nextBoundaryIndx =
emailText.IndexOf
(startingBoundary,
startingBoundaryIndx +
startingBoundary.Length);
if (nextBoundaryIndx != -1 &&
nextBoundaryIndx !=
startingBoundaryIndx)
{
string multipartMsg =
emailText.Substring
(startingBoundaryIndx +
startingBoundary.Length,
(nextBoundaryIndx -
startingBoundaryIndx -
startingBoundary.Length));
int headersIndx =
multipartMsg.IndexOf
("\r\n\r\n");
if (headersIndx == -1)
throw new
FormatException
("Incompatible

multipart message format");
string bodyText =
multipartMsg.Substring
(headersIndx).Trim();
NameValueCollection
headers =
Util.ParseHeaders
(multipartMsg.Trim());
messageParts.Add
(new MessagePart
(headers, bodyText));
}
else
break;
startingBoundaryIndx =
nextBoundaryIndx;
}
else
break;
}
if (newLinesIndx != -1)
{
string emailBodyText =
emailText.Substring(newLinesIndx + 1);
}
}
else
{
int headersIndx = emailText.IndexOf("\r\n\r\n");
if (headersIndx == -1)
throw new FormatException("Incompatible multipart
message format");
string bodyText = emailText.Substring
(headersIndx).Trim();
NameValueCollection headers =
Util.ParseHeaders(emailText);
messageParts.Add(new MessagePart(headers, bodyText));
}
return messageParts;
}
public static DateTime ConvertStrToUtcDateTime(string str)
{
Match m = UtcDateTimeRegex.Match(str);
int day, month, year, hour, min, sec;
if (m.Success)
{
day = Convert.ToInt32(m.Groups["day"].Value);
year = Convert.ToInt32(m.Groups["year"].Value);
hour = Convert.ToInt32(m.Groups["hour"].Value);
min = Convert.ToInt32(m.Groups["minute"].Value);
sec = Convert.ToInt32(m.Groups["second"].Value);
switch (m.Groups["month"].Value)
{
case "Jan":
month = 1;
break;
case "Feb":
month = 2;
break;
case "Mar":
month = 3;
break;
case "Apr":
month = 4;
break;
case "May":
month = 5;
break;
case "Jun":
month = 6;
break;
case "Jul":
month = 7;
break;
case "Aug":
month = 8;
break;
case "Sep":
month = 9;
break;
case "Oct":
month = 10;
break;
case "Nov":
month = 11;
break;
case "Dec":
month = 12;
break;
default:
throw new FormatException
("Unknown month.");
}
string offsetSign = m.Groups["offsetsign"].Value;
int offsetHours = Convert.ToInt32(m.Groups
["offsethours"].Value);
int offsetMinutes = Convert.ToInt32(m.Groups
["offsetminutes"].Value);
DateTime dt = new DateTime(year, month, day,
hour, min, sec);
if (offsetSign == "+")
{
dt.AddHours(offsetHours);
dt.AddMinutes(offsetMinutes);
}
else if (offsetSign == "-")
{
dt.AddHours(-offsetHours);
dt.AddMinutes(-offsetMinutes);
}
return dt;
}
throw new FormatException
("Incompatible date/time string format");
}
}
}


Step 2
Add a WebPage named as Home.aspx.
Paste this Designing Page into Home.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Home.aspx.cs" Inherits="Home" %>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


Untitled Page






















Welcome To Gmail









ControlToValidate="txt_email" ErrorMessage="Invalid Mail Format"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">







ControlToValidate="txt_password" ErrorMessage="*">

onclick="Button1_Click" style="text-align: center" Text="Login" Width="72px" />






Paste this code into Home.aspx.cs:
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class Home : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["email"] = txt_email.Text;
Session["pwd"] = txt_password.Text;
Response.Redirect("Pop3Client.aspx");
}
}
Step 3
Add a WebPage named as Pop3Client.aspx.
Paste this Designing Page into Pop3Client.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Pop3Client.aspx.cs"
Inherits="Pop3Client" %>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">









ColumnSpan="4">Listing emails
-
of
for





#


From


Subject


Date & Time




BorderWidth="0" runat="server">

















Paste this coding into Pop3Client.aspx.cs:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using Prabhu;
public partial class Pop3Client : System.Web.UI.Page
{
public const string Host = "pop.gmail.com";
public const int Port = 995;
public string Email ;
public string Password ;
public const int NoOfEmailsPerPage = 5;
public const string SelfLink =
"{1}";
public const string DisplayEmailLink =
"{1}";
protected void Page_Load(object sender, EventArgs e)
{
int page = 1;
if (Request.QueryString["page"] == null)
{
Response.Redirect("Pop3Client.aspx?page=1");
Response.Flush();
Response.End();
}
else
page = Convert.ToInt32(Request.QueryString["page"]);
try
{
Email = Session["email"].ToString();
Password = Session["pwd"].ToString();
}
catch (Exception ex) { Response.Redirect("Home.aspx"); }
int totalEmails;
List emails;
string emailAddress;
using (Prabhu.Pop3Client client = new Prabhu.Pop3Client
(Host, Port, Email, Password, true))
{
emailAddress = client.Email;
client.Connect();
totalEmails = client.GetEmailCount();
emails = client.FetchEmailList(((page - 1) *
NoOfEmailsPerPage) + 1, NoOfEmailsPerPage);
}
int totalPages;
int mod = totalEmails % NoOfEmailsPerPage;
if (mod == 0)
totalPages = totalEmails / NoOfEmailsPerPage;
else
totalPages = ((totalEmails - mod) / NoOfEmailsPerPage) + 1;
for (int i = 0; i < emails.Count; i++)
{
Email email = emails[i];
int emailId = ((page - 1) * NoOfEmailsPerPage) + i + 1;
TableCell noCell = new TableCell();
noCell.CssClass = "emails-table-cell";
noCell.Text = Convert.ToString(emailId);
TableCell fromCell = new TableCell();
fromCell.CssClass = "emails-table-cell";
fromCell.Text = email.From;
TableCell subjectCell = new TableCell();
subjectCell.CssClass = "emails-table-cell";
subjectCell.Style["width"] = "300px";
subjectCell.Text = String.Format(DisplayEmailLink,
emailId, email.Subject);
TableCell dateCell = new TableCell();
dateCell.CssClass = "emails-table-cell";
if (email.UtcDateTime != DateTime.MinValue)
dateCell.Text = email.UtcDateTime.ToString();
TableRow emailRow = new TableRow();
emailRow.Cells.Add(noCell);
emailRow.Cells.Add(fromCell);
emailRow.Cells.Add(subjectCell);
emailRow.Cells.Add(dateCell);
EmailsTable.Rows.AddAt(2 + i, emailRow);
}
if (totalPages > 1)
{
if (page >
Step 4

Add a WebPage named as DisplayPop3Email.aspx.
Paste this Designing Page into DisplayPop3Email.aspx:

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="DisplayPop3Email.aspx.cs" Inherits="DisplayPop3Email" %>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
































Email #
Date & Time
From
Subject
Attachments







Paste this code into DisplayPop3Email.aspx.cs:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using Prabhu;
using System.Text.RegularExpressions;
using System.Text;

public partial class DisplayPop3Email : System.Web.UI.Page
{
public const string Host = "pop.gmail.com";

public const int Port = 995;

public string Email ;

public string Password;

protected static Regex CharsetRegex = new Regex("charset=\"?
(?[^\\s\"]+)\"?", RegexOptions.IgnoreCase |
RegexOptions.Compiled);

protected static Regex QuotedPrintableRegex =
new Regex("=(?[0-9a-fA-F]{2,2})",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

protected static Regex UrlRegex = new Regex("(?https?://[^\\s\"]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

protected static Regex FilenameRegex =
new Regex("filename=\"?(?[^\\s\"]+)\"?",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

protected static Regex NameRegex =
new Regex("name=\"?(?[^\\s\"]+)\"?",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

protected void Page_Load(object sender, EventArgs e)
{
int emailId = -1;

if (Request.QueryString["emailId"] == null)
{
Response.Redirect("Pop3Client.aspx");
Response.Flush();
Response.End();
}
else
Email = Session["email"].ToString();
Password = Session["pwd"].ToString();
emailId = Convert.ToInt32(Request.QueryString["emailId"]);
Email email = null;
List msgParts = null;
using (Prabhu.Pop3Client client =
new Prabhu.Pop3Client (Host, Port,Email, Password, true))
{
client.Connect();
email = client.FetchEmail(emailId);
msgParts = client.FetchMessageParts(emailId);
}

if (email == null || msgParts == null)
{
Response.Redirect("Pop3Client.aspx");
Response.Flush();
Response.End();
}
MessagePart preferredMsgPart = FindMessagePart(msgParts,
"text/html");

if (preferredMsgPart == null)
preferredMsgPart = FindMessagePart(msgParts,
"text/plain");

else if (preferredMsgPart == null && msgParts.Count > 0)
preferredMsgPart = msgParts[0];
string contentType, charset, contentTransferEncoding, body = null;
if (preferredMsgPart != null)
{
contentType = preferredMsgPart.Headers["Content-Type"];
charset = "us-ascii";
contentTransferEncoding =preferredMsgPart.Headers
["Content-Transfer-Encoding"];
Match m = CharsetRegex.Match(contentType);
if (m.Success)
charset = m.Groups["charset"].Value;
HeadersLiteral.Text = contentType != null
? "Content-Type: " +contentType +
"
" : string.Empty;
HeadersLiteral.Text += contentTransferEncoding !=
null ?"Content-Transfer-Encoding: " +
contentTransferEncoding : string.Empty;
if (contentTransferEncoding != null)
{
if (contentTransferEncoding.ToLower()== "base64")
body = DecodeBase64String(charset,
preferredMsgPart.MessageText);
else
if (contentTransferEncoding.ToLower() ==
"quoted-printable")
body = DecodeQuotedPrintableString
(preferredMsgPart.MessageText);
else
body = preferredMsgPart.MessageText;
}
else
body = preferredMsgPart.MessageText;
}
EmailIdLiteral.Text = Convert.ToString(emailId);
DateLiteral.Text = email.UtcDateTime.ToString(); ;
FromLiteral.Text = email.From;
SubjectLiteral.Text = email.Subject;
BodyLiteral.Text = preferredMsgPart != null ?
(preferredMsgPart.Headers["Content-Type"].IndexOf("text/plain")
!= -1 ?"
" + FormatUrls(body) + "
" : body) : null;
ListAttachments(msgParts);
}
protected Decoder GetDecoder(string charset)
{
Decoder decoder;
switch (charset.ToLower())
{
case "utf-7":
decoder = Encoding.UTF7.GetDecoder();
break;
case "utf-8":
decoder = Encoding.UTF8.GetDecoder();
break;
case "us-ascii":
decoder = Encoding.ASCII.GetDecoder();
break;
case "iso-8859-1":
decoder = Encoding.ASCII.GetDecoder();
break;
default:
decoder = Encoding.ASCII.GetDecoder();
break;
}
return decoder;
}
protected string DecodeBase64String(string charset, string encodedString)
{
Decoder decoder = GetDecoder(charset);
byte[] buffer = Convert.FromBase64String(encodedString);
char[] chararr = new char[decoder.GetCharCount(buffer,0, buffer.Length)];
decoder.GetChars(buffer, 0, buffer.Length, chararr, 0);
return new string(chararr);
}
protected string DecodeQuotedPrintableString(string encodedString)
{
StringBuilder b = new StringBuilder();
int startIndx = 0;
MatchCollection matches = QuotedPrintableRegex.Matches(encodedString);
for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
string hexchars = m.Groups["hexchars"].Value;
int charcode = Convert.ToInt32(hexchars, 16);
char c = (char)charcode;
if (m.Index > 0)
b.Append(encodedString.Substring(startIndx,
(m.Index - startIndx)));
b.Append(c);
startIndx = m.Index + 3;
}
if (startIndx < encodedString.Length)
b.Append(encodedString.Substring(startIndx));
return Regex.Replace(b.ToString(),
"=\r\n", "");
}
protected void ListAttachments(List msgParts)
{
bool attachmentsFound = false;
StringBuilder b = new StringBuilder();
b.Append("
    ");
    foreach (MessagePart p in msgParts)
    {
    string contentType = p.Headers["Content-Type"];
    string contentDisposition = p.Headers["Content-Disposition"];
    Match m;
    if (contentDisposition != null)
    {
    m = FilenameRegex.Match(contentDisposition);
    if (m.Success)
    {
    attachmentsFound = true;
    b.Append("
  1. ").Append(m.Groups
    ["filename"].Value).Append("
  2. ");
    }
    }
    else if (contentType != null)
    {
    m = NameRegex.Match(contentType);
    if (m.Success)
    {
    attachmentsFound = true;
    b.Append("
  3. ").Append(m.Groups
    ["filename"].Value).Append("
  4. ");
    }
    }
    }
    b.Append("
");
if (attachmentsFound)
AttachmentsLiteral.Text = b.ToString();
else
AttachementsRow.Visible = false;
}
protected MessagePart FindMessagePart(List msgParts,
string contentType)
{
foreach (MessagePart p in msgParts)
if (p.ContentType != null && p.ContentType.IndexOf(contentType) != -1)
return p;
return null;
}
protected string FormatUrls(string plainText)
{
string replacementLink = "${url}";
return UrlRegex.Replace(plainText, replacementLink);
}
}

Create PDF Using c#

Create PDF

Introduction
There are several ways to create PDFs. The hardest of them all is perhaps to create it on your own using C#. However, if you want to learn how to do so, you have to climb a steep learning curve. You can either read the 1300+ page specification document available free from Adobe's PDF Technology Center or use an open source library called iTextSharp. iTextSharp eases the learning curve a fair amount. But learning to use iTextSharp is itself non-trivial. The people behind iTextSharp have done a very nice job of putting together a set of tutorials. If you get through the tutorials, creating a PDF becomes somewhat easier. The tutorials, however, are based on .NET 1.x and cannot be used "out of the box" with .NET 2.0 without a fair amount of code rework.

This project contains the reworked .NET 2.0 code and a friendlier interface

•to get to the iTextSharp tutorials web site more directly
•to see the results of each chapter and example more easily (than on the iTextSharp web site)
•to access the Adobe reference resources a little more quickly
WARNING:
Creating simple PDFs becomes easy once you grasp iTextSharp. But ... creating useful, practical, nice looking PDFs is hard. And hard work. In some ways it makes HTML, CSS, ASP.NET, Javascript and C# look easy! If you've ever struggled with Postscript and SVG you will appreciate why PDFs are so darned hard to master. That is perhaps Adobe's secret of success!

Situation
To make a long story short, I needed a way to send tabular data (from DataGridViews and the like) to various friends. Some could deal with HTML, but not Excel. The reverse was true for some of the others. It turns out, the only format all of them can handle is PDF. So, I thought I could programmatically create PDFs from my DataGridViews, etc. Easier said than done!

Complication
It turned out there is no easy way to do this. Because I could not find a satisfactory solution to meet my needs, I decided to investigate the subject. The more I looked into it, the more intrigued I became. Then I stumbled upon iTextSharp. While it looked very promising, it was a challenge, and still is!!!. First because of the .NET version mismatch. Second, because the tutorials web site is out of sync with the downloaded version (as of Mar 14 or so). Third, it was just plain difficult to understand by reading alone.

Solution
Creating a PDF by reading a book is just as hard as creating a Windows application by reading a book. When it comes to things like understanding the quaint under-the-hood stuff of PDFs and such, people like me simply have to write code and try it ad nauseam until one has that epiphanic Aha! moment. So, I built this little application to test out much of the code in the iTextSharp Tutorials web site. Having gone through the tedious code cleanups, I am sharing it with people like you; it might get you up the learning curve a little faster.

DISCLAIMER
I undertook this project to also learn a few things about Visual Studio 2005, C#, XML, DataGridView, etc. Caveat Emptor: Nothing has been properly or adequately tested. More important, there is a good chance, you or someone else can do this better. So, if you do use this code and cannot produce what you expect, there is little I can do to help you. On the bright side, though, you have the source code and all the technical references in the world you will ever need from Adobe and the good people at iTextSharp.

This solution only contains examples for the first six chapters of the tutorial web site. I did not include anything from the remaining chapters in part because they do require you to do some more reading but mostly because I ran out of steam! A couple of examples in Chapter 6 will not work because I was unable to get the required files from SourceForge.net.

Using the application
Be sure to read the DISCLAIMER above before you do anything.

Tutorial Menu
The Tutorial menu contains a command corresponding to each Chapter and Example in the iTextSharp Tutorials web site.



Simply selecting a chapter and an example will cause the PDF to be generated and displayed in the browser (using the Adobe Acrobat Reader, which one assumes you have). For example, Selecting Tutorial > Chapter 5 > 1: My First Table will execute the code below. The URL just above each such method points to the pertinent page with detailed information in the iTextSharp Tutorial web site. (You can also get to it via the Help menu.)

public bool Chap0501(string sFilePDF)
{
bool bRet = false;

Debug.WriteLine("Chapter 5 example 1: My First Table");

// step 1: creation of a document-object
Document document = new Document();

try
{
// step 2:
// we create a writer that listens to the document
// and directs a PDF-stream to a file

PdfWriter writer = PdfWriter.GetInstance(document,
new FileStream(sFilePDF, FileMode.Create));

// step 3: we open the document
document.Open();

// step 4: we create a table and add it to the document
Table aTable = new Table(2, 2); // 2 rows, 2 columns
aTable.AddCell("0.0");
aTable.AddCell("0.1");
aTable.AddCell("1.0");
aTable.AddCell("1.1");
document.Add(aTable);

bRet = true;
}
catch (DocumentException de)
{
this.Message = de.Message;
}
catch (IOException ioe)
{
this.Message = ioe.Message;
}

// step 5: we close the document
document.Close();

if (bRet)
this.Message = sFilePDF + " has been created";

return bRet;
}
This method along with all the others for chapters 1 through 6 are in the module called VVX_iTextSharp_Tutorials.cs; they are accessed via a class called iTextSharp_Tutorials in the VVX namespace.

The only way to learn is to mess around with the code. If you do, KEEP IN MIND, it is a very good idea to always get past the document.Close(); before you terminate a Debug session.

Help Menu
The Help menu contains links to two important sources of information:

•iTextSharp Tutorial Home
•Adobe PDF Specifications (various versions)
Try them. You will see why they are very important, especially if you are determined to create your own PDFs.

Using the code
Be sure to read the DISCLAIMER above before you do anything.
Prerequisite
This solution was created using Visual Studio 2005 and before building the solution you need to use the VS2005 Project > Add Reference menu command to provide a Reference to iTextSharp.DLL version 4.x. If you don't have this, you can download just the DLL or the source [and build it yourself] using one of these links to SourceForge.net:

•Download iTextSharp DLL (~1 MB)
•Download iTextSharp Source (~3 MB)
Building the solution
If you have Visual Studio 2005 then you should be able to use the project source code "out of the box" - simply build and run. The code itself is not rocket science. It is reasonably documented. More important, you have access to a wealth of information on what the code does via valuable links in the Help menu. If you don't have Visual Studio 2005, you will have to ask a more experienced friend. (Don't ask me, as I don't have a clue! Don't ask Adobe either, as no one there may be able to help as they did not create iTextSharp.)

Code modules
Side benefits of the code for newbies (like myself): The project includes modules with reasonably documented and self-explantory code. With luck, they may help you learn how to use a few features of the sub-systems employed.
VVX_iTextSharp_Tutorials.cs
VVX.iTextSharp_Tutorials is a class that contains about 3300+ lines of code for about 40 examples from the tutorials web site and reworked a bit to make them compatible with the above version of iTextSharp.DLL. The rework included the following:


•Updating names of methods, such as changing addCell to AddCell


•Updating names of enum values, such as changing RIGHT to ALIGN_RIGHT


•Adding a Message property so that I could display the status [of a call to create one of the example PDFs] in the UI's status bar as shown in the pictures above


•Adding helper methods, such as DoGetImageFile(...) and DoLocateImageFile(...) to help locate and load sample image files used in some of the tutorial examples. (These image files are in the Images folder.) I tend to prefix names of methods I created with a "Do" for two reasons -- first to distinguish them from methods that I did not create and second because they tend to show up together in the Intellisense pop-up


•Making sure there are explicit references to methods, types, properties, and such in the System.Drawing namespace to eliminate ambiguous references. Note: I also specifically commented out using System.Drawing; and recommend you do the same, as there are some methods and properties that appear to have slightly different meanings in the iTextSharp namespace


•Modifying the code for some of the examples, mainly to use the methods mentioned above, because both Adobe's PDF Reader and iTextSharp sometimes complain with unhelpful messages if the code fails to "properly" load and create images from these files. In virtually all such cases, I have wrapped my code and the original code in #if ... #else ... #endif

VVX_About.cs
VVX.About is a simple class that provides a "cheap", zero maintenance, "Help | About" message box. If you don't know how to access information in an assembly, it can show you one way of extracting some information from it.

I use VS2005's Project > appname Properties... > Application > Assembly Information ... option to specify/update the relevant information [which is good practice anyway] and then handle the user's Help > About menu request like this:

private void ctlHelpAboutMNU_Click(object sender, EventArgs e)
{
VVX.About.Show();
}

It is "cheap" and "zero maintenance" because I don't need to create a form and do all the hard work to maintain/update it to get something like this:



This message box is displayed simply by invoking the static method VVX.MsgBox.Info(...) from within VVX.About.Show().

VVX_MsgBox.cs
VVX.MsgBox is a class to simplify access to MessageBoxes of different kinds. It helped me learn how to use message boxes more efficiently. For example, the MsgBox.Confirm(...) method allows me to do something like this:

if (VVX.MsgBox.Confirm("Save changes?"))
this.DoFileSave();
instead of this:

if(DialogResult.Yes == MessageBox.Show("Save changes?"
, "Confirm"
, MessageBoxButtons.YesNo
, MessageBoxIcon.Question))
{
this.DoFileSave();
}

VVX_FileDialog.cs
VVX.FileDialog is a class to access OpenFileDialog and SaveFileDialog a little more efficiently. For example, the FileDialog.GetFilenameToOpen(...) method allows me to do something like this:

string filename = VVX.FileDialog.GetFilenameToOpen(VVX.FileDialog.FileType.XML);
if (filename.Length > 0)
{
this.DoGridPopulate(this.ctlTableDGV);
}
and

string filename = VVX.FileDialog.GetFilenameToOpen(VVX.FileDialog.FileType.Image);
if (VVX.File.Exists(filename))
{
img = Image.GetInstance(filename);;
}
The methods simply takes care of setting up the filters, etc., before displaying the OpenFileDialog or SaveFileDialog to the user.

VVX_File.cs
VVX.File is a class to simplify access to a few File-related methods, such as Exists. Again, it is not rocket science, but I found it was hard to remember that you have to use the System.IO.FileInfo class to test for the existence of a file! I now can check a file with just this.

if(VVX.File.Exists(filename))
{
//... do something
}
iText

There are alternatives
If iTextSharp is too difficult you might consider using one of several commercial PDF solutions, some of them are quite inexpensive. However, I haven't had much success with them. (The only place I have found creating PDFs is a breeze is on my iMac; creating PDFs on it from any application is a no-brainer! And you get beautiful PDFs, too.)

Finally, a word of thanks to you

Windows Application with Embedded Database

To have a windows desktop application with an embedded database. You can use MS SQL Compact edition.

To add the database to your application follow the below steps:

1) Goto solution explorer.
2) Right click on your application.
3) Goto add new item.
4) Add Local Database.
5) Right Click on Your application.
6) Add new reference to System.data.SqlServerCe.
7) Goto Server Explorer.
8) The newly Created databse wil be there, now you can add your tables.
9) To add an auto incriment column in the database, set identity of that feild to true, indentity incriment to 1, identity seed to 1.
10) The connection string would be

string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\cce.sdf";
connectionString = "datasource=" + dbfile;
11) Now all set to done.

Few limitations of using compact editions are:

1) It doesnt support Joins.
2) It dosent support .HasRows.
3) The biggest disadvantage is, when you are running the application directly through the VS, you wont be able to check the data in the databse, because when you run the project the database file is created on the temparory location and data will not goto into the datafile that has been created within the project.