|
|
|
|
|
|
|
Author Rank :
|
|
|
Page Views :
|
93199
|
|
Downloads :
|
3165
|
|
Rating :
|
Rate it
|
|
Level :
|
Intermediate
|
|
|
|
|
Download
Files:
|
|
|
|
|
|
|
|
|
|
|
Edited by Nina Miller
Introduction
Well it is that time of the year again. Time to get in shape for the summer months, and what better way to do it then through a rigid exercise program. I was never very good at tracking my progress in the gym, but thanks to .NET (and my wife), I have a way to do just that. This program uses the DataGridView bound to a Microsoft Access Database to create a printed sheet with your latest work out plans. The workout chart includes the exercise, number of sets, number of reps, amount of weight, and most importantly, whether or not you completed the exercise. The best part of this program is that you can print out your exercise program and bring it with you to the weight room.
Figure 1 - Exercise Program
New Form Capture Feature
.NET comes with a new form capture feature: the ability to copy the form as you see it on the screen into a bitmap. Although not useful for controls that you need to scroll, New Form Capture Feature works if you can fit all the contents you need to see on the screen into a bitmap. In this application, we stretched the DataGridView to allow for the full contents of the exercises, and we enabled AutoScrolling on the Form. This way the DataGridView will be much larger than the form, and the screen capture will print the entire DataGridView contents to the printer. The exercise application gives you two options: turning on the form capture feature to print out the form bitmap, or printing using a customized DataGridView printing. The customized printing is the default mode of the exercise program and it's more powerful because you can print the data in the grid view beyond any scrolling limitations of the DataGridView. Below is the code for capturing the form in a bitmap and drawing it to a graphics surface:
Listing 1 - Printing the Form Capture to a Graphics Surface
|
private void DrawFormSurface(System.Drawing.Printing.PrintPageEventArgs e) {
// create a bitmap the size of the form Bitmap bmp = new Bitmap(gridExercise.Width, gridExercise.Height);
// draw the form image to the bitmap gridExercise.DrawToBitmap(bmp, new Rectangle(0, 0, gridExercise.Width, gridExercise.Height));
// draw the bitmap image of the form onto the graphics surface e.Graphics.DrawImage(bmp, new Point(0, 0)); } |
Using a Filename to Map an Image in the DataGridView
We want to place an image of the exercise into the DataGridView without inserting the image in the database. We prefer to place all the images in an images directory. Then we will read the images file names from the database, retrieve the images from the images directory, and put the images into the DataGridView. In order to accomplish all this, we'll need to create a custom grid view column and grid view cell that inherits from DataGridViewImageColumn/smaller>/color> /smaller>/color>and DataGridViewImageCell. /smaller>/color>We then override the GetFormattedValue/smaller> /smaller>method in the custom DataGridViewImageCell class. In the GetFormatted value method, we create a mapping between the file names and the actual images. Below is the code for accomplishing the filename to image mapping in a DataGridView:
Listing 2 - Mapping Images into the DataGridView from file name Strings
|
using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; using System.Reflection;
namespace ExerciseProgram {
/// <summary> /// Create a Custom DataGridViewImageColumn /// </summary>
public class StringImageColumn : DataGridViewImageColumn {
public StringImageColumn() { this.CellTemplate = new CustomImageCell(); this.ValueType = typeof(string); // value of this column is a string, but it shows images in the cells after formatting }
}
/// <summary> /// Create a Custom DataGridViewImageCell /// </summary>
public class CustomImageCell : DataGridViewImageCell {
// mapping between filename and image static System.Collections.Generic.Dictionary<string, Image> dotImages = new Dictionary<string, Image>(); // load up custom dot images
static public System.Collections.Generic.Dictionary<string, Image> Images { get { return dotImages; } }
public CustomImageCell() { this.ValueType = typeof(int); }
protected override object GetFormattedValue( object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) {
if (value.GetType() != typeof(string)) return null;
// get the image from the string and return it LoadImage(value);
// return the mapped image return dotImages[(string)value]; }
public static void LoadImage(object value) { // load the image from the images directory if it does not exist if (dotImages.ContainsKey((string)value) == false) { string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\images\\" + (string)value;
// read the image file Image theImage = Image.FromFile(path);
// assign the image mapping dotImages[(string)value] = theImage; } }
public override object DefaultNewRowValue { get { return 0; } }
}
} |
Updating the Grid
The DataGridView is bound to the Microsoft Access Database via a DataGridAdapter. We can edit the sets, reps, and weight values inside the grid while increasing body strength and the program will persist these values to the database. Sometimes it is useful to override the behavior of the DataGridView for updates and inserts in order to customize how the grid is updated. Below is the ADO.NET code that updates the grid in Microsoft Access without using the OleDb Adapter:
Listing 3 - Updating the Microsoft Access Database after editing the GridView
|
/// <summary>
/// Event Handler called when Cell is finished editing /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void gridExercise_CellEndEdit(object sender, DataGridViewCellEventArgs e) { UpdateCurrentRow(e); }
private void UpdateCurrentRow(DataGridViewCellEventArgs e) { int index = e.RowIndex; DataRow dr = scheduleDataSet.Tables[0].Rows[e.RowIndex]; string val = dr[gridExercise.Columns[e.ColumnIndex].DataPropertyName].ToString(); OleDbCommand updateCommand = new OleDbCommand();
// construct update command and update from the data set updateCommand.CommandText = "UPDATE `Schedule` SET `Completed` = {0}, `Reps` = {1}, `Weight` = {2}, `Sets` = {3} WHERE `ID` = {4}";
updateCommand.CommandText = String.Format(updateCommand.CommandText, dr["Completed"], dr["Reps"], dr["Weight"], dr["Sets"], dr["ID"]);
updateCommand.CommandType = System.Data.CommandType.Text; updateCommand.Connection = scheduleTableAdapter.Connection; updateCommand.Connection.ConnectionString = string.Format( @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}\Schedule.mdb", Path.GetDirectoryName(Application.ExecutablePath));
updateCommand.Connection.Open();
// execute the update on the database updateCommand.ExecuteNonQuery(); updateCommand.Connection.Close(); } |
Printing the DataGridView by Brute Force.
Once we are satisfied with our exercise parameters, it is time to print out the exercise schedule and head to the gym. Printing is accomplished using the PrintDocument in conjuction with GDI+. Every row and column is painstakingly drawn to the print graphics surface. Listing 4 shows the code that draws the exercise rows below the header. The method loops through each row in the DataSet and draws the text corresponding to the column in the data row. If the row contains a picture, rather than text, the image that is mapped to the text in the cell is printed instead. We also need to track the row and column position after placing each object onto the graphics surface so we know where the next object goes. We do this by incrementing the local variables: columnPosition and rowPosition.
Listing 4 - Printing out the Exercise Rows
|
private void DrawGridBody(Graphics g, ref int columnPosition, ref int rowPosition) { // loop through each row and draw the data to the graphics // surface.
foreach (DataRow dr in scheduleDataSet.Tables[0].Rows) { columnPosition = 0;
// draw a line to separate the rows
g.DrawLine(Pens.Black, new Point(0, rowPosition), new Point(this.Width, rowPosition));
// loop through each column in the row, and // draw the individual data item foreach (DataGridViewColumn dc in gridExercise.Columns) { // if its a picture, draw a bitmap if (dc.DataPropertyName == "Picture") { if (dr[dc.DataPropertyName].ToString().Length != 0) { if (CustomImageCell.Images.ContainsKey(dr[dc.DataPropertyName].ToString())) { g.DrawImage(CustomImageCell.Images[dr[dc.DataPropertyName].ToString()], new Point(columnPosition, rowPosition)); } } } else if (dc.ValueType == typeof(bool)) { // draw a check box in the column
g.DrawRectangle(Pens.Black, new Rectangle(columnPosition, rowPosition + 20, 10, 10)); } else { // just draw string in the column string text = dr[dc.DataPropertyName].ToString();
if (dc.DefaultCellStyle.Font != null) g.DrawString(text, dc.DefaultCellStyle.Font, Brushes.Black, (float)columnPosition, (float)rowPosition + 20f); else g.DrawString(text, this.Font, Brushes.Black, (float)columnPosition, (float)rowPosition + 20f); }
// go to the next column position columnPosition += dc.Width + 5;
}
// go to the next row position rowPosition = rowPosition + 65; }
} |
Conclusion
The DataGridView is even more full featured than the DataGrid and provides a good interface for manipulating DataSets. This article explained two ways to print data inside the DataGridView. Hopefully this exercise/fontfamily> will give you some insight into printing one of the more powerful controls inside the Windows Form in C# and .NET.
|
|
Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post
Here.
|
|
|
|
|
Login
to add your contents and source code to this article
|
|
|
|
|
|
|
|
|
|
|
|
Mike Gold
Michael Gold is President of Microgold Software Inc., makers of the WithClass UML Tool. His company is a Microsoft VBA Partner and Borland Partner. Mike is a Microsoft MVP and founding member of C# Corner. He has a BSEE and MEng EE from Cornell University and has consulted for Chase Manhattan Bank, JP Morgan, Merrill Lynch, and Charles Schwab. Currently he is a senior developer at Finisar Corp. He has been involved in several .NET book projects, and is currently working on a book for using .NET with embedded systems.
He can be reached at mike@c-sharpcorner.com
|
|
|
|
|
|
|
|
|
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional
consulting company, our consultants are well-known experts in .NET and many of them
are MVPs, authors, and trainers. We specialize in Microsoft .NET development and
utilize Agile Development and Extreme Programming practices to provide fast pace
quick turnaround results. Our software development model is a mix of Agile Development,
traditional SDLC, and Waterfall models.
|
|
Click here to learn more about C# Consulting. |
|
|
|
|
|
|
|
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon.
Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees.
As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
|
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
|
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
|
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
|
|
|
|
|
|
|
|
|
|
|
|
|