2012-11-01 58 views
5

WPF Datagridで作業していますが、コピーの&貼り付けメカニズムを強化/変更しようとしています。WPF Datagrid:追加の行をクリップボードにコピー

ユーザーがいくつかのセルを選択してCTRL + Cを押すと、基になるコントロールはCopyingRowClipboardContentイベントをキャッチできます。

this.mainDataGrid.CopyingRowClipboardContent 
       += this.DatagridOnCopyingRowClipboardContent; 

この方法では、いくつかのセルがヘッダーと行の両方に追加され、結果として「より広い」グリッドが作成されます。私は最後の行の後にヘッダーと2前に追加の行を追加しようとしていますので、私はこだわっています。この時点で

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")); } 

(下の画像を参照)。

アイデア?提案?

ここでは、MVVMのやり方には興味がありません。ここで

enter image description here

+0

スウィートpicが、あなたはそれをどのように描くのですか? –

+2

ありがとうございます。古い学校のペンと紙==> iPhoneの絵は==>作物を作ってPaint.Netで調整してください。おそらく、全体には1分もかかりません。私の右手を使うという事実は偶然です。 :) – mhttk

答えて

3

あなたを助けるかもしれないコードスニペットです。 このスニペットは、主に、ヘッダーを含め、選択したすべてのデータを取得するために使用されます(私はRowHeaders部分を削除しました。 ご不明な点がございましたら、お知らせください。私は大文字で書かれたコメントをいくつか残しました。これはあなた自身のデータを追加する場所です このアプローチの良い点は、DataGridItemsSourceで直接動作し、DataGridCellではないことです。主な理由は:例えば、フォーマット番号にDataGridCellを使用すると、実際の値は得られませんが、フォーマットされたものだけです(あなたのソースは14.49で、StringFormatはN0です。 "普通の"方法)

/// <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

これはかなり面白いです。だからあなたのアプローチは、実際にグリッド内のメカニズムを完全にバイパスすることです。 – mhttk

+0

私は上で説明したように、デフォルトのものが私のニーズを十分に満たしていないのでコピー/貼り付けの動作を再定義しました(私は自然で、 – Damascus

0

あなたはコンテンツを後でExcelですか? もしそうなら、ここで私がやったことだ:私の場合は

/// <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; 
} 

私はいくつかの静的ヘッダーの簡単いくつかの変数と連結することができていました。重要なことは、別のセルを宣言するための\tです。は次の行を宣言します。

0

私はこれを古い投稿と認識していますが、私はクリップボードにデータグリッドの行をコピーするより最近の質問を見つけることができませんでした。 Clipboard.SetDataを使用すると、ClipboardRowContentの意図が無効になります。

私のニーズに合わせて、私が望む行のeClipboardRowContentに再度貼り付けています。 cell.Itemは、選択した行ごとに必要なすべての情報です。

ヒント:e.ClipboardRowContent.Clear();を実行せずに重複を取得していました。 eClipboardRowContentを使用した後私は前にクリアし、DataGrid.SelectedItemsを使って行を構築していました。

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); 

}

関連する問題