2012-11-01 41 views
5

Tôi đang làm việc với DataGrid của WPF và tôi đang cố gắng cải thiện/thay đổi cơ chế sao chép &.WPF Datagrid: sao chép các hàng bổ sung vào clipboard

Khi người dùng chọn một số ô rồi nhấn CTRL + C, các điều khiển cơ bản có thể bắt được sự kiện CopyingRowClipboardContent.

this.mainDataGrid.CopyingRowClipboardContent 
       += this.DatagridOnCopyingRowClipboardContent; 

Trong phương pháp này, một số ô được thêm vào cả đầu trang và hàng, do đó dẫn đến lưới "rộng hơn".

private void DatagridOnCopyingRowClipboardContent(
     object sender, 
     DataGridRowClipboardEventArgs dataGridRowClipboardEventArgs) 
    { 
     // this is fired every time a row is copied 
     var allContent = dataGridRowClipboardEventArgs.ClipboardRowContent; 

     allContent.Insert(0, new DataGridClipboardCellContent(
              null, 
              this.mainDataGrid.Columns[0], 
              "new cell")); 
    } 

Tại thời điểm này tôi gặp khó khăn bởi vì tôi đang cố gắng để bổ sung thêm một dòng trước header và hai sau hàng cuối cùng (xem hình dưới đây).

Bất kỳ ý tưởng nào? Gợi ý?

Xin lưu ý rằng tôi không quan tâm đến cách thực hiện MVVM tại đây.

enter image description here

+0

ngọt pic làm thế nào bạn vẽ nó? –

+2

Cảm ơn.Old trường bút & giấy ==> iPhone hình ảnh ==> cây trồng và điều chỉnh với Paint.Net. Toàn bộ có thể mất ít hơn một phút. Thực tế là tôi sử dụng tay phải của tôi là ngẫu nhiên. :) – mhttk

Trả lời

3

Đây là đoạn mã có thể giúp bạn. Đoạn mã này chủ yếu được sử dụng để truy xuất tất cả dữ liệu đã chọn của bạn, bao gồm tiêu đề (tôi đã xóa phần RowHeaders vì bạn dường như không cần nó). Nếu bạn có bất kỳ câu hỏi nào, vui lòng cho tôi biết. Tôi để lại một vài phần với ý kiến ​​được viết bằng chữ in hoa: đây là nơi bạn nên thêm dữ liệu của riêng mình Phần tốt nhất của phương pháp này là nó trực tiếp làm việc vớicủa DataGrid và KHÔNG phải là DataGridCell. Lý do chính là: nếu bạn sử dụng DataGridCell trên số được định dạng chẳng hạn, bạn sẽ KHÔNG nhận được giá trị thực, nhưng chỉ số được định dạng (nói nguồn của bạn là 14,49 và StringFormat là N0, bạn sẽ chỉ sao chép 14 nếu bạn sử dụng một cách "thông thường")

/// <summary> 
    /// Handles DataGrid copying with headers 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void OnCopyingDataGrid(object sender, ExecutedRoutedEventArgs e) 
    { 
     // First step: getting the coordinates list of all cells selected 
     IList<Tuple<int, int>> cellsCoordinatesList = new List<Tuple<int, int>>(); 
     HashSet<int> rowList = new HashSet<int>(); 
     HashSet<int> columnList = new HashSet<int>(); 
     foreach (System.Windows.Controls.DataGridCellInfo cell in this.SelectedCells) 
     { 
      int column = cell.Column.DisplayIndex; 
      int row = this.Items.IndexOf(cell.Item); 
      cellsCoordinatesList.Add(new Tuple<int, int>(row, column)); 
      if (!rowList.Contains(row)) 
      { 
       rowList.Add(row); 
      } 
      if (!columnList.Contains(column)) 
      { 
       columnList.Add(column); 
      } 
     } 

     // Second step: Create the table to copy/paste 
     object[,] arrayToBeCopied = new object[rowList.Count, columnList.Count + 1]; 
     IList<string> colHead = this.ColumnHeaders.Cast<object>().Select(h => h.ToString()).ToList(); 
     for (int row = 0; row < arrayToBeCopied.GetLength(0); row++) 
     { 
      for (int column = 0; column < arrayToBeCopied.GetLength(1); column++) 
      { 
       if (row == 0) 
       { 
        arrayToBeCopied[row, column] = colHead[columnList.ElementAt(column - 1)]; 
       } 
       else 
       { 
        arrayToBeCopied[row, column] = // WHATEVER YOU WANT TO PUT IN THE CLIPBOARD SHOULD BE HERE. THIS SHOULD GET SOME PROPERTY IN YOUR ITEMSSOURCE 

       } 
      } 
     } 

     // Third step: Converting it into a string 
     StringBuilder sb = new StringBuilder(); 

     // HERE, ADD YOUR FIRST ROW BEFORE STARTING TO PARSE THE COPIED DATA 

     for (int row = 0; row < arrayToBeCopied.GetLength(0); row++) 
     { 
      for (int column = 0; column < arrayToBeCopied.GetLength(1); column++) 
      { 
       sb.Append(arrayToBeCopied[row, column]); 
       if (column < arrayToBeCopied.GetLength(1) - 1) 
       { 
        sb.Append("\t"); 
       } 
      } 
      sb.Append("\r\n"); 
     } 

     // AND HERE, ADD YOUR LAST ROWS BEFORE SETTING THE DATA TO CLIPBOARD 

     DataObject data = new DataObject(); 
     data.SetData(DataFormats.Text, sb.ToString()); 

     Clipboard.SetDataObject(data); 
    } 
+0

Điều này khá thú vị. Vì vậy, cách tiếp cận của bạn là thực sự hoàn toàn bỏ qua cơ chế trong lưới. – mhttk

+0

Chính xác, tôi đã xác định lại hành vi sao chép/dán vì như tôi đã giải thích ở trên, mặc định không hoàn toàn đáp ứng nhu cầu của tôi (mà tôi cho là tự nhiên, sao chép các giá trị và không viết những gì được viết trên màn hình): / – Damascus

0

Bạn đang cố gắng sao chép nội dung vào ví dụ Excel sau? Nếu vậy, đây là những gì tôi đã làm:

/// <summary> 
/// Copy the data from the data grid to the clipboard 
/// </summary> 
private void copyDataOfMyDataGridToClipboard(object sender, EventArgs e) 
{ 
    // Save selection 
    int selectedRow = this.myDataGrid.SelectedRows[0].Index; 

    // Select data which you would like to copy 
    this.myDataGrid.MultiSelect = true; 
    this.myDataGrid.SelectAll(); 

    // Prepare data to be copied (that's the interesting part!) 
    DataObject myGridDataObject = this.myDataGrid.GetClipboardContent(); 
    string firstRow = "FirstRowCommentCell1\t"+ this.someDataInCell2 +"..\r\n"; 
    string lastTwoRows = "\r\nBottomLine1\t" + yourvariables + "\r\nBottomLine2"; 
    string concatenatedData = firstRow + myGridDataObject.GetText() + lastTwoRows; 

    // Copy into clipboard 
    Clipboard.SetDataObject(concatenatedData); 

    // Restore settings 
    this.myDataGrid.ClearSelection(); 
    this.myDataGrid.MultiSelect = false; 

    // Restore selection 
    this.myDataGrid.Rows[selectedRow].Selected = true; 
} 

Trong trường hợp của tôi, tôi đã có một số tiêu đề của tĩnh mà có thể dễ dàng nối với một số biến. Quan trọng cần viết là \t để khai báo một ô khác, \r\n khai báo hàng kế tiếp

0

Tôi nhận thấy đây là một bài đăng cũ hơn, nhưng tôi đăng giải pháp này để hoàn thành. Tôi không thể tìm thấy một câu hỏi gần đây về việc sao chép các hàng dữ liệu vào clipboard. Sử dụng Clipboard.SetData tuân theo ý định ClipboardRowContent.

Đối với nhu cầu của tôi, tôi đang dán lại vào e.ClipboardRowContent hàng mà tôi muốn. Cell.Item là tất cả thông tin tôi cần cho mỗi hàng đã chọn.

Gợi ý: Tôi đã nhận được bản sao mà không cần thực hiện e.ClipboardRowContent.Clear(); sau khi sử dụng e.ClipboardRowContent. Tôi đã xóa trước và sử dụng DataGrid.SelectedItems để xây dựng các hàng.

private void yourDataGrid_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e) 
{ 
var dataGridClipboardCellContent = new List<DataGridClipboardCellContent>(); 

string prevCell = ""; 
string curCell = ""; 

foreach (DataGridClipboardCellContent cell in e.ClipboardRowContent) 
{ 
    //Gives you access item.Item or item.Content here 
    //if you are using your struct (data type) you can recast it here curItem = (yourdatatype)item.Item;   
    curItem = cell.Item.ToString(); 

    if (curCell != prevCell) 
     dataGridClipboardCellContent.Add(new DataGridClipboardCellContent(item, item.Column, curCell)); 

    prevCell = curCell; 

} 
e.ClipboardRowContent.Clear(); 

//Re-paste back into e.ClipboardRowContent, additionally if you have modified/formatted rows to your liking 
e.ClipboardRowContent.AddRange(dataGridClipboardCellContent); 

}

Các vấn đề liên quan