Friday, May 30, 2008

Webcontrol GridView with sorting

For everyone with the error:

The GridView "dgGridView" fired event Sorting which wasn't handled.

Here is the solution:

If you get the above error your allready set the AllowSorting="true" if not set it to your gridView.
Add to the grid an method for the event "sorting", when double click in the properties list it will create a new method for you which looks like this:


protected void gvProjectParts_Sorting(object sender, GridViewSortEventArgs e)
{
}


First we bind the data from SQL and put the datatable in the ViewState because we need this later.


protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataSet dataset = new DataSet();
SqlConnection conn = new SqlConnection("ConnectionString");
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("select * from tblTable", conn);
adapter.Fill(dataset);
DataTable table = dataset.Tables[0];
if (table.Rows.Count > 0)
{
gvProjectParts.DataSource = table;
ViewState["gvProjectParts_DataSource"] = table;
gvProjectParts.DataBind();
}
}
}


Then we adjust the sort method where we use the saved viewstate, this is because gvProjectParts.DataSource and send.DataSource are empty:

protected void gvProjectParts_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable m_DataTable = (DataTable)ViewState["gvProjectParts_DataSource"];
if (m_DataTable != null)
{
DataView m_DataView = new DataView(m_DataTable);
m_DataView.Sort = e.SortExpression + " " + getSortDirection();
(sender as GridView).DataSource = m_DataView;
(sender as GridView).DataBind();
}
}

The function getSortDirection is explained here where we use the ViewState again to store the direction. This is because e.SortDirection is allways ASC.


private string getSortDirection()
{
string m_SortDirection;
if (ViewState["gvProjectParts_sortDirection"] == null)
m_SortDirection = "DESC";
else
m_SortDirection = (string)ViewState["gvProjectParts_sortDirection"];
switch (m_SortDirection)
{
case "ASC":
m_SortDirection = "DESC";
break;
case "DESC":
m_SortDirection = "ASC";
break;
}
ViewState["gvProjectParts_sortDirection"] = m_SortDirection;
return m_SortDirection;
}


Try it out !

Big thanks to Ryan Olshan and his post

Think it can also be done without using ViewState, please tell me how :)

Cheers,
Sjoerd

Monday, May 26, 2008

Rounded Corner Generator

I was looking today for a easy way to fix rounded corners on my div. I didnt want to use paint.net for cutting my own corners.

Following website creates these corners for you including the CSS and DIV code:

http://www.roundedcornr.com/

The following options are available:

- Basic RoundedCornr
- RoundedCornr with Gradient
- RoundedCornr with Border
- Single RoundedCornr Image ( for buttons ect. )

The standard weight x height for the RoundedCornr with Border is 1024 x 600. If you want to extend this open the _tl.png image and extend this one to your size.

Goodluck.

Monday, May 19, 2008

iTextSharp table is deprecated use PdfPTable instead

I was looking today for the function TableFitsPage, because it wasn't working as i expected it would be. Google turned up with a few results, this was one of them:

http://sourceforge.net/mailarchive/message.php?msg_id=003b01c7e0b1%24ad8869a0%246801a8c0%40abraxas.local

This post says: "Use a PdfPTable instead of a Table. Table is not supported anymore"

I never heard of PdfPTable even in the tutorials the dont mention it. Think they should make it deprecated in the library so people will know it's not supported anymore. Anyways the example from my last article uses the Table class.

This is the same example but with PdfPTable:


protected void Page_Load(object sender, EventArgs e)
{
//Create document A4
Document document = new Document(PageSize.A4);
//Start the writer
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c:\\test.pdf", FileMode.Create));
//Open the document
document.Open();


#region Example2
//Start table with 2 columns
//Set the withs for the columns to 10% and 90%
PdfPTable table = new PdfPTable( new float[] { 10, 90 });
table.WidthPercentage = 100;

//Add first cell with colspan2
PdfPCell firstCell = new PdfPCell(new Phrase("Colspan Cell", FontFactory.GetFont(FontFactory.HELVETICA, 14, Color.BLACK)));
firstCell.Colspan = 2;
firstCell.VerticalAlignment = Element.ALIGN_TOP;
firstCell.BorderWidthBottom = 0.5f;
table.AddCell(firstCell);

//Add more cells
for (int i = 0; i < 10; i++)
{
PdfPCell moreCells = new PdfPCell(new Phrase("Cell " + i.ToString(), FontFactory.GetFont(FontFactory.HELVETICA_OBLIQUE, 12)));
moreCells.VerticalAlignment = Element.ALIGN_TOP;
moreCells.Colspan = 1;
moreCells.BorderWidth = 0.5f;
table.AddCell(moreCells);
}
//Add table to document
document.Add(table);
#endregion


//Close the document
document.Close();
}


Cell -> PdfPCell
Chunk -> Phrase
Table - > PdfPTable


Goodluck.

Sunday, May 18, 2008

Create PDF files in memory and mail them as an attachment

In my previous post i showed how to create an PDF file on-the-fly with iTextSharp.

Now we pick up the first HELLO WORLD example and dont write it to C:\text.pdf but to a MemoryStream. After that we mail it as an attachment.

As you will see it's no rocket science!



protected void Page_Load(object sender, EventArgs e)
{
//Create document A4
Document document = new Document(PageSize.A4);
//Start the writer and write to memory
MemoryStream myStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, myStream);
//Open document
document.Open();

#region Example1
//Set some document attributes
document.AddTitle("Hello world");
document.AddAuthor("Sjoerd Perfors");
document.AddSubject("This is my first PDF created on: " + DateTime.Now.ToShortDateString());
//Add an image
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance("c:\\caesar_coin.jpg");
document.Add(image);
//Add a normal text
document.Add(new Chunk("HELLO WORLD", FontFactory.GetFont(FontFactory.HELVETICA, 18, Color.RED)));
//Add text to a specific position
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 12);
cb.ShowTextAligned(Element.ALIGN_RIGHT, "Another text placed on 100,400", 100, 400, 0);
cb.EndText();
#endregion

//Close the document
document.Close();

//Copy the stream to another stream and close it.
MemoryStream pdfstream = new MemoryStream(myStream.ToArray());
myStream.Close();
//Use the stream to send email
string fromEmail = "someone@someplace.com";
string toEmail = "someone@thisplace.com";
string body = "BODY";
string titel = "Sending your personal on the fly created PDF!!";

try
{
//Create the mailmessage object.
MailMessage objEmail = new MailMessage(fromEmail, toEmail, titel, body);
//Add the stream as attachemnt.
objEmail.Attachments.Add(new Attachment(pdfstream, "yourpdf.pdf"));
//Create the smtpclient with a SMTPserver defined in your web.config.
SmtpClient emailClient = new SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
//Send the mail
emailClient.Send(objEmail);
//Close the stream
pdfstream.Close();
}
catch (Exception exc)
{
Console.WriteLine("Send failure: " + exc.ToString());
}
}


Goodluck!

How to create on-the-fly FREE PDF files in C# Asp.net with tables/images/page numbering and more!

Hi there, been a while since my last post..

Today i will show how to create "on the fly" PDF files. I used this for an web application where users have a "personal" PDF file in their mailbox.

There are many library's available for creating PDF files. This site will show a list of open source library's: csharp-source.net/open-source/pdf-libraries

Some of them i have tried:

Report.NET
SharpPDF
PDFsharp

but i think the easiest to use is iTextSharp.

The homepage of iTextSharp is: http://sourceforge.net/projects/itextsharp/ Here you can download the library, source code and examples.

Short description from the iTextSharp homepage:

"iText# (iTextSharp) is a port of the iText open source java library written entirely in C# for the .NET platform. iText# is a library that allows you to generate PDF files on the fly. It is implemented as an assembly."

The example project creates a large amount of PDF files to show what can be done with iTextSharp. You will have to comment a lot in order to get it working but after that it can come handy. This is because the examples project was build on an earlier version of iTextSharp.

Here are some tutorials for iTextSharp:

itextsharp.sourceforge.net/tutorial/index.html
www.aspfree.com/c/a/BrainDump/Working-with-iTextSharp/ ( found this while writing this article )

OK lets start Visual studio!

First we need to add a reference to the iTextSharp library:

references -> add reference -> browse -> select itextsharp.dll

Then we can include the following to our class:

using iTextSharp.text.pdf;
using iTextSharp.text;

and for file access:

using System.IO;

First we write the hello world with an image and some texts:


protected void Page_Load(object sender, EventArgs e)
{
//Create document A4
Document document = new Document(PageSize.A4);
//Start the writer
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c:\\test.pdf", FileMode.Create));
//Open the document
document.Open();
//Set some document attributes
document.AddTitle("Hello world");
document.AddAuthor("Sjoerd Perfors");
document.AddSubject("This is my first PDF created on: " + DateTime.Now.ToShortDateString());
//Add an image
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance("c:\\caesar_coin.jpg");
document.Add(image);
//Add a normal text
document.Add(new Chunk("HELLO WORLD", FontFactory.GetFont(FontFactory.HELVETICA, 18, Color.RED)));
//Add text to a specific position
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 12);
cb.ShowTextAligned(Element.ALIGN_RIGHT, "Another text placed on 100,400", 100, 400, 0);
cb.EndText();
//Close the document
document.Close();
}

See how easy it is?

Remember that the X and Y positions are calculated from the bottomleft and not from the topleft.

The following example shows how to create an table with 2 columns
TABLE IS DEPRECATED SEE MY NEW POST WITH A EXAMPLE USING PdfPTable


#region Example2
//Start table with 2 columns
iTextSharp.text.Table table = new iTextSharp.text.Table(2);
table.BorderWidth = 0;
table.Padding = 2;
//Set the withs for the columns to 10% and 90%
float[] headerwidths = { 10, 90 };
table.Widths = headerwidths;
table.Width = 100;

//Add first cell with colspan2
Cell firstCell = new Cell(new Chunk("Colspan Cell", FontFactory.GetFont(FontFactory.HELVETICA, 14, Color.BLACK)));
firstCell.Colspan = 2;
firstCell.VerticalAlignment = Element.ALIGN_TOP;
firstCell.BorderWidthBottom = 0.5f;
table.AddCell(firstCell);

//Add more cells
for (int i = 0; i < 10; i++)
{
Cell moreCells = new Cell(new Chunk("Cell "+ i.ToString() , FontFactory.GetFont(FontFactory.HELVETICA_OBLIQUE,12)));
moreCells.VerticalAlignment = Element.ALIGN_TOP;
moreCells.Colspan = 1;
moreCells.BorderWidth = 0.5f;
table.AddCell(moreCells);
}
//Add table to document
document.Add(table);
#endregion


To add some nice functions like page numbering or footers we have to create a new class which extends the class PdfPageEventHelper. This class has the following handy functions:


public virtual void OnChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title);
public virtual void OnChapterEnd(PdfWriter writer, Document document, float position);
public virtual void OnCloseDocument(PdfWriter writer, Document document);
public virtual void OnEndPage(PdfWriter writer, Document document);
public virtual void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, string text);
public virtual void OnOpenDocument(PdfWriter writer, Document document);
public virtual void OnParagraph(PdfWriter writer, Document document, float paragraphPosition);
public virtual void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition);
public virtual void OnSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title);
public virtual void OnSectionEnd(PdfWriter writer, Document document, float position);
public virtual void OnStartPage(PdfWriter writer, Document document);


To use the functions we create a new class and overides above functions with out own code to create a nice footer:


public class PDFPageEvents: PdfPageEventHelper
{
PdfPTable table;
PdfTemplate tpl;
BaseFont helv;

public override void OnOpenDocument(PdfWriter writer, Document document)
{
table = new PdfPTable(2);
// initialization of the template
tpl = writer.DirectContent.CreateTemplate(100, 100);
tpl.BoundingBox = new Rectangle(-20, -20, 100, 100);
// initialization of the font
helv = BaseFont.CreateFont("Helvetica", BaseFont.WINANSI, false);
}

public override void OnEndPage(PdfWriter writer, Document document)
{
if (document.PageNumber == 1)
return;
PdfContentByte cb = writer.DirectContent;
cb.SaveState();
// write the headertable
float[] floatwidth = { (document.Right - document.Left) };
table.TotalWidth = 100;
//table.SetTotalWidth(floatwidth);
table.WriteSelectedRows(0, -1, document.Left, document.PageSize.Height - 50, cb);
// compose the footer
String text = "Page " + writer.PageNumber + " of ";

float textSize = helv.GetWidthPoint(text, 12);
float textBase = document.Bottom - 20;
cb.BeginText();
cb.SetFontAndSize(helv, 12);

float adjust = helv.GetWidthPoint("0", 12);
cb.SetTextMatrix(document.Right - textSize - adjust, textBase);
cb.ShowText(text);
cb.EndText();

cb.AddTemplate(tpl, document.Right - adjust, textBase);

cb.SaveState();
}

public override void OnCloseDocument(PdfWriter writer, Document document)
{
tpl.BeginText();
tpl.SetFontAndSize(helv, 12);
tpl.SetTextMatrix(0, 0);
tpl.ShowText("" + (writer.PageNumber - 1));
tpl.EndText();
}
}


Now in our previous example we add the following:


//Create document A4
Document document = new Document(PageSize.A4);
//Start the writer
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c:\\test.pdf", FileMode.Create));
PDFPageEvents pageEvent = new PDFPageEvents();
writer.PageEvent = pageEvent;
//Open the document
document.Open();
document.Add(new Chunk("This is a new page WITHOUT page numbering."));
document.NewPage();
for (int i = 0; i < 5; i++)
{
document.Add(new Chunk("This is a new page WITH page numbering."));
document.NewPage();
}
//Close the document
document.Close();


In the next article i will descripe how to create an PDF in memory and mail this as an attachment.

Goodluck and big thanks for iTextSharp!