事件功能应该适用于datagridview中的所有页面 - 分页概念

时间:2016-01-13 07:02:59

标签: c# datagridview

我有一项任务是开发涉及分页的Windows应用程序。如果我执行任何分割日期和时间等事件,则仅应用于当前页面。我想将该事件应用于Datagridview中的所有页面。

如果我采用datatable/dataset并对其进行处理,则UI会花时间读取文件,因为它再次将整个文件读取到数据表。因此,请建议将事件应用于DataGridView中的所有页面的任何其他替代方法。

如果需要,我会在任何网站或此处发布代码或上传我的代码。 如果我的问题不清楚,请告诉我。

VARIABLES DECLARATION:

List<String> cmbList = new List<string>();
        public String Replace;
        public String Find;
        public String Col;
        public String NewColumn;
        public String NewColumnValue;
        public string MyFOrmat { get; set; }
        int PageCount;
        int maxRec;
        int pageSize = 30;
        int currentPage = 1;
        int recNo = 0;
        string FileName;
        String[] datfile;

button1 = BROWSE BUTTON(我在哪里阅读文件):

private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.InitialDirectory = "Desktop";
            openFileDialog1.Filter = "dat files (*.DAT)|*.DAT|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    FileName = openFileDialog1.FileName;
                    string text = System.IO.File.ReadAllText(FileName);
                    datfile = text.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
                    //Added on 2015-12-02
                    maxRec = datfile.Length - 1;
                    PageCount = maxRec / pageSize;
                    LoadPage(MyFOrmat);
 }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }
            }
        }

LOADPAGE代码:

public void LoadPage(string Format, bool isFindAndReplace = false)
        {
            int startRec;
            int endRec;

            if (currentPage == PageCount)
            {
                endRec = maxRec;
            }
            else
            {
                endRec = pageSize * currentPage;
            }

            dataGridView1.Rows.Clear();
            if (recNo == 0)
            {
                dataGridView1.Columns.Clear();
            }

            int rowindex = 0;
            startRec = recNo;
            for (int RowCount = startRec; RowCount <= endRec; RowCount++)
            {
                if (datfile[RowCount].ToString() != "" )
                {
                    if (RowCount == 0)
                    {
                        string[] column = datfile[RowCount].Split('þ');
                        for (int i = 0; i < column.Length - 1; i++)
                        {


     if (column[i].ToString() != "" && column[i].ToString() != "\u0014")
                                {
                                    DataGridViewTextBoxColumn dgvtxtcountry = new DataGridViewTextBoxColumn();
                                    dgvtxtcountry.HeaderText = column[i].ToString();
                                    dgvtxtcountry.Name = column[i].ToString();
                                    dataGridView1.Columns.Add(dgvtxtcountry);
                                    cmbList.Add(column[i]);
                                    i += 1;
                                }
                            }
                        }

                        if (RowCount != 0)
                        {
                            dataGridView1.Rows.Add();
                            string[] column = datfile[RowCount].Split('þ');
                            int index = 0;
                            for (int i = 1; i < column.Length - 1; i++)
                            {
                                if (column[i].ToString() != "\u0014")
                                {
                                    if (i == 3)
                                    {
                                        dataGridView1.Rows[rowindex].Cells[index].Value = Convert.ToDateTime(column[i]).ToString(Format);
                                    }
                                    else
                                    { dataGridView1.Rows[rowindex].Cells[index].Value = column[i].Trim('þ'); }
    index += 1;
                                    i += 1;
                                }
                            }
                            rowindex += 1;
                        }
                    }
                    recNo += 1;
                }
            }

查找并更换事件:

 private void btnFindandReplace_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2();
            f.cmbColumnCombo.DataSource = cmbList;
            f.ShowDialog();

            for (int i = 0; i <= dataGridView1.Rows.Count - 1; i++)
            {
                //dataGridView1.Rows[rowindex].Cells[index].Value = Convert.ToDateTime(column[i]).ToString(Format);
                if (dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value.ToString().ToLower().Contains(f.txtfind.Text.ToLower()))
                {
                    //dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value = dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value.ToString().ToLower().Replace(f.txtfind.Text.ToLower(), f.txtreplace.Text);
                    //bulidDataRow(i);
                    if (!string.IsNullOrEmpty(f.txtfind.Text))
                    {
                        dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value = dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value.ToString().Replace(f.txtfind.Text, f.txtreplace.Text);
                        #region Commented
                        //dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value = dataGridView1.Rows[i].Cells[f.cmbColumnCombo.Text].Value.ToString().Replace(f.txtfind.Text, f.txtreplace.Text);
                        //bulidDataRow(i);
                        #endregion
                    }
                }
            }
        }

private void btnNext_Click(object sender, EventArgs e)
    {
        currentPage += 1;
        if (currentPage > PageCount)
        {
            currentPage = PageCount;
            //Check if you are already at the last page.
            if (recNo == maxRec)
            {
                MessageBox.Show("You are at the Last Page!");
                return;
            }
        }
        LoadPage(MyFOrmat);
    }

如果需要添加任何内容,请与我们联系。

1 个答案:

答案 0 :(得分:0)

总结您的要求:

  • 您想要阅读10k - 500k记录的大数据文件
  • 您希望以DataGridView
  • 的块/页显示它们
  • 您希望允许用户修改数据:

    • 用户可以合并
    • 用户可以对数据
    • 使用更改和替换
    • 日期和时间列可能拆分
  • 应保存可能修改的数据

我认为你有两种方法

  • 缓存数据
  • 缓存操作

缓存操作是可行的,但在编写缓存和保持数据同步方面显然更加大惊小怪。

所以缓存数据将是我的首选。

以下是如何分解功能的草图:

  • 读取整个数据并将其加载到DataTable
  • 的函数
  • 初始显示和显示特定页面的功能
  • 用于对行列表执行每项更改的函数。

调用更改功能后,必须刷新当前页面显示。

保持内存中的数据总量不应该成为现在的问题;我注意到您正在读取datFile数组中已存在的所有数据。把它读成一张桌子可以让你一遍又一遍地分开它。

DataTable.DataRow还提供了HasErrorsRowState等不错的功能。它的Items可以有一个专用的类型来帮助格式化..

但请注意,DataRow没有(真正的)构造函数;相反,它必须从DataTable创建,因此您首先必须从列中创建一个!

显示代码将使用pageSizecurrentFirstLine变量;它可以清除行并将其添加到DGV中,或者您可以使用DataTable来获取绑定解决方案,无论如何都需要DataRows和过滤器放在桌面上,或者放在BindingSource

当然,您也可以使用自己的结构,也可以使用简单的string[]List<string>来保存行数据。

如果您对缓存操作的想法感兴趣,可以创建一个包含以下内容的ChangeAction类:

  • 类型
  • 所需的参数,即列,更改和替换字符串等。

然后在List<ChangeAction>中,您会在它们发生时存储它们,然后将它们应用于每个未更改的行。 但是这是第一个问题:你需要知道哪一行已被更改,可能是ChangeAction可以应用两次而不会搞砸数据..更多问题可能会也可能不会稍后,取决于你的数据和行动的细节..

以下是如何使用类级别变量设置绑定的示例:

DataTable DT = new DataTable();
BindingSource BS = new BindingSource();
int pageSize = 0;
int firstLineVisible = 0;

填写表后,您可以绑定它并设置初始文件管理器:

BS.DataSource = DT;
dataGridView1.DataSource = BS;

pageSize = (dataGridView1.ClientSize.Height - dataGridView1.ColumnHeadersHeight) 
          / dataGridView1.Rows[0].Height;
int l1 = firstLineVisible; int l2 = firstLineVisible + pageSize;
BS.Filter = "Nr >= " + l1  + " and Nr < " + l2;

滚动时,您只需更改firstLineVisible并暂停Filter DataSource ..

现在,所有数据修改都应使用DataTable方法处理SetField中的数据!

另请注意,您的数据中需要一个包含运行编号的列。如果您的数据没有数据,则可以通过将其添加到数据行来轻松添加数据:

该列在DataGridView中自动生成。对于DataTable我们希望在第一条数据线中拥有它;我使用分隔符字符串sep

var lines = File.ReadAllLines(fileName).ToList();
..
string[] sep = { ";" };
var p0 = ("Nr" + sep[0] + lines[0]).Split(sep, StringSplitOptions.None );
DT.Columns.Clear();
for (int i = 0; i < p0.Length; i++) DT.Columns.Add(p0[i], typeof(string));

将其添加到数据中就是这么简单:

for (int l = 1; l < lines.Count; l++)
{
    var p = (l + sep[0] + lines[l]).Split(sep, StringSplitOptions.None);
    DT.Rows.Add(p);
}

如果您想要..:

,可以隐藏数字列
dataGridView1.Columns["Nr"].Visible = false;

您应该在设置Filter后立即添加该行。