2012-05-09 31 views
12

Mam DataGridView w aplikacji .Net (V4 C# VS2010) & chcę skopiować wszystkie dane do schowka za pomocą kliknięcia przycisku. Nie ma problemu -DataGridView: Kopiowanie zakończone do schowka

private void copyToClipboard() 
{ 
    dataGridView1.SelectAll(); 
    DataObject dataObj = dataGridView1.GetClipboardContent(); 
    if (dataObj != null) 
     Clipboard.SetDataObject(dataObj); 
} 

Problem jest to, że użytkownik może już mieć pewne komórki, wiersze itp wybrane na DataGrid & naprawdę nie chce zmienić ten wybór. Powyższe oczywiście wszystko wybiera. Mogę danychGridView1.ClearSelection(); na końcu, który jest marginalnie lepszy, ale wciąż nie osiąga tego, co jest wymagane.

mogę zapisać wybrane komórki:

var mySelectedCells = dataGridView1.SelectedCells; 

ale jak mogę dostać te zaznaczone komórki wybrać ponownie na DataGrid po egzemplarzu? Czy istnieje prosty sposób na odzyskanie kolekcji wybranych komórek z powrotem do DataGrid? Być może istnieje lepszy sposób na skopiowanie całej siatki do schowka bez wpływu na obecnie wybrane komórki?

Odpowiedz

10

Przypuszczam, jeśli tylko chciał reprezentować zawartość komórek jak tekst i skopiować je do schowka, tabulatorami, można zrobić coś takiego:

var newline = System.Environment.NewLine; 
    var tab = "\t"; 
    var clipboard_string = ""; 

    foreach (DataGridViewRow row in dataGridView1.Rows) 
    { 
     for (int i=0; i < row.Cells.Count; i++) 
     { 
       if(i == (row.Cells.Count - 1)) 
        clipboard_string += row.Cells[i].Value + newline; 
       else 
        clipboard_string += row.Cells[i].Value + tab; 
     } 
    } 

    Clipboard.SetText(clipboard_string); 

Wyjście wydaje się dość podobna do tej z GetClipboardContent(), ale należy uważać na wszelkie DataGridViewImageColumns lub dowolnego typu, który nie jest niejawnie ciągiem.

Edytuj: Anthony jest poprawny, użyj StringBuilder, aby uniknąć przydzielania nowego ciągu dla każdej konkatenacji. Nowy kod:

var newline = System.Environment.NewLine; 
    var tab = "\t"; 
    var clipboard_string = new StringBuilder(); 

    foreach (DataGridViewRow row in dataGridView1.Rows) 
    { 
     for (int i = 0; i < row.Cells.Count; i++) 
     { 
      if (i == (row.Cells.Count - 1)) 
       clipboard_string.Append(row.Cells[i].Value + newline); 
      else 
       clipboard_string.Append(row.Cells[i].Value + tab); 
     } 
    } 

    Clipboard.SetText(clipboard_string.ToString()); 
+0

Dzięki. To właśnie zrobiłem na końcu. Musiałem dodać kolejną instrukcję if 'if (row.Cells [i] .Visible), ponieważ kilka kolumn było niewidocznych i to rozwiązanie kopiuje wszystkie komórki, widoczne lub nie - (' dataGridView1.GetClipboardContent(); 'tylko kopie widoczne rzeczy). Nie jestem pewien, w jaki sposób DataGridViewImageCell zostanie obsłużony, ale nie jest to problemem dla mojej konkretnej aplikacji. – Nigel

+0

Nie ma problemu Nigel, cieszę się z pomocy. Kiedy wspomniałem DataGridViewImageCell, po prostu miałem na myśli, że nie jestem pewien, jak zachowywałby się kod, gdybyś używał czegoś innego niż DataGridViewTextBoxCell, ale uważam, że ten typ jest domyślny, jeśli nie określisz inaczej. Ale jeśli używasz wszystkich komórek TextBox, nie powinno to stanowić problemu. Twoje zdrowie. –

+0

Po prostu chcę wspomnieć, że jeśli 'DataGridView' jest duży, prawdopodobnie chcesz użyć' StringBuilder', a nie tylko używać łączenia ciągów. – Anthony

0

Myślę, że poniższa metoda dokładnie zrobi to, co chcesz. Wystarczy wywołać tę metodę z nazwą DataGridView na zdarzeniu kliknięcia przycisku.

Private Sub CopyDataGridViewToClipboard(ByRef dgv As DataGridView) 
    Try 
     Dim s As String = "" 
     Dim oCurrentCol As DataGridViewColumn 'Get header 
     oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible) 
     Do 
      s &= oCurrentCol.HeaderText & Chr(Keys.Tab) 
      oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, _ 
       DataGridViewElementStates.Visible, DataGridViewElementStates.None) 
     Loop Until oCurrentCol Is Nothing 
     s = s.Substring(0, s.Length - 1) 
     s &= Environment.NewLine 'Get rows 
     For Each row As DataGridViewRow In dgv.Rows 
      oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible) 
      Do 
       If row.Cells(oCurrentCol.Index).Value IsNot Nothing Then 
        s &= row.Cells(oCurrentCol.Index).Value.ToString 
       End If 
       s &= Chr(Keys.Tab) 
       oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, _ 
         DataGridViewElementStates.Visible, DataGridViewElementStates.None) 
      Loop Until oCurrentCol Is Nothing 
      s = s.Substring(0, s.Length - 1) 
      s &= Environment.NewLine 
     Next 'Put to clipboard 
     Dim o As New DataObject 
     o.SetText(s) 
     Clipboard.SetDataObject(o, True) 

    Catch ex As Exception 
     ShowError(ex, Me) 
    End Try 
End Sub 
1

Oto wersja kodu VB w języku C# z opcjami kopiowania nagłówków i kopiowania tylko wybranych wierszy.

private void CopyDataGridViewToClipboard(DataGridView dgv, bool includeHeaders = true, bool allRows = false) 
    { 
     // copies the contents of selected/all rows in a data grid view control to clipboard with optional headers 
     try 
     { 
      string s = ""; 
      DataGridViewColumn oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible); 
      if (includeHeaders) 
      {     
       do 
       { 
        s = s + oCurrentCol.HeaderText + "\t"; 
        oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, DataGridViewElementStates.Visible, DataGridViewElementStates.None); 
       } 
       while (oCurrentCol != null); 
       s = s.Substring(0, s.Length - 1); 
       s = s + Environment.NewLine; //Get rows 
      } 
      foreach (DataGridViewRow row in dgv.Rows) 
      { 
       oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible); 

       if (row.Selected || allRows) 
       { 
        do 
        { 
         if (row.Cells[oCurrentCol.Index].Value != null) s = s + row.Cells[oCurrentCol.Index].Value.ToString(); 
         s = s + "\t"; 
         oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, DataGridViewElementStates.Visible, DataGridViewElementStates.None); 
        } 
        while (oCurrentCol != null); 
        s = s.Substring(0, s.Length - 1); 
        s = s + Environment.NewLine; 
       }          
      } 
      Clipboard.SetText(s); 
     } 
     catch (Exception ex) 
     { 
      toolStripStatusLabel2.Text = @"Error: " + ex.Message; 
     } 
    } 
Powiązane problemy