質問者
ドラッグ中のアイテムを半透明で表示する方法

質問
すべての返信
-
http://www.codeproject.com/useritems/ListViewDragDropManager.asp
この辺りは参考になりませんか ?
-
FC-Shiro 様
ありがとうございます。
ソースを拝見させていただきましたが、
やはりWin32APIを使用しているようです。
最終的な目的は表題の通りですが、
問題を明確にするため、追記させていただきます。
現在、下記のように作成中です。
1)ドラッグ中の半透明アイテムのビジュアルを決定するのは、ドラッグ元のListBox。
2)ドラッグ中の半透明アイテムのビジュアルはAdornerを使用する。
3)ドラッグドロップ操作はSystem.Windows.DragDrop.DoDragDrop()メソッドを使う。
4)ドラッグドロップを管理するマネージャクラスを作成して、
Attached Propertyを使用して ListBoxにドラッグ元、ドロップ先の機能を個別に追加できるようにする。
(マネージャが使用するIドラッグ元、Iドロップ先インターフェースをListBox用に実装したクラスを作成して適用)
下記のサンプルをベースに作成しています。
http://blogs.msdn.com/llobo/archive/2006/12/08/drag-drop-library.aspx
問題となっているのは、DoDragDrop中にマウス座標を上手く取得することができないため、
ドラッグ中の半透明アイテムのビジュアルをマウスに追随させることができない点です。
(ドラッグドロップ中は処理が確定するまでMouse.GetPosition()からもマウス座標を取得できない?)
DoDragDrop中にマウス座標を取得する方法として現在分かっているのは、下記の方法です。
1)Win32APIからマウス座標を取得する。
→ドラッグ元のQueryContinueイベントハンドラ内でWin32APIから取得したマウス座標を適用する。
2)DragEventArgsからマウス座標を取得する。
→ウィンドウ全体のAllowDropを"True"にして、PreviewDragOverイベントハンドラ内でマウス座標を適用する。
できればどちらも避けたいです。
そこで、ドラッグドロップ中に上記方法以外でマウス座標を取得できる方法
がありましたら教えていただけないでしょうか。
もちろん、表題を(できるだけスマートに)実現できれば、上記と全く異なる方法でも構いません。
よろしくお願いします。 -
ターゲットとなるUIElementで
Mouseのイベントを拾ってしまっているので,
ターゲットではないところの上では表示されないですね。
Mouseのイベントは,
いくつかの Add系のメソッドがあるので,
Mouse.AddPreviewMouseMoveHandler(ウィンドウインスタンス,ソース側のハンドラ);
にしてやるカラクリに変えればいいような気がするんですけどね。
以下のように受け取れると思うので試してみて,
Code Snippetclass Class1
{
public void Initialize()
{
UIElement wnd = Application.Current.MainWindow;
Mouse.AddMouseMoveHandler(wnd, OnMouse_Move);
}
public void OnMouse_Move(Object sender, MouseEventArgs e)
{
UIElement container = Application.Current.MainWindow.Content as UIElement;
if(container != null)
{
Console.WriteLine("Mouse_Move: {0}", e.GetPosition(container));
}
}
}
public partial class Window1 : System.Windows.Window
{
Class1 cls;
public Window1()
{
InitializeComponent();
cls = new Class1();
cls.Initialize();
}
}
場所は,実際は,Manager内のOnDragSourceAdvisorChanged などです。
Application.Current.MainWindowでなく,
引数で実際に渡した方がいいような気もするんですけどね。
一応,元のコードに近い形にしてあります。
-
tngar さんからの引用
3)ドラッグドロップ操作はSystem.Windows.DragDrop.DoDragDrop()メソッドを使う。
と言う事で、DoDragDrop()中は、MouseMoveイベントは発生しませんね。(泣)
DoDragDrop()は、ole32.dllのDoDragDropを呼んでいるようです。
ですので、受ける時も、IOleDropSourceやIOleDropTargetインターフェイスを通じて受けているようですね。
(内部で受けて、WPFのイベントに置き換えて発行。と言うような形で実装しているようです。)
今回の場合、アプリケーションを超えてのDrag&Dropが必要無いのであれば、
System.Windows.DragDrop.DoDragDrop()メソッド
を使用しない独自実装を考えていったほうがよさそうです。
アプリケーションを超えてのDragを実装するときには、DoDragDrop()メソッドを使っていくのでしょう。 -
ご返答いただきありがとうございます。
>ふる様
申し訳ありません。「穴あき」の概念が理解できませんでした。
現在、半透明ビジュアルは「IsHitTestVisible = false」としているため、マウスイベントが取れない状態となっています。
たとえば、半透明ビジュアルの"PreviewDragOver"イベント等からマウス座標を取得して適用しつつ、
その下のコントロール(リストボックス等)のイベントも取得する方法がある、ということでしょうか?
具体的な方法をご教示いただけるとありがたいです。
>稍丼様
残念ながら、FC-Shiro様のおっしゃる通り、DoDragDrop()中は、MouseMoveイベントは発生しないようです。
Add系のメソッドについては大変勉強になりました。
>FC-Shiro
やはりそのようですね。
今回はアプリケーションを超えてのドラッグドロップがありそうなので、
「1)Win32APIからマウス座標を取得する。」でいきたいと考えています。