この記事は2019年05月13日に投稿しました。
目次
エッセンシャルWPF:Windows Presentation Foundation (Programmer's SELECTION)
- 作者: Chris Anderson,星睦
- 出版社/メーカー: 翔泳社
- 発売日: 2007/10/31
- メディア: 大型本
- 購入: 6人 クリック: 128回
- この商品を含むブログ (32件) を見る
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているWPFのDataGridのセルをドラッグアンドドロップで別のDataGridにコピーする方法についてです。
2. WPFのDataGridのセルをドラッグアンドドロップで別のDataGridにコピーする
WPFのDataGridのセルをドラッグアンドドロップで別のDataGridにコピーするには以下のようにします。
実装例
MainWIndow.xaml
<Window x:Class="WPFDataGridDragAndDrop.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WPFDataGridDragAndDrop" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <DataGrid Grid.Row="0" Name="dataGrid1" AutoGenerateColumns="false" CanUserAddRows="false" CanUserSortColumns="false" SelectionMode="Extended" SelectionUnit="Cell" IsReadOnly="true" DataContext="{Binding}" ItemsSource="{Binding}" MouseDoubleClick="DataGrid1_MouseDoubleClick" /> <DataGrid Grid.Row="1" Name="dataGrid2" AutoGenerateColumns="false" CanUserAddRows="false" CanUserSortColumns="false" SelectionMode="Extended" SelectionUnit="Cell" IsReadOnly="true" AllowDrop="true" DataContext="{Binding}" ItemsSource="{Binding}" DragEnter="DataGrid2_DragEnter" Drop="DataGrid2_Drop" /> </Grid> </Window>
MainWIndow.xaml.cs
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFDataGridDragAndDrop { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { /** * @brief コンストラクタ */ public MainWindow() { InitializeComponent(); // DataGrid1を設定します。 dataGrid1.Columns.Add(new DataGridTextColumn() { Header = "番号", Binding = new Binding("no") }); dataGrid1.Columns.Add(new DataGridTextColumn() { Header = "値", Binding = new Binding("value") }); var dataTable1 = new DataTable("DataTable1"); dataTable1.Columns.Add(new DataColumn("no", typeof(string))); dataTable1.Columns.Add(new DataColumn("value", typeof(string))); for (int i = 0; i < 5; i++) { var dataRow1 = dataTable1.NewRow(); dataRow1["no"] = i.ToString(); dataRow1["value"] = i.ToString(); dataTable1.Rows.Add(dataRow1); } dataGrid1.DataContext = dataTable1; // DataGrid2を設定します。 dataGrid2.Columns.Add(new DataGridTextColumn() { Header = "番号", Binding = new Binding("no") }); dataGrid2.Columns.Add(new DataGridTextColumn() { Header = "値", Binding = new Binding("value") }); var dataTable2 = new DataTable("DataTable2"); dataTable2.Columns.Add(new DataColumn("no", typeof(string))); dataTable2.Columns.Add(new DataColumn("value", typeof(string))); for (int i = 0; i < 5; i++) { var dataRow2 = dataTable2.NewRow(); dataRow2["no"] = (i + 10).ToString(); dataRow2["value"] = (i + 10).ToString(); dataTable2.Rows.Add(dataRow2); } dataGrid2.DataContext = dataTable2; } /** * @brief DataGrid1でマウスがダブルクリックされた時に呼び出されます。 * * @param [in] sender DataGrid1 * @param [in] e マウスボタンイベント */ private void DataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e) { // 選択されたDataGrid1のセルの列番号、行番号を取得します。 var dataGrid = sender as DataGrid; var columnIndex = dataGrid.CurrentCell.Column.DisplayIndex; var rowIndex = dataGrid.Items.IndexOf(dataGrid1.CurrentItem); // 選択されたセルを取得します。 var row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow; var cell = dataGrid.Columns[columnIndex].GetCellContent(row); var data = cell as TextBlock; // ドラッグアンドドロップ動作を開始します。 DragDrop.DoDragDrop(dataGrid, data, DragDropEffects.Copy); } /** * @brief DataGrid2にドラッグが開始された時に呼び出されます。 * * @param [in] sender DataGrid2 * @param [in] e マウスボタンイベント */ private void DataGrid2_DragEnter(object sender, DragEventArgs e) { // ドラッグアンドドロップの効果をコピーとします。 e.Effects = DragDropEffects.Copy; } /** * @brief DataGrid2にドロップされた時に呼び出されます。 * * @param [in] sender DataGrid2 * @param [in] e マウスボタンイベント */ private void DataGrid2_Drop(object sender, DragEventArgs e) { // 元データを取得します。 var srcTextBlock = e.Data.GetData(typeof(TextBlock)) as TextBlock; // DataGrid2でDropされた位置のセル(TextBlock)を取得し、元データに書き換えます。 var point = e.GetPosition((UIElement)sender); var hitResultTest = VisualTreeHelper.HitTest(dataGrid2, point); if (hitResultTest != null) { var visualHit = hitResultTest.VisualHit; while (visualHit != null) { if (visualHit is TextBlock) { var dstTextBlock = visualHit as TextBlock; dstTextBlock.Text = srcTextBlock.Text; break; } } visualHit = VisualTreeHelper.GetParent(visualHit); } } } }
3. おわりに
以前Windowsフォームで
を調べたことがあります。
今回WPFのDataGridで同様の処理を行うため、再度調べてみました。
実戦で役立つ C#プログラミングのイディオム/定石&パターン
- 作者: 出井秀行
- 出版社/メーカー: 技術評論社
- 発売日: 2017/02/18
- メディア: 大型本
- この商品を含むブログ (1件) を見る
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688