🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

2回答

3634閲覧

データグリッドビューにドラッグしたアイテムをドロップした行にいれるには

aikawajun

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2021/03/25 08:56

編集2021/03/26 01:42

現在C#にて、3列x10行ほどあるデータグリッドビューにファイルをドラッグアンドドロップしてそのファイル名を選択されている行の3列目に入れると言うような形の処理を行っております。

ただ、選択している場所以外に落とした場合でも、選択した箇所に限定しているため、例えば選択しているのが2行目でも、8行目にドロップしたら8行目に入るようにするにはどうすればいいでしょうか?

一応、現状ドロップした際のソースが下記になります。

private void dataGridView_DragDrop(object sender, DragEventArgs e) { //ドロップされたファイルの一覧を取得 string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false); if (fileName[0] != "") { return; } // ドロップ先がDataGridViewであるかチェック DataGridView Target = sender as DataGridView; if (Target == null) { return; } DataGridViewRowUpdate();// 任意の行にファイル名を入れるメソッド }

色々調べてはいるのですが、ドロップした行に落した場合のイベントがあればいいと思ったのですが、見つけて無いだけかもしれませんが、無さそうでした。

また、MouseMoveにしてしまうと、ファイルをドラッグしていない状態で選択していないのに、選択する行が変わってしまうと少々厄介かと思い他にいい方法が無いかご存じの方がいらっしゃいましたら、ご教授頂けないでしょうか。

よろしくお願いいたします。

※追記
OS:Windows10
VisualStudioのバージョン:Community 2019 Ver 16.9.1
プロジェクトの種類:WindowsForms
フレームワークの種類:.NET Framework 4.8
.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/26 01:34 編集

・開発環境を記入してください。 OS、VisualStudioのバージョン プロジェクトの種類(WindowsForms、WPF、コンソール等)、 フレームワークの種類(.NET Framework X.XX、.NETCore X.X等) ・DataGridタグは、WPFのDataGridを連想させます。WindowsFormsのものならDataGridViewですので修正してください。出来ればWindows Formsタグも付けたほうがよいでしょう。 前回の質問の修正依頼も無視されていますが、対応をお願いします。 きちんと正しい情報を伝えないと正しい回答が付かず、回答者の余計な手間を増やします。(既にsoi013さんがWPFと勘違いした回答をしてしまっています)
aikawajun

2021/03/26 01:43

勝手が分かっておらずすみません。 ご指摘ありがとうございます。 文末に追記とタグの追加と削除をしました。
Hey_CH

2021/03/26 11:56

「C# datagridview ドラッグアンドドロップ」(可能なら英語の方がベター)とかで検索してみてはいかがでしょうか? 最初わからなかったコードでも、今は理解できるかもしれませんよ。 (YAmaGNZさんとのやり取りを見てちょっと思った感想です。)
guest

回答2

0

ベストアンサー

DragEventArgsのX、YプロパティとDataGridView.HitTestメソッドを使ってできませんかね?

投稿2021/03/25 12:29

YAmaGNZ

総合スコア10469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aikawajun

2021/03/26 07:54 編集

//指定された(クリックされた)座標位置の情報を取得する System.Windows.Forms.DataGridView.HitTestInfo hti; hti = Target.HitTest(e.X, e.Y); //クリックされた場所の情報を取得 switch (hti.Type) { case System.Windows.Forms.DataGridViewHitTestType.None: Console.WriteLine("バックグランドがクリックされました。"); break; case default: break; } 上記のようにsender変数をDataGridViewにキャストしたTarget変数を使って、出来ないか試してみたのですが、Typeが何度やってもNoneとなっており、出来なさそうです。 一応、ポイントとしては、合ってるっぽいのですが、多分渡しているポイントの起点がフォームの左上っぽくて、hti変数の値を確認すると-1になっているため、少しお手上げ状態です。
YAmaGNZ

2021/03/26 03:34

スクリーン座標とクライアント座標の違いに気をつけましょう。
aikawajun

2021/03/26 06:24

スクリーン座標とクライアント座標の違いは、調べたため理解できていると思うのですが、フォーム内でさらにデータグリッドビューの座標に絞り込む必要があるのか、そもそもの使っているメソッドが間違っているのかが分からない状態です。
YAmaGNZ

2021/03/26 07:06

DragEventArgsで得られるのは「スクリーン座標」です。 HitTestで指定するのは「クライアント座標」です。 なので、スクリーン座標からクライアント座標に変換する必要があります。
aikawajun

2021/03/26 08:31

そう言う事だったんですね。 e.XとYはスクリーン座標で、HitTestにスクリーン座標を入れれば、枠外で-1になるってことで合っているでしょうか。 スクリーン座標からクライアント座標に変換する方法調べてみます。 ありがとうございます。
aikawajun

2021/03/26 09:16

Point sp, cp; // スクリーン座標の取得 sp = Cursor.Position; // クライアント座標に変換 cp = this.PointToClient(sp); //指定された(クリックされた)座標位置の情報を取得する System.Windows.Forms.DataGridView.HitTestInfo hti; hti = Target.HitTest(cp.X, cp.Y); 先ほどのソースにクライアント座標の指定をしてみたのですが、それでも-1でTypeがNoneになっておりました。 上記でもやはりおかしいでしょうか?
YAmaGNZ

2021/03/26 09:19

HitTestで使うのは「DataGridViewのクライアント座標」です。 thisの指定となると、フォームのクライアント座標となります。
guest

0

追記:WPFの回答はを書きましたが、質問のプラットフォームはWinFormsだったので、使えません。


DataGridAutoGenerateになっていなくて、ドロップするのは行全体でなくても良いのであれば、発想を変えてドロップ用の列を作ってしまうのはどうでしょうか?

DataGridDataGridの行ではなく、ドロップ用の列の1つ1つのセルのTextBlockにドロップイベントがついているような形です。
どの行にドロップされかを判別する方法はいろいろありますが、Tagオブジェクトを流用してみました。
コードビハインドで書きましたが、MVVMでも可能です。

xaml

1<Window 2 x:Class="DataGridFileDrop.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" Height="450"> 6 <DataGrid x:Name="myDataGrid" AutoGenerateColumns="False"> 7 <DataGrid.Columns> 8 <DataGridTemplateColumn> 9 <DataGridTemplateColumn.CellTemplate> 10 <DataTemplate> 11 <TextBlock 12 AllowDrop="True" 13 Drop="TextBlock_Drop" 14 Tag="{Binding}" 15 Text="[DROP HERE!]" /> 16 </DataTemplate> 17 </DataGridTemplateColumn.CellTemplate> 18 </DataGridTemplateColumn> 19 <DataGridTextColumn Binding="{Binding}" /> 20 </DataGrid.Columns> 21 </DataGrid> 22</Window>

csharp

1public partial class MainWindow : Window 2{ 3 public MainWindow() 4 { 5 InitializeComponent(); 6 7 myDataGrid.ItemsSource = new[] { "TARO", "KOJIRO", "SABURO" }; 8 } 9 10 private void TextBlock_Drop(object sender, DragEventArgs e) 11 { 12 if (sender is TextBlock dropedTB && dropedTB.Tag is string dropedName) 13 { 14 if (e.Data.GetData(DataFormats.FileDrop, false) is string[] fileNames) 15 { 16 foreach (string fileName in fileNames) 17 { 18 Trace.WriteLine($"Droped {e.Data} at {fileName}"); 19 } 20 } 21 } 22 } 23}

投稿2021/03/25 12:22

編集2021/03/26 11:14
soi013

総合スコア149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/26 01:17

質問のサンプルソースから見て、恐らくWPFではなくWindowsFormsです。
soi013

2021/03/26 11:12

うっかりしてました。修正依頼で先に聞けばよかったですね。 まぁ、誰かの役に立つ可能性が0ではないので、そのままにしておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問