[C#.NET][Winform][ADO.NET] 實作DataViewGrid複製 / 貼上

[ADO.NET][Winform] 實作DataViewGrid複製 / 貼上

假設我的需求是從DataGridView複製資料,然後再另一個DataGridView貼上

又或者是我要從Excel表格中複製資料,然後在DataGridView貼上

 

我先來實作由DataGridView複製資料,然後貼上另一個DataGridView,在Winform擺了兩個DataViewGrid,

先將DataGridView1塞入資料,並將 ClipboardCopyMode 屬性設為 EnableWithoutHeaderText,主要是我想要忽略標題的複製,在這裡你必須要依照自己的需求變化唷。


private void Form1_Load(object sender, EventArgs e)
{
    DataTable table = new DataTable();
    string[] fields = new string[] { "ID", "Name" };
    foreach (var item in fields)
    {
        DataColumn column = new DataColumn();
        column.Caption = item;
        column.ColumnName = item;
        table.Columns.Add(column);
    }
    DataRow row = table.NewRow();
    row["ID"] = "1";
    row["Name"] = "余小章";
    table.Rows.Add(row); 

    row = table.NewRow();
    row["ID"] = "2";
    row["Name"] = "王大明";
    table.Rows.Add(row);
    this.dataGridView1.DataSource = table;
}

然後再要判斷DataGridView2是否有按下Ctrl+v


private void dataGridView2_KeyPress(object sender, KeyPressEventArgs e)
{
    char value = e.KeyChar;
    int key = (int)value;
    if (key != 22)
        return;
    PasteClipboard(dataGridView2);
}

 

這理有 Ctrl+v的KeyCode

http://www.physics.udel.edu/~watson/scen103/ascii.html

PasteClipboard方法裡使用了Clipboard類別來處理,裡面的處理方式都是依照DataGridView複製規則處理的,請自行觀察clipboard 變數,在這個方法理我也依複製來源的資料列數,增加DataGridView列數


private void PasteClipboard(DataGridView dataGridView)
{
    string clipboard = Clipboard.GetText();
    string[] lines = clipboard.Split('\n'); 

    //取得目前的行列數
    int currentRow = dataGridView.CurrentCell.RowIndex;
    int currentColumn = dataGridView.CurrentCell.ColumnIndex;
    int rowCount = dataGridView.Rows.Count; 

    DataGridViewCell CurrentCell;
    //增加列數
    if (lines.Length > rowCount - currentRow)
    {
        int cut = lines.Length - (rowCount - currentRow);
        dataGridView.Rows.Add(cut);
    }
    //將值寫入到DataGridView
    foreach (string line in lines)
    {
        string[] cells = line.Split('\t');
        for (int i = 0; i < cells.Length; i++)
        {
            //處理儲存格
            CurrentCell = dataGridView[currentColumn + i, currentRow];
            string value = cells[i];
            CurrentCell.Value = value;
        }
        currentRow++;
    }
}

此方法裡我沒有判斷ColumnName就貼上了,比較好的做法的要依ColumnName各別貼上資料,這時就得把Header給考慮進去,總之還是須要依自己的需求去決定,在這裡我就不這麼做了,別傻傻的把專案照抄。

同理,從Excel複製過來的資料或是文字檔(分格符號為Tab)也是符合我的處理;也是因為"貼上"這個動作所會發生的可能性太多,所以預設並沒有提供這個功能吧(聳肩),純屬個人之猜測。

PS.若你的DataGridView有使用資料繫結,那就必須要處理資料來源,而不是直接處理DataGridView。

 

範例演示結果如下

 

範例下載

DataGridView_Clipboard.zip

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo