セルデータのクリップボードコピー機能の実装
TreeDataGridコントロールにおいて、特定セルのテキストを右クリック操作でコピーする機能を実装する方法について説明します。AvaloniaUIのイベント処理メカニズムを活用した実践的なアプローチを紹介します。
基本的な実装フロー
コンテキストメニュー表示直前のイベントをキャッチし、現在フォーカスされているセルのデータを取得する仕組みを構築します。以下のXAML構成を採用します。
<TreeDataGrid x:Name="DataGridControl">
<TreeDataGrid.ContextMenu>
<ContextMenu>
<MenuItem x:Name="CopyCellCommand"
Header="セル内容をコピー"
Click="HandleCellCopy"/>
</ContextMenu>
</TreeDataGrid.ContextMenu>
</TreeDataGrid>
データモデルの定義
グリッドにバインドするデータ構造を以下のように設計します。
public record GridItemData(string Title, string Content);
イベントハンドリングの実装
コンテキストメニュー表示時のイベント処理を記述します。重要なポイントは、ルーティングイベントのソースから直接テキストデータを取得する方法です。
private void DataGridControl_ContextRequested(object? sender, ContextRequestedEventArgs e)
{
if (e.Source is TextBlock targetCell && !string.IsNullOrEmpty(targetCell.Text))
{
e.EventArgs.Handled = true;
CopyCellCommand.Tag = targetCell.Text;
}
}
クリップボード操作の実装
コピー操作の実際の処理を非同期で実行します。クリップボードAPIのエラーハンドリングも含めます。
private async void HandleCellCopy(object? sender, RoutedEventArgs e)
{
if (CopyCellCommand.Tag is not string cellText) return;
try
{
await TopLevel.GetTopLevel(this)?.Clipboard?.SetTextAsync(cellText) ??
Task.CompletedTask;
}
catch (Exception ex)
{
Debug.WriteLine($"クリップボード操作失敗: {ex.Message}");
}
}
データソースの設定
グリッドのデータバインディング設定例を示します。
var items = new List<GridItemData>
{
new("ドキュメント1", "詳細内容A"),
new("レポート2", "詳細内容B")
};
DataGridControl.Source = new FlatTreeDataGridSource<GridItemData>(items)
{
Columns =
{
new TextColumn<GridItemData, string>("タイトル", x => x.Title),
new TextColumn<GridItemData, string>("内容", x => x.Content)
}
};
実装のポイント
- ContextRequestedイベントはコンテキストメニュー表示直前に発火するため、リアルタイムのセル状態を取得可能
- イベント引数のSourceプロパティにアクセスすることで、現在のUI要素ツリーを参照
- TopLevel経由でのClipboardアクセスにより、ウィンドウコンテキスト外からの操作も可能
- 非同期処理でUIスレッドをブロックせずにクリップボード操作を実行