C#

C# -- DataGridView 정렬과 row 이동하기 (DataTable, DataView 사용)

자유프로그램 2019. 4. 27. 11:06
반응형

C# -- DataGridView 정렬과 row 이동하기

       ( DataTable 과 연결된 DataGridView 정렬하기 )

 

소스 ; 

datatable_datagridview_test.zip
0.33MB

 

< 기본 전제 조건 >

- 정렬시에는 row 이동막음

  왜냐면, row 이동은 원본 data 순서를 이동시키는 목적임.

 

 

 

** DataTable row 복사하기

 

 

 

 

<< 실행 결과 >>

 

 

 

<< 소스코드 >>

--

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace datatable_datagridview_test
{
public partial class Form1 : Form
{
private List<Stock> _stockList = new List<Stock>();
private DataTable _dt = new DataTable(); // original data
private DataTable _dtSort = new DataTable(); // 정렬한 data -- 즉, _dt 의 복사본.
private DataGridViewCell _currentCell = null;
private bool _isSortable = false; // 정렬가능 모드면, true;
private bool _isAsc = true; // 정렬 모드
public Form1()
{
InitializeComponent();
this._stockList.Add(new Stock() { StockCode = "005930", StockName = "삼성전자", Price = 44750 });
this._stockList.Add(new Stock() { StockCode = "068270", StockName = "셀트리온", Price = 213500 });
this._stockList.Add(new Stock() { StockCode = "215600", StockName = "신라젠", Price = 64100 });
this._stockList.Add(new Stock() { StockCode = "003490", StockName = "대한항공", Price = 34350 });
this._stockList.Add(new Stock() { StockCode = "011150", StockName = "CJ씨푸드", Price = 3130 });
}
private void Form1_Load(object sender, EventArgs e)
{
_dt.Columns.Add("종목코드", typeof(string));
_dt.Columns.Add("종목명", typeof(string));
_dt.Columns.Add("가격", typeof(int));
foreach (var stock in _stockList)
{
_dt.Rows.Add(stock.StockCode, stock.StockName, stock.Price);
}
_dtSort = _dt.DefaultView.ToTable(); // 정렬용 _dt 복사본
if (this._isSortable)
{
this.dataGridView1.DataSource = _dtSort.DefaultView;
}
else
{
this.dataGridView1.DataSource = _dt; // 원본 연결.
}
foreach(DataGridViewColumn col in this.dataGridView1.Columns)
{
col.SortMode = DataGridViewColumnSortMode.NotSortable;
}
this.dataGridView1.CurrentCell = null;
}
private void btnDataLoad_Click(object sender, EventArgs e)
{
}
private void btnUpFirst_Click(object sender, EventArgs e)
{
int idx = _currentCell.RowIndex;
int idxColumn = _currentCell.ColumnIndex;
if (idx == 0)
{
// 맨 위면, 그냥 종료!
return;
}
DataRow row = _dt.Rows[idx];
DataRow newRow = _dt.NewRow();
newRow.ItemArray = row.ItemArray; // 내용 복사.
_dt.Rows.RemoveAt(idx);
_dt.Rows.InsertAt(newRow, 0);
this.dataGridView1.CurrentCell = dataGridView1[idxColumn, 0];
_dtSort = _dt.DefaultView.ToTable(); // 정렬용 _dt 복사본 갱신하기.
}
private void btnDownLast_Click(object sender, EventArgs e)
{
int idx = _currentCell.RowIndex;
int idxColumn = _currentCell.ColumnIndex;
if (idx == _dt.Rows.Count - 1)
{
// 맨 마지막 이면, 그냥 종료!
return;
}
DataRow row = _dt.Rows[idx];
DataRow newRow = _dt.NewRow();
newRow.ItemArray = row.ItemArray; // 내용 복사.
_dt.Rows.RemoveAt(idx);
_dt.Rows.Add(newRow);
this.dataGridView1.CurrentCell = dataGridView1[idxColumn, _dt.Rows.Count - 1];
_dtSort = _dt.DefaultView.ToTable(); // 정렬용 _dt 복사본 갱신하기.
}
private void btnUp_Click(object sender, EventArgs e)
{
int idx = _currentCell.RowIndex;
int idxColumn = _currentCell.ColumnIndex;
if (idx == 0)
{
// 맨 위면, 그냥 종료!
return;
}
DataRow row = _dt.Rows[idx];
DataRow newRow = _dt.NewRow();
newRow.ItemArray = row.ItemArray; // 내용 복사.
_dt.Rows.RemoveAt(idx);
_dt.Rows.InsertAt(newRow, idx - 1);
this.dataGridView1.CurrentCell = dataGridView1[idxColumn, idx-1];
_dtSort = _dt.DefaultView.ToTable(); // 정렬용 _dt 복사본 갱신하기.
}
private void btnDown_Click(object sender, EventArgs e)
{
int idx = _currentCell.RowIndex;
int idxColumn = _currentCell.ColumnIndex;
if (idx == _dt.Rows.Count - 1)
{
// 맨 마지막 이면, 그냥 종료!
return;
}
DataRow row = _dt.Rows[idx];
DataRow newRow = _dt.NewRow();
newRow.ItemArray = row.ItemArray; // 내용 복사.
_dt.Rows.RemoveAt(idx);
_dt.Rows.InsertAt(newRow, idx+1);
this.dataGridView1.CurrentCell = dataGridView1[idxColumn, idx+1];
_dtSort = _dt.DefaultView.ToTable(); // 정렬용 _dt 복사본 갱신하기.
}
private void btnDisplayData_Click(object sender, EventArgs e)
{
// dataTable 원본 내용을 textbox 에 출력하기 -- _dt 출력
foreach(DataRow row in _dt.Rows)
{
string txt = $"종목코드={row[0]}, 종목명={row["종목명"]}, 현재가={row[2]}";
this.textBox1.AppendText(txt + Environment.NewLine);
}
}
private void btnSortedDataTable_Click(object sender, EventArgs e)
{
// 정렬한 dataTable 내용 출력하기 -- _dtSort 출력
foreach (DataRow row in _dtSort.Rows)
{
string txt = $"종목코드={row[0]}, 종목명={row["종목명"]}, 현재가={row[2]}";
this.textBox1.AppendText(txt + Environment.NewLine);
}
}
private void btnInfo_Click(object sender, EventArgs e)
{
Debug.WriteLine($"-- info ; _currentCell row= {_currentCell.RowIndex}, column={_currentCell.ColumnIndex}");
}
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
// column header click 인경우 -- sort 용
//Console.WriteLine($"heder click idx -- {e.ColumnIndex} {this.dataGridView1.Columns[e.ColumnIndex].HeaderText}");
if (!this._isSortable)
{
// 정렬 불가능시..
return;
}
string columnName = this.dataGridView1.Columns[e.ColumnIndex].HeaderText;
if (this._isAsc)
{
this._dtSort.DefaultView.Sort = columnName + " ASC"; // dataTable.DataView 를 정렬하기.
this._isAsc = ! this._isAsc;
}
else
{
this._dtSort.DefaultView.Sort = columnName + " DESC";
this._isAsc = !this._isAsc;
}
this._dtSort = _dtSort.DefaultView.ToTable(); // 정렬한 결과를 dataTable 에 저장하기.
this.dataGridView1.DataSource = this._dtSort.DefaultView; // dataTable 의 변환된 값을, 다시 datagridview 에 출력한다.
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Console.WriteLine($"datagridview click; col index = {e.ColumnIndex}, row index = {e.RowIndex}");
if(e.RowIndex == -1)
{
// column header click !!!
}
}
private void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
{
_currentCell = this.dataGridView1.CurrentCell;
if (_currentCell != null)
{
Debug.WriteLine($"_currentCell row= {_currentCell.RowIndex}, column={_currentCell.ColumnIndex}");
}
}
private void btnClear_Click(object sender, EventArgs e)
{
this.textBox1.Clear();
}
private void chkBoxSort_CheckedChanged(object sender, EventArgs e)
{
if (this.chkBoxSort.Checked)
{
// 정렬보기 -- 정렬만 가능, 원본 row 이동 불가능.
this._isSortable = true; // 정렬가능. -- 원본 row 이동작업 불가능
this.btnUp.Enabled = false;
this.btnUpFirst.Enabled = false;
this.btnDown.Enabled = false;
this.btnDownLast.Enabled = false;
this.dataGridView1.DataSource = _dtSort.DefaultView; // 정렬용 복사본 dataTable 연결.
}
else
{
// 정렬 안됨. -- 원본 data 의 row 이동 가능.
this._isSortable = false; // 정렬 불가능 -- 원본 row 이동작업 가능.
this.btnUp.Enabled = true;
this.btnUpFirst.Enabled = true;
this.btnDown.Enabled = true;
this.btnDownLast.Enabled = true;
this.dataGridView1.DataSource = _dt; // 원본 연결.
}
}
private void btnInput_Click(object sender, EventArgs e)
{
Debug.WriteLine($"before ; _currentCell.Text = {_currentCell.Value}");
if(_currentCell.ColumnIndex == 2)
{
_currentCell.Value = int.Parse(this.textBox2.Text.Trim());
}
else
{
_currentCell.Value = this.textBox2.Text.Trim();
}
Debug.WriteLine($"after ; _currentCell.Text = {_currentCell.Value}");
}
}
public class Stock
{
public string StockCode { get; set; }
public string StockName { get; set; }
public int Price { get; set; }
}
}

 

 

 

 

 

반응형