我有一项任务是开发涉及分页的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);
}
如果需要添加任何内容,请与我们联系。
答案 0 :(得分:0)
总结您的要求:
DataGridView
您希望允许用户修改数据:
我认为你有两种方法:
缓存操作是可行的,但在编写缓存和保持数据同步方面显然更加大惊小怪。
所以缓存数据将是我的首选。
以下是如何分解功能的草图:
DataTable
调用更改功能后,必须刷新当前页面显示。
保持内存中的数据总量不应该成为现在的问题;我注意到您正在读取datFile
数组中已存在的所有数据。把它读成一张桌子可以让你一遍又一遍地分开它。
DataTable.DataRow
还提供了HasErrors
或RowState
等不错的功能。它的Items
可以有一个专用的类型来帮助格式化..
但请注意,DataRow
没有(真正的)构造函数;相反,它必须从DataTable
创建,因此您首先必须从列中创建一个!
显示代码将使用pageSize
和currentFirstLine
变量;它可以清除行并将其添加到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
后立即添加该行。