XamDataGridでFieldGroupを使って列をグループ化していると、クリップボード機能でコピーした際に、既定の実装ではコピー結果の列順が画面の表示順と一致しないことがあります。本記事では、ClipboardCopyingイベントを使って選択範囲を独自に文字列化し、常に画面の表示順通りにクリップボードへコピーする方法を紹介します。
XamDataGrid の設定
まずXamDataGridでクリップボード操作を有効にし、ClipboardCopyingイベントをハンドラーに割り当てます。今回のポイントは、FieldGroupを使って列をグループ化している点です。
<igWPF:XamDataGrid x:Name="xamDataGrid1" DataSource="{Binding}" ClipboardCopying="xamDataGrid1_ClipboardCopying">
<igWPF:XamDataGrid.FieldLayoutSettings>
<igWPF:FieldLayoutSettings AutoGenerateFields="False" AllowClipboardOperations="All"/>
</igWPF:XamDataGrid.FieldLayoutSettings>
<igWPF:XamDataGrid.FieldLayouts>
<igWPF:FieldLayout>
<igWPF:Field Name="AAA" />
<igWPF:FieldGroup Label="BBB">
<igWPF:Field Name="B1"/>
<igWPF:Field Name="B2"/>
</igWPF:FieldGroup>
<igWPF:Field Name="CCC" />
<igWPF:FieldGroup Label="DDD">
<igWPF:Field Name="D1"/>
<igWPF:Field Name="D2"/>
</igWPF:FieldGroup>
<igWPF:Field Name="EEE" />
</igWPF:FieldLayout>
</igWPF:XamDataGrid.FieldLayouts>
</igWPF:XamDataGrid>

例えば、AAA、BBB(B1・B2)、CCC、DDD(D1・D2)、EEEの順に列が並んだ画面で、値が「A0、B0、B1、C0、D0、D1、E0」の1行目を選択してコピーし、MS Excelにペーストすると、既定の実装ではFieldGroup外の列(AAA・CCC・EEE)が先にまとめられ、FieldGroup内の列(BBB・DDD)が後に続く「A0、C0、E0、B0、B1、D0、D1」という順序でペーストされてしまい、画面の表示順とは異なる結果になります。

ClipboardCopying イベントの処理
ClipboardCopyingイベントでは、既定のコピー処理をキャンセルし(e.Cancel = true)、選択されているセル(SelectedItems.Cells)またはレコード(SelectedItems.Records)を画面の表示順に走査しながら独自にタブ・改行区切りの文字列を組み立て、Clipboard.SetTextでクリップボードに設定します。こうすることで、FieldGroupの有無に関わらず、常に見た目通りの順序でコピーが行われるようになります。
private void xamDataGrid1_ClipboardCopying(object sender, Infragistics.Windows.DataPresenter.Events.ClipboardCopyingEventArgs e)
{
if (sender is not XamDataGrid xamDataGrid)
{
return;
}
var strBuilder = new StringBuilder();
var selectedCells = xamDataGrid.SelectedItems.Cells;
var selectedCellCount = selectedCells.Count;
if (selectedCellCount > 0)
{
for (var i = 0; i < selectedCellCount; i++)
{
var currentCell = selectedCells[i];
if (i > 0)
{
var previousCell = selectedCells[i - 1];
if (previousCell.Record.Index != currentCell.Record.Index)
{
strBuilder.Append("\r\n");
}
else
{
strBuilder.Append('\t');
}
}
strBuilder.Append(currentCell.Value);
}
}
else
{
foreach (DataRecord rec in xamDataGrid.SelectedItems.Records)
{
var cells = rec.Cells;
var cellCount = cells.Count;
for (var i = 0; i < cellCount; i++)
{
if (i > 0)
{
strBuilder.Append('\t');
}
strBuilder.Append(cells[i].Value);
}
strBuilder.Append("\r\n");
}
}
Clipboard.SetText(strBuilder.ToString());
e.Cancel = true;
}
実行結果
サンプルを実行し、先ほどと同じ1行目を選択してコピーした後、MS Excelにペーストすると、今度はFieldGroupで並べた列の順序通り「A0、B0、B1、C0、D0、D1、E0」の順でデータが貼り付けられ、画面の見た目通りの結果が得られます。
