Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

FieldList Control

0.00/5 (No votes)
25 Apr 2010 2  
A coding control for document coding or QCing applications.

FieldListControl.jpg

Introduction

I started to write a large program that will contain some good functions to be able to code fields for documents and retrieve them easily by searching fields and/or the OCRed body of documents. My first two steps of the application are about done. I would like to share one of the components that I wrote, called the "Field List" control.

This control runs of a file with an "lst" extension which carries a very simple structure in text format.

Update

Because of its complicated nature(!) I have only uploaded the control sample project instead of the project I am working on, which includes the control. With new sample code and the new video clip, it should be easy to understand this control and what it is designed for. (Watch its video clip here)

Points of Interest

I should probably step-up my coding level from C# Beginner to C# Beginner/Intermediate :) With this control, field entries are unlimited. With its "scrollbar", the user can go up and down.

Components

I will include one component here: the FieldList control.

The FieldList control has a vertical scrollbar and a container that has labels, textboxes, and/or drop-down boxes created during runtime. This is one of the useful things people might learn from this control: how to create controls in runtime and get information from them. The QnCMain form is the preview of the main coder form.

lstFile.jpg

The Code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace FieldList
{
    public partial class FieldList : UserControl
    {
        // Fields
        // private int intFieldCount; // Number of fields will be set
        private const int BoxHeight = 20; // Height of the Textbox

        public FieldList()
        {
            InitializeComponent();
        }

        // We get the path of the 'lst' file and the lines
        // will be skipped at the top of that file
        // There might be some user notes on the top
        // that program should skip at streamread
        public void LoadFields(string FieldFilePath)
        {
            // Check the path

            if (File.Exists(FieldFilePath) != true)
            {
                throw new Exception("'Field List' File Can not be found!");
            }

            string LineData; // Line datab from 'lst' file
            string LabelText; // Field label text
            string ControlBoxName; // Combobox and textbox names created with this
            string[] SplitText; // Splitter
            int ControlCount = 0; // This calculates the 'top' for the controls
            int ii = 0; // Loop to bypass top lines of the 'lst' file
            int SkipFirstLines;

            // panel1.Top = 0; // Set container's 'top' value
            panel1.Width = (this.Width - 10) - SCRBar.Width;
            // Set container's 'width' value

            // Open Stream to tread
            StreamReader CurrentFields = new StreamReader(FieldFilePath);

            // Find out how many lines wil be skipped
            SkipFirstLines = Convert.ToInt32(CurrentFields.ReadLine());
            // Set fields

            for (ii = 0; ii < SkipFirstLines; ii++) // First two lines are not fields
            {
                LineData = CurrentFields.ReadLine();
            }

            while (CurrentFields.EndOfStream != true)
            {
                LineData = CurrentFields.ReadLine();
                SplitText = LineData.Split('@');

                LabelText = SplitText.GetValue(0).ToString();
                ControlBoxName = LabelText.Replace(' ','_');
                // Replace spaces with
                // underscores for text and combo box names

                if (ControlCount > 0)
                {
                    ControlCount = ControlCount + (BoxHeight + 2);
                    // Encrement 'top' value
                }
                else
                {
                    ControlCount = 1; // This is set to one only once.
                                      // Code will not come here the second time
                }
                
                if (SplitText.Count() > 1)
                {
                    // Drop Down Control
                    ComboBox NewComboBox = new ComboBox();
                    NewComboBox.Width = ((panel1.Width / 3) * 2) - 5;
                    NewComboBox.Height = BoxHeight;
                    NewComboBox.Left = (panel1.Width / 3) + 5;
                    NewComboBox.Top = ControlCount;
                        for (ii = 0; ii < (SplitText.GetUpperBound(0)); ii++)
                        {
                            NewComboBox.Items.Add (SplitText.GetValue(ii+1));
                        }
                    NewComboBox.Name = "cmb" + ControlBoxName;
                    panel1.Controls.Add(NewComboBox);
                    NewComboBox.SelectedIndex = 0;
                }
                else
                {
                    // Text Control
                    TextBox NewTextBox = new TextBox();
                    // Space little less than 2/3
                    NewTextBox.Width = ((panel1.Width / 3) * 2) - 5;
                    NewTextBox.Height = BoxHeight;
                    NewTextBox.Left = (panel1.Width / 3) + 5; // Start next to label
                    NewTextBox.Top = ControlCount;
                    NewTextBox.Name = "txt" + ControlBoxName;
                    panel1.Controls.Add(NewTextBox);
                }
                CreateLabel(ControlCount, LabelText);
                panel1.Height = ControlCount + 32;
            }

            ScrollSet();
            CurrentFields.Dispose();
        }

        private void CreateLabel(int TopValue, string LabelName)
        {
            // Label Control
            Label NewLabel = new Label();
            NewLabel.Width = (panel1.Width / 3) + 5; // Space little less than 2/3
            NewLabel.Height = BoxHeight;
            NewLabel.Left = 0; // Start at the left edge of the panel1
            NewLabel.Top = TopValue;
            panel1.Controls.Add(NewLabel);
            NewLabel.TextAlign = ContentAlignment.MiddleRight;
            NewLabel.Text = LabelName;
        }

        private void SCRBar_Scroll(object sender, ScrollEventArgs e)
        {
            panel1.Top = -SCRBar.Value;
        }

        private void FieldList_SizeChanged(object sender, EventArgs e)
        {
            ScrollSet();
        }

        private void ScrollSet()
        {
            if (panel1.Height > this.Height)
            {
                SCRBar.Enabled = true;
                SCRBar.Maximum = panel1.Height - this.Height;
            }
            else
            {
                SCRBar.Enabled = false;
            }
            panel1.Top = 0; // Set container's 'top' value
        }

        public List<string> GetValues()
        {
            List<string> strValues = new List<string>();

            foreach (Control BoxControlText in panel1.Controls)
            {
                if (BoxControlText is TextBox || BoxControlText is ComboBox)
                {
                    strValues.Add(BoxControlText.Text);
                }
            }
            return strValues;
        }

        public void SetValues(List<string> BoxValues)
        {
            int ii = 0;
            foreach (Control BoxControlText in panel1.Controls)
            {
                if (BoxControlText is TextBox || BoxControlText is ComboBox)
                {
                    BoxControlText.Text = BoxValues[ii];
                    ii++;
                }
            }
        }
    }
}

The above code is the entire code for the control. I am pretty sure this can be done in easier ways, but the code is doing exactly what I need. If you do come up with some more shortcuts for it, please let me know.

File.Exists(FieldFilePath)

This is one of my best friends in coding when it comes to checking a file or a folder.

panel1.Width = (this.Width - 10) - SCRBar.Width;

Sometimes I set the width of some of the controls during runtime. It's a good practice to make things more organized in your application.

for (ii = 0; ii < SkipFirstLines; ii++)

Here is the code after we skip the first few lines (optional). The reason I decided to have header lines in the Field List file is to put some reminders or warnings. Sometimes people open text files and screw around with them, it's a good thing to let them know not to touch some of them.

ControlCount = ControlCount + (BoxHeight + 2);

This line is the main line which the height of the container calculated. It also sets where the next control (label, textbox, and/or combo box) will be located from the top (of the container).

ControlBoxName = LabelText.Replace(' ','_');

When I name the controls, I make sure there are no spaces between words. I also add "cbo" and/or "txt" to the start of the names to easily identify the type of the control.

panel1.Controls.Add(NewTextBox);

Each control has an "Add" method, so all we have to do is to add the control to wherever we want... in this case, into the container control. Just in case you ask, "Why into the container?" I use the container to group everything, and actually move it up and down with the scrollbar if there are more items than can fit in the control itself (check the private void ScrollSet() method).

I used List<string> a lot in this code. I also used "@" as my separator for the dropdownmenu items, and a "hidden listbox" to keep the "header text" during settings. Remember, these things can be done in many ways. You don't have to use separators, you can use other methods such as lines, or use a database to keep your drop down information and other field information. Instead of a "hidden listbox", you can write your own array class etc. I went shortcut, with the tools available for me instead of writing more lines of code. A habit from VB world. Pros will roll their eyes at this code... and I want to know what they would have done :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here