65.9K
CodeProject 正在变化。 阅读更多。
Home

字段列表控件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (3投票s)

2010 年 4 月 20 日

CPOL

3分钟阅读

viewsIcon

26437

downloadIcon

620

用于文档编码或质量控制 (QC) 应用程序的编码控件。

FieldListControl.jpg

引言

我开始编写一个大型程序,其中将包含一些好的功能,以便能够对文档的字段进行编码,并通过搜索字段和/或文档的 OCR 文本轻松检索它们。 我的应用程序的前两个步骤已经完成。 我想分享我编写的一个组件,称为“字段列表”控件。

此控件运行于一个扩展名为 "lst" 的文件,该文件以文本格式携带一个非常简单的结构。

更新

由于其复杂性(!),我只上传了控件示例项目,而不是我正在处理的项目,其中包含该控件。 借助新的示例代码和新的视频剪辑,应该很容易理解此控件及其设计用途。(在此处观看其视频剪辑)

关注点

我可能应该将我的编码水平从 C# 初学者提高到 C# 初学者/中级 :) 使用此控件,字段条目是无限的。 通过它的“滚动条”,用户可以上下移动。

Components

我将在此处包含一个组件:FieldList 控件

FieldList 控件有一个垂直滚动条和一个容器,该容器在运行时创建标签、文本框和/或下拉框。 这是人们可能从该控件中学到的一个有用之处:如何在运行时创建控件并从中获取信息。 QnCMain 窗体是主编码器窗体的预览。

lstFile.jpg

代码

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++;
                }
            }
        }
    }
}

以上代码是该控件的完整代码。 我确信可以用更简单的方法来完成,但代码完全实现了我的需求。 如果您能为它提出一些更快捷的方法,请告诉我。

File.Exists(FieldFilePath)

当涉及到检查文件或文件夹时,这是我在编码方面最好的朋友之一。

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

有时我在运行时设置某些控件的宽度。 这是一个很好的做法,可以使应用程序中的事物更有条理。

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

这是我们跳过前几行之后的代码(可选)。 我决定在 Field List 文件中包含标题行的原因是放入一些提醒或警告。 有时人们会打开文本文件并对其进行修改,让他们知道不要碰其中的某些内容是件好事。

ControlCount = ControlCount + (BoxHeight + 2);

此行是计算容器高度的主要行。 它还设置了下一个控件(标签、文本框和/或组合框)将从顶部(容器顶部)开始的位置。

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

当我命名控件时,我确保单词之间没有空格。 我还会在名称的开头添加 "cbo" 和/或 "txt" 以便轻松识别控件的类型。

panel1.Controls.Add(NewTextBox);

每个控件都有一个“Add”方法,所以我们所要做的就是将控件添加到我们想要的位置……在这种情况下,添加到容器控件中。 以防万一你问,“为什么放入容器?” 我使用容器将所有内容分组,如果项目多于控件本身可以容纳的,则实际上用滚动条上下移动它(检查 private void ScrollSet() 方法)。

我在该代码中大量使用了 List<string>。 我还使用 "@" 作为下拉菜单项目的分隔符,并使用一个“隐藏的列表框”来保存设置期间的“标题文本”。 请记住,这些事情可以用多种方式完成。 您不必使用分隔符,您可以使用其他方法,例如行,或者使用数据库来保存您的下拉信息和其他字段信息。 您可以编写自己的数组类等,而不是使用“隐藏的列表框”。 我采取了捷径,使用了我可用的工具,而不是编写更多的代码行。 来自 VB 世界的习惯。 专业人士会对这段代码翻白眼……我想知道他们会怎么做 :)

FieldList 控件 - CodeProject - 代码之家
© . All rights reserved.