In this series, we will use controls from ComponentOne Studio for WinForms to create a Sales Management application and show how easily anyone can "Become an Expert". Keep in mind that up until now* we have created a table to display sales data, implemented features to add/delete data and added a feature to automatically show totals.
* See Part One and Part Two before continuing.
In Part 3, we'll use the C1Ribbon control (part of Studio for WinForms) to change the look and feel of the application. We'll also use the C1PdfDocument control to export a report to a PDF file, and we'll also add Excel export options using the C1FlexGrid control.
So let's get started!
Up until now we've used basic Windows controls in the Sales Management Application menu and form itself. To enhance the look and feel of the application, we'll incorporate the Ribbon interface using the C1Ribbon control.
In order to use the C1Ribbon control, we need to add it to the toolbox. To add the control, right click on the toolbox and open "Choose Toolbox Items".
Please refer to the previous articles for details regarding this topic.
Let's begin by adding the C1Ribbon control to the display area of the form. It looks very different from MenuStrip. C1Ribbon provides a tabbed interface using menu items which are divided into tabs and groups for better visual effect. In this application we will divide our items into two tabs: one for basic functionality and another for file exporting features.
We have a C1RibbonForm class which is used to get a form with C1Ribbon control on it. So let's shift from the common Form class to the C1RibbonForm class. Use the following code to modify the base Form class (parent class).
public partial class Form1 : Form
using C1.Win.C1Ribbon; // Add
public partial class Form1 : C1RibbonForm
The form has changed completely! We'll use this as a base and add buttons and textboxes to the C1Ribbon control to create the menu.
Now we will add tabs and groups to the Ribbon. To add tabs, select the Application Menu (round section) from the top left of the screen and click "Actions" and then "Add Tab".
For changing the text of the tab, select the tab to display its context-sensitive toolbar and click on "Text Settings". Text settings and tooltip settings can be done from this popup window.
You can also modify Text settings and add more groups in the same way. Similarly, controls can also be added to groups. Select the default Group and drop-down the actions menu. Select to add a Button.
Now, let's change the icons. To change the Button's icon, click on "Change Image" from its toolbar.
From the Change Image pop-up, select the icon to be changed. Modify "Large Image" for large icons and "Small Image" for small icons. Depending on whether or not you select a large image will determine if the button is large or small. Even if you want a large button, it's also recommended to choose a small image for use in the Quick Access Toolbar.
Try changing icons for all the controls in the same way. Continue to fill out the Ribbon with the following tabs and groups. Some controls are for features we have already implemented and some are for the new features we plan to implement. For PDF export we will have to add a separate C1PdfDocument component. Note: details about this feature will be covered later.
Now that we have modified the appearance, let's add new features. Usually in business applications, users want data to be exported to a file.
Let's first add a feature for exporting our data to Excel. First, add a RibbonButton event. This can be done by simply double clicking on the RibbonButton, just like a usual button control. We will use the "Output" button in the "Excel" group of the file tab created earlier.
To accomplish the Excel exporting we'll simply use C1FlexGrid's export feature. Use the following code to export C1FlexGrid data to an Excel file format.
this.c1FlexGrid1.SaveExcel("File Name", "Sheet Name", "Output Options");
Data from C1FlexGrid will be displayed in the specified sheet. We have fixed rows (header rows) and fixed columns (header columns) in the Sales Management Application. Specify FileFlags.IncludeFixedCells in the output option to get fixed cells in the Excel file.
If you open the exported Excel file, you'll notice the window outline is fixed for the sections with fixed cells. Also, our cell styles are respected in the Excel format, but our custom OwnerDraw progress bars are not.
In addition to Excel export, we can also export C1FlexGrid data to XML. Exporting to Excel limits reusability from the customer's end because it's restricted to the software being used. By exporting to XML we can load and export data in a format more native to the FlexGrid. We will export C1FlexGrid data to an XML file and then read data from this file.
We'll use the "Export" button in the XML group. Use the following code to export C1FlexGrid data to an XML file format.
Just write one line of code and that's it!
Let's read the data from the XML file back to the grid. Execute the following code to load the XML file and paste the data back to C1FlexGrid. Use the "Import" button of XML group in the Ribbon.
And just like file exporting, we only need one line of code here too. Background color has also been read back with the data! So when data is exported to XML, font, background color, and other similar information is also exported to the file.
Finally, since we are creating a Sales Management application, let's try adding a reporting feature. We will use C1PdfDocument component to create a PDF file. C1PdfDocument (part of Studio for WinForms) is used for generating PDF documents.
So let's start creating the PDF file! Add the C1PdfDocument component from the toolbox, just like you did for C1Ribbon. Then add the click event of the "PDF Output" button under the PDF group in the Home tab.
Now let's add some code.
this.c1PdfDocument1.DocumentInfo.Title = "Title";
This code initializes the C1PdfDocument component and sets the PDF file title. The title can be verified in the PDF file properties.
RectangleF rcPage = this.c1PdfDocument1.PageRectangle;
Here we get the page area and determine the display area of the page by setting the top, bottom, left, right margins.
Next we'll set the title (heading) style of the report.
// Get and set the height.
rc.Height = this.c1PdfDocument1.MeasureString("Title (Heading)", "Font", rc.Width).Height;
// Draw title.
this.c1PdfDocument1.DrawString("Title (Heading)", "Font", Brushes.Black, "Drawing area");
// Adjust the drawing location.
rc.Offset(0, rc.Height 5);
The code above set the height of the drawing area using the MeasureString method. We then draw the title using the DrawString method. Then, modify Brushes.Black to change the color of the text. And finally, adjust the drawing location by an amount equal to the height of the title plus the row padding.
The following code will draw the header section. The basic sequence will be the same as drawing the title; however, in this case it will be for multiple columns, so the horizontal width needs to be calculated. (In our application, we are simply dividing the width by the number of columns. Also, for setting the height of the drawing area, we are calculating based on the height of the tallest cell).
`// Measure cell width
rcCell.Width = rc.Width / fields.Length;
// Get the height. Select the highest one and set it.
float height = this.c1PdfDocument1.MeasureString("Header String", "Font", rcCell.Width).Height;
rcCell.Height = Math.Max(rcCell.Height, height);`
Next, fill the drawing area and draw the header string. Adjust the position of the drawing area and our drawing of the header is complete.
// Fill the cell.
// Draw header.
this.c1PdfDocument1.DrawString("Header String", "Font", Brushes.White, rcCell);
// Position is set by adjusting the horizontal width only.
Finally, we will draw the data section. Drawing the data section is similar to the header section. It contains numeric values, strings and date values. The numeric values will be left aligned and all other data types will be right aligned.
StringFormat sf = new StringFormat();
// Check if the value can be converted to double.
sf.Alignment = (double.TryParse("Data", out d)) ? StringAlignment.Far :StringAlignment.Near;
// Draw the data in the cell.
this.c1PdfDocument1.DrawString("Data", "Font", Brushes.Black, rcCell, sf);
We are also checking if the numeric data type or any other data type can be converted to double to avoid conversion errors. For numeric data, we set StringAlignment to Far, and for other data types set it to Near. Then draw the data string by specifying the string format at runtime while using the DrawString method. Finally, once the file is saved using the Save method of C1PdfDocument, our process is complete. Page breaks have also been implemented in this sample application.
The generated PDF file now contains sales data. This might be confidential information since this is a business application, so let's set a password for the PDF file. This password will be required to open and view the PDF file.
Check the checkbox "Include Password" in the PDF group of Home tab. The following code is implemented when you click on "PDF Output" after entering a string in the "Password" textbox.
this.c1PdfDocument1.Security.UserPassword = "Password String";
Here we just need to use the UserPassword property of the PdfSecurity class to set the password. The security of the PDF file is enhanced this way so the users who do not have the password will not be able to open the PDF file.
In this part we modified the look and feel of the application with the help of the C1Ribbon control. We implemented features like Excel export and XML export and import. We also created a PDF file and set a password for it using the C1PdfDocument component. By making a few code changes to the controls we were able to enhance the features in the application immensely.
In Part 4, we'll add some more interesting features to the application by binding sales data to a chart control and displaying the data in C1FlexGrid in the form of a chart.