在桌面程式開發過程中我們常常使用DataGridView作為資料展示的表格,在表格中我們可能要對資料進行查詢或者替換。
其實要實現這個查詢替換的功能並不難,記錄下實現過程,不一定是最好的方式,但它有用!
先看demo下效果
1、資料展示
- 建一個WinForm窗體 GridDataWindow ,放上選單和DataGridView控制元件,新增4列用來顯示資訊。
- 建立一個Person類用於顯示資料
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
}
- 在窗體Load事件裡面初始化顯示資料
2、查詢替換窗體
- 建一個WinForm窗體 DataToolsWindow
這個窗體主要是用來控制查詢和替換的文字,選擇範圍是當前列還是整個資料表格。
窗體中主要是查詢替換文字的值,選中的查詢範圍和是否能設定查詢範圍變數;還包括4個事件,4個事件在GridDataWindow 中新增用於響應操作。
- LookUpHandler:點選查詢,根據選擇的範圍和值依次查詢表格單元格。
- ReplaceHandler:替換文字,根據選擇的範圍和值依次查詢表格單元格,如果查詢到則替換。
- ReplaceAllHandler:全部替換,根據選擇的範圍和值依次查詢所有表格單元格,查詢到並全部替換。
- WindownClosedHandler:窗體關閉,當查詢窗體關閉後主窗體得到通知並做些需要的邏輯。
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、如何查詢替換
例項化一個DataToolsWindow後對事件進行註冊。重點是如何查詢,因為替換和查詢一樣,只要查詢到了替換就行了。
- 查詢下一個
大概的思路就是按照【選定】的當前單元格為標記,首先以當前單元格為分界線向下查詢,在查詢的過程中判斷使用者選擇的是當前列還是整個資料表,如果是當前列只需要按行查詢當前列就行了。
如果是整個資料表查詢則需要整行的每列都查詢,如果查詢到選中行查詢的列就是找當前列前面的列(後面的列會在向下查詢中遍歷到),如果不是選中行則整行從第一列開始全部列查詢。
同理,向下查詢的思路也就出來了。
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)
{
//如果是當前選中行 則查詢後面的列
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
{
//欄位查詢不查詢當前 因為是查詢下一個
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)
{
//如果是當前選中行 只查詢前面的列
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
{
//欄位查詢不查詢當前 因為是查詢下一個
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("未找到匹配項!");
}
- 替換下一個
替換就比較簡單了,首先如果選中列就是查詢的值則直接替換,然後再替換則按照查詢的思路查詢到下一個後替換就行了,程式碼基本一樣就沒必要放垃圾程式碼了。
- 全部替換
全部替換就不用查詢下一個要顯示查詢過程那麼麻煩了,直接遍歷所有單元格進行替換並選中供使用者檢視就行了。
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("未找到匹配項!");
}
4、原始檔
打包了這個兩個窗體程式碼:DataGridViewExcel.zip