WinForm使用DataGridView實(shí)現(xiàn)類似Excel表格的查找替換功能
在桌面程序開發(fā)過(guò)程中我們常常使用DataGridView作為數(shù)據(jù)展示的表格,在表格中我們可能要對(duì)數(shù)據(jù)進(jìn)行查找或者替換。
其實(shí)要實(shí)現(xiàn)這個(gè)查找替換的功能并不難,記錄下實(shí)現(xiàn)過(guò)程,不一定是最好的方式,但它有用!
先看demo下效果

1、數(shù)據(jù)展示建一個(gè)WinForm窗體 GridDataWindow ,放上菜單和DataGridView控件,添加4列用來(lái)顯示信息。

創(chuàng)建一個(gè)Person類用于顯示數(shù)據(jù)
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
}
在窗體Load事件里面初始化顯示數(shù)據(jù)

2、查找替換窗體建一個(gè)WinForm窗體 DataToolsWindow

這個(gè)窗體主要是用來(lái)控制查找和替換的文本,選擇范圍是當(dāng)前列還是整個(gè)數(shù)據(jù)表格。
窗體中主要是查找替換文本的值,選中的查找范圍和是否能設(shè)置查找范圍變量;還包括4個(gè)事件,4個(gè)事件在GridDataWindow 中添加用于響應(yīng)操作。
- LookUpHandler:點(diǎn)擊查找,根據(jù)選擇的范圍和值依次查找表格單元格。
- ReplaceHandler:替換文本,根據(jù)選擇的范圍和值依次查找表格單元格,如果查找到則替換。
- ReplaceAllHandler:全部替換,根據(jù)選擇的范圍和值依次查找所有表格單元格,查找到并全部替換。WindownClosedHandler:窗體關(guān)閉,當(dāng)查找窗體關(guān)閉后主窗體得到通知并做些需要的邏輯。
public event EventHandler LookUpHandler;
public event EventHandler ReplaceHandler;
public event EventHandler ReplaceAllHandler;
public event EventHandler WindownClosedHandler;
public bool AllLookup
{
get
{
if (cbRange.SelectedIndex == 1)
return true;
else
return false;
}
set
{
if (value)
{
cbRange.SelectedIndex = 1;
}
else
{
cbRange.SelectedIndex = 0;
}
}
}
public bool CanSetRang
{
set
{
btnLookup.Enabled = false;
btnReplace.Enabled = false;
btnAllReplace.Enabled = false;
}
}
public string LookupContent
{
get { return txtLookup.Text; }
set { txtLookup.Text = value; }
}
public string ReplaceContent
{
get { return txtReplace.Text; }
}
3、如何查找替換

實(shí)例化一個(gè)DataToolsWindow后對(duì)事件進(jìn)行注冊(cè)。重點(diǎn)是如何查找,因?yàn)樘鎿Q和查找一樣,只要查找到了替換就行了。
- 查找下一個(gè)
大概的思路就是按照【選定】的當(dāng)前單元格為標(biāo)記,首先以當(dāng)前單元格為分界線向下查找,在查找的過(guò)程中判斷用戶選擇的是當(dāng)前列還是整個(gè)數(shù)據(jù)表,如果是當(dāng)前列只需要按行查找當(dāng)前列就行了。
如果是整個(gè)數(shù)據(jù)表查找則需要整行的每列都查找,如果查找到選中行查找的列就是找當(dāng)前列前面的列(后面的列會(huì)在向下查找中遍歷到),如果不是選中行則整行從第一列開始全部列查找。
同理,向下查找的思路也就出來(lái)了。
private void ToolsWindow_LookUpHandler(object sender, EventArgs e)
{
int currentRowIndex = dgvPeople.CurrentCell.RowIndex;
int currentColumnIndex = dgvPeople.CurrentCell.ColumnIndex;
foreach (DataGridViewRow row in dgvPeople.Rows)
{
//向下查找
if (row.Index >= currentRowIndex)
{
if (toolsWindow.AllLookup)
{
//如果是當(dāng)前選中行 則查找后面的列
if (currentRowIndex == row.Index)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.ColumnIndex > currentColumnIndex)
{
if (cell.Value != null && cell.Value.ToString().Contains(toolsWindow.LookupContent))
{
cell.Selected = true;
dgvPeople.CurrentCell = cell;
return;
}
}
}
}
else
{ //否則從第一列開始查找
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.Value != null && cell.Value.ToString().Contains(toolsWindow.LookupContent))
{
cell.Selected = true;
dgvPeople.CurrentCell = cell;
return;
}
}
}
}
else
{
//字段查找不查找當(dāng)前 因?yàn)槭遣檎蚁乱粋€(gè)
if (row.Index == currentRowIndex)
continue;
if (row.Cells[currentColumnIndex].Value != null && row.Cells[currentColumnIndex].Value.ToString().Contains(toolsWindow.LookupContent))
{
row.Cells[currentColumnIndex].Selected = true;
dgvPeople.CurrentCell = row.Cells[currentColumnIndex];
return;
}
}
}
}
foreach (DataGridViewRow row in dgvPeople.Rows)
{
//向上查找
if (row.Index <= currentRowIndex)
{
if (toolsWindow.AllLookup)
{
//如果是當(dāng)前選中行 只查找前面的列
if (currentRowIndex == row.Index)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.ColumnIndex < currentColumnIndex)
{
if (cell.Value != null && cell.Value.ToString().Contains(toolsWindow.LookupContent))
{
cell.Selected = true;
dgvPeople.CurrentCell = cell;
return;
}
}
}
}
else
{ //否則從第一列開始查找
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.Value != null && cell.Value.ToString().Contains(toolsWindow.LookupContent))
{
cell.Selected = true;
dgvPeople.CurrentCell = cell;
return;
}
}
}
}
else
{
//字段查找不查找當(dāng)前 因?yàn)槭遣檎蚁乱粋€(gè)
if (row.Index == currentRowIndex)
continue;
if (row.Cells[currentColumnIndex].Value != null && row.Cells[currentColumnIndex].Value.ToString().Contains(toolsWindow.LookupContent))
{
row.Cells[currentColumnIndex].Selected = true;
dgvPeople.CurrentCell = row.Cells[currentColumnIndex];
return;
}
}
}
}
MessageBox.Show("未找到匹配項(xiàng)!");
}
- 替換下一個(gè)
替換就比較簡(jiǎn)單了,首先如果選中列就是查找的值則直接替換,然后再替換則按照查找的思路查找到下一個(gè)后替換就行了,代碼基本一樣就沒(méi)必要放垃圾代碼了。
- 全部替換
全部替換就不用查找下一個(gè)要顯示查找過(guò)程那么麻煩了,直接遍歷所有單元格進(jìn)行替換并選中供用戶查看就行了。
private void ToolsWindow_ReplaceAllHandler(object sender, EventArgs e)
{
bool IsReplace = false;
int currentColumnIndex = dgvPeople.CurrentCell.ColumnIndex;
foreach (DataGridViewRow row in dgvPeople.Rows)
{
if (toolsWindow.AllLookup)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.ColumnIndex != 0 && cell.Value != null && cell.Value.ToString().Contains(toolsWindow.LookupContent))
{
cell.Selected = true;
cell.Value = cell.Value.ToString().Replace(toolsWindow.LookupContent, toolsWindow.ReplaceContent);
IsReplace = true;
}
}
}
else
{
if (row.Cells[currentColumnIndex].Value != null && row.Cells[currentColumnIndex].Value.ToString().Contains(toolsWindow.LookupContent))
{
row.Cells[currentColumnIndex].Selected = true;
row.Cells[currentColumnIndex].Value = row.Cells[currentColumnIndex].Value.ToString().Replace(toolsWindow.LookupContent, toolsWindow.ReplaceContent);
IsReplace = true;
}
}
}
if (!IsReplace)
MessageBox.Show("未找到匹配項(xiàng)!");
}
4、源文件
打包了這個(gè)兩個(gè)窗體代碼:DataGridViewExcel.zip
到此這篇關(guān)于WinForm使用DataGridView實(shí)現(xiàn)類似Excel表格的查找替換的文章就介紹到這了,更多相關(guān)DataGridView實(shí)現(xiàn)表格的查找替換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C#開發(fā)WinForm根據(jù)條件改變DataGridView行顏色
- C#開發(fā)WinForm之DataGridView開發(fā)詳解
- Winform讓DataGridView左側(cè)顯示圖片
- Winform在DataGridView中顯示圖片
- WinForm中DataGridView折疊控件【超好看】
- winform用datagridview制作課程表實(shí)例
- WinForm中DataGridView添加,刪除,修改操作具體方法
- WinForm DataGridView控件隔行變色的小例子
- C#開發(fā)WinForm清空DataGridView控件綁定的數(shù)據(jù)
相關(guān)文章
Unity中的靜態(tài)批處理和動(dòng)態(tài)批處理操作
這篇文章主要介紹了Unity中的靜態(tài)批處理和動(dòng)態(tài)批處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
Unity UGUI的HorizontalLayoutGroup水平布局組件介紹使用
這篇文章主要為大家介紹了Unity UGUI的HorizontalLayoutGroup水平布局組件介紹使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
C#實(shí)現(xiàn)強(qiáng)制關(guān)閉當(dāng)前程序進(jìn)程
這篇文章主要介紹了C#實(shí)現(xiàn)強(qiáng)制關(guān)閉當(dāng)前程序進(jìn)程,本文直接給出實(shí)現(xiàn)代碼,可以實(shí)現(xiàn)完全Kill掉不留痕跡,需要的朋友可以參考下2015-06-06
在WCF數(shù)據(jù)訪問(wèn)中使用緩存提高Winform字段中文顯示速度的方法
這篇文章主要介紹了在WCF數(shù)據(jù)訪問(wèn)中使用緩存提高Winform字段中文顯示速度的方法,是非常實(shí)用的功能,需要的朋友可以參考下2014-09-09

