C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: WPFでファイルのドラッグ&ドロップ


(過去ログ 122 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■72904 / inTopicNo.1)  WPFでファイルのドラッグ&ドロップ
  
□投稿者/ nobb (49回)-(2014/07/31(Thu) 17:57:04)

分類:[C#] 

WPFでファイルをドロップしてもらい、それをZIP圧縮するというプログラムを作ろうとしています。
その際、フォルダを含めてドロップされたくないので、フォルダが含まれている場合はDragEffects.Noneに設定し、
ドロップを受け付けないようにしたいと思い「PreviewDragEnterイベント」や「DragEnterイベント」で設定しましたが、
カーソルが変更されずに分からなくなってしまいました。

WindowsFormsでは期待通りに動くので、何か初歩的なものを見落としていそうなのですがご教示下さい。

環境:Windows7、VS2013 Update2、WPF、.NET Framework4.5
期待する動作:Form(Window?)上に配置されたImageに対してドラッグされた際、フォルダが含まれている場合は○に斜線のカーソルに、
       ファイルのみの場合は、コピーを行えるカーソルに変更
現状:カーソルが変わらないので、何も考えずにDragEffects.Noneに設定し、カーソルに変化があるかの実験。しかし、常にマウスカーソルに点線の四角のみのカーソル。
※関連しそうなイベントに片っ端から設定していますので、訳が分からない状態(&コピペしまくり)ですが、実験中ですのでご容赦ください。
※GiveFeedBack関連は、自分でカーソルファイルを用意し、既定以外のものを描画したいという時に使うものだとは認識してますが、
 念のため書いてあります。(というか、これにブレークポイント設定してもブレークしないのはなんでだろう・・・?)

== MainWindow.xaml ==
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Background="Black" AllowDrop="True">
        <Border Height="150" BorderThickness="3" BorderBrush="#FFC5BFBF">
            <Image HorizontalAlignment="Center"
                   Height="142"
                   VerticalAlignment="Center"
                   Width="314"
                   Source="img/Drop.png"
                   AllowDrop="True"
                   PreviewDragEnter="Image_PreviewDragEnter"
                   PreviewDragOver="Image_PreviewDragOver"
                   PreviewDragLeave="Image_PreviewDragLeave"
                   PreviewDrop="Image_PreviewDrop"
                   PreviewGiveFeedback="Image_PreviewGiveFeedback"
                   GiveFeedback="Image_GiveFeedback"/>
        </Border>

    </Grid>
</Window>

== MainWindow.xaml.cs ==
using System;
using System.Collections.Generic;
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 WpfApplication1
{
  /// <summary>
  /// MainWindow.xaml の相互作用ロジック
  /// </summary>
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }

    private void Image_PreviewDragEnter(object sender, DragEventArgs e)
    {
      System.Diagnostics.Debug.Print("PreviewDragEnter - e.Effects:{0}", e.Effects);
      e.Effects = DragDropEffects.Copy;
    }

    private void Image_PreviewDragOver(object sender, DragEventArgs e)
    {
      //System.Diagnostics.Debug.Print("PreviewDragOver - e.Effects:{0}", e.Effects);
      e.Effects = DragDropEffects.None;
    }

    private void Image_PreviewDragLeave(object sender, DragEventArgs e)
    {
      System.Diagnostics.Debug.Print("PreviewDragLeave - e.Effects:{0}", e.Effects);
      e.Effects = DragDropEffects.None;
    }

    private void Image_PreviewDrop(object sender, DragEventArgs e)
    {
      System.Diagnostics.Debug.Print("PreviewDrop - e.Effects:{0}", e.Effects);
      e.Effects = DragDropEffects.None;
    }

    private void Image_PreviewGiveFeedback(object sender, GiveFeedbackEventArgs e)
    {
      System.Diagnostics.Debug.Print("PreviewDrop - e.Effects:{0}", e.Effects);
    }

    private void Image_GiveFeedback(object sender, GiveFeedbackEventArgs e)
    {
      System.Diagnostics.Debug.Print("PreviewDrop - e.Effects:{0}", e.Effects);
    }

  }
}

引用返信 編集キー/
■72905 / inTopicNo.2)  Re[1]: WPFでファイルのドラッグ&ドロップ
□投稿者/ Hongliang (216回)-(2014/07/31(Thu) 18:18:14)
PreviewDragEnterおよびPreviewDragOverで、Effectsを操作したときはHandledをtrueにしてやればどうでしょうか。

> ※GiveFeedBack関連は、自分でカーソルファイルを用意し、既定以外のものを描画したいという時に使うものだとは認識してますが、
>  念のため書いてあります。(というか、これにブレークポイント設定してもブレークしないのはなんでだろう・・・?)
GiveFeedBackおよびQueryContinueDragは、D&Dのソース側でのイベントです。
引用返信 編集キー/
■72906 / inTopicNo.3)  Re[1]: WPFでファイルのドラッグ&ドロップ
□投稿者/ とっちゃん (250回)-(2014/07/31(Thu) 18:23:55)
とっちゃん さんの Web サイト
No72904 (nobb さん) に返信
> WPFでファイルをドロップしてもらい、それをZIP圧縮するというプログラムを作ろうとしています。
> その際、フォルダを含めてドロップされたくないので、フォルダが含まれている場合はDragEffects.Noneに設定し、
> ドロップを受け付けないようにしたいと思い「PreviewDragEnterイベント」や「DragEnterイベント」で設定しましたが、
> カーソルが変更されずに分からなくなってしまいました。
>
> WindowsFormsでは期待通りに動くので、何か初歩的なものを見落としていそうなのですがご教示下さい。
>
> 環境:Windows7、VS2013 Update2、WPF、.NET Framework4.5
> 期待する動作:Form(Window?)上に配置されたImageに対してドラッグされた際、フォルダが含まれている場合は○に斜線のカーソルに、
>        ファイルのみの場合は、コピーを行えるカーソルに変更
> 現状:カーソルが変わらないので、何も考えずにDragEffects.Noneに設定し、カーソルに変化があるかの実験。しかし、常にマウスカーソルに点線の四角のみのカーソル。
> ※関連しそうなイベントに片っ端から設定していますので、訳が分からない状態(&コピペしまくり)ですが、実験中ですのでご容赦ください。
> ※GiveFeedBack関連は、自分でカーソルファイルを用意し、既定以外のものを描画したいという時に使うものだとは認識してますが、
>  念のため書いてあります。(というか、これにブレークポイント設定してもブレークしないのはなんでだろう・・・?)
>

Debug.Print()で見ているようですが、デバッガで動きは追いかけてみましたか?

一応確認ですが。。。
DragEnter など、Preview のつかないイベントを使っている理由は何でしょうか?


引用返信 編集キー/
■72908 / inTopicNo.4)  Re[2]: WPFでファイルのドラッグ&ドロップ
□投稿者/ nobb (50回)-(2014/08/01(Fri) 09:19:07)
No72905 (Hongliang さん) に返信
ご回答ありがとうございます。

> PreviewDragEnterおよびPreviewDragOverで、Effectsを操作したときはHandledをtrueにしてやればどうでしょうか。
PreviewDragOverに[e.Handled = true;]を設定することで期待する動作になりました。
ただ、PreviewDragEnterの方に何を設定していてもカーソルに変化はみられませんでした。
WinFormsの時はDragEnterイベントで変化させてましたが、これは変わったと考えていいのでしょうか?


> GiveFeedBackおよびQueryContinueDragは、D&Dのソース側でのイベントです。
ソース側で使うイベントなのですね。ありがとうございます。
引用返信 編集キー/
■72910 / inTopicNo.5)  Re[2]: WPFでファイルのドラッグ&ドロップ
□投稿者/ nobb (51回)-(2014/08/01(Fri) 09:36:43)
No72906 (とっちゃん さん) に返信
ご回答ありがとうございます。

> Debug.Print()で見ているようですが、デバッガで動きは追いかけてみましたか?
はい。一応今の簡素な形にする前に色々処理を含んだ状態でデバッガで追いかけていました。
そこで、e.Effectsに何を設定しても変わらなかったので、出来る限り簡素な形にし、
WPFから増えたPreview○○というイベントがよく分からなかったので、イベントの順序も知りたかったので今の形にしました。
イベントの流れという意味での「追いかけてみた?」はまだやっていません。

> 一応確認ですが。。。
> DragEnter など、Preview のつかないイベントを使っている理由は何でしょうか?
WPFでのドラッグ&ドロップは今までやった事がなかったので、WinFormsで行っていたDragEnterから始めてみました。
理由として言うならば「Winformsでそうやってたから」ですね。
Previewが付くものと、付かないものの違いがいまいち分かっていないので、そこも調べなければと思っています。

かずきさんのブログで、その辺りの説明、e.Handledに関する説明もあったので、
Previewはトンネルで、付かない方はバブルという「表面」はわかりましたが、
さて、それを使う場合はどの様な違いになるのか?という事までは理解できていません。
# バブルはなんとなくイメージできるのですが、トンネルがイメージ出来ません。ルートから下がるってどういうこと・・・
http://blogs.wankuma.com/kazuki/archive/2008/02/24/124598.aspx
引用返信 編集キー/
■72911 / inTopicNo.6)  Re[3]: WPFでファイルのドラッグ&ドロップ
□投稿者/ Hongliang (217回)-(2014/08/01(Fri) 10:36:27)
> PreviewDragOverに[e.Handled = true;]を設定することで期待する動作になりました。
> ただ、PreviewDragEnterの方に何を設定していてもカーソルに変化はみられませんでした。
> WinFormsの時はDragEnterイベントで変化させてましたが、これは変わったと考えていいのでしょうか?

http://msdn.microsoft.com/ja-jp/library/system.windows.dragdrop.dragenter.aspx
DragDrop.DragEnter添付イベントの解説に、Effectsに関する記述がありますね。
引用返信 編集キー/
■72917 / inTopicNo.7)  Re[4]: WPFでファイルのドラッグ&ドロップ
□投稿者/ nobb (52回)-(2014/08/01(Fri) 12:08:52)
No72911 (Hongliang さん) に返信
> http://msdn.microsoft.com/ja-jp/library/system.windows.dragdrop.dragenter.aspx
> DragDrop.DragEnter添付イベントの解説に、Effectsに関する記述がありますね。

URLの提示ありがとうございます。
そのページにはたどり着いていましたが、「完全に」読み落としていました。
DragEnterではなく、DragOverで対応します。



また、標題に関しては解決致しましたので、一応解決済みとさせていただきます。
解決済み
引用返信 編集キー/
■72918 / inTopicNo.8)  Re[3]: WPFでファイルのドラッグ&ドロップ
□投稿者/ とっちゃん (251回)-(2014/08/01(Fri) 13:12:04)
とっちゃん さんの Web サイト
No72910 (nobb さん) に返信
> ■No72906 (とっちゃん さん) に返信

<<順番変更>>
>>一応確認ですが。。。
>>DragEnter など、Preview のつかないイベントを使っている理由は何でしょうか?
> WPFでのドラッグ&ドロップは今までやった事がなかったので、WinFormsで行っていたDragEnterから始めてみました。
> 理由として言うならば「Winformsでそうやってたから」ですね。
> Previewが付くものと、付かないものの違いがいまいち分かっていないので、そこも調べなければと思っています。
>
Prewview がつかないイベント。。。じゃなくて、つくイベント。。。ですね。
自分が書いた内容が逆になってる...orz

ドラッグドロップで、ルーティングが不要というわけではありませんが、基本的には受け取りたいオブジェクトだけで
完結するので、Preview ではないほう(本来処理すべきオブジェクト自身)で、e.Handled = true をして
適切にメッセージを処理すればOKです。

>>Debug.Print()で見ているようですが、デバッガで動きは追いかけてみましたか?
> はい。一応今の簡素な形にする前に色々処理を含んだ状態でデバッガで追いかけていました。
> そこで、e.Effectsに何を設定しても変わらなかったので、出来る限り簡素な形にし、
> WPFから増えたPreview○○というイベントがよく分からなかったので、イベントの順序も知りたかったので今の形にしました。
> イベントの流れという意味での「追いかけてみた?」はまだやっていません。
>
こちらについては、Previewのつくイベントと、Previewのつかないイベントでそれぞれハンドラを用意して
通知メッセージを表示すると、どういう順番でなにがきているか?は判断しやすいかと。




> かずきさんのブログで、その辺りの説明、e.Handledに関する説明もあったので、
> Previewはトンネルで、付かない方はバブルという「表面」はわかりましたが、
> さて、それを使う場合はどの様な違いになるのか?という事までは理解できていません。
> # バブルはなんとなくイメージできるのですが、トンネルがイメージ出来ません。ルートから下がるってどういうこと・・・
> http://blogs.wankuma.com/kazuki/archive/2008/02/24/124598.aspx

WPFというか、XAMLのソースを見るとわかるように、ウィンドウなどのコンテントをツリー状に表現していますよね。

今回のウィンドウ構成なら、
Window
+Grid
++Border
+++Image

という親子関係になっていて、これがそのままツリー構造的に内部保持されます。
これが、要素ツリーと呼ばれる存在です。

このツリーのWindow(トップ、親とも呼ぶ)から、Image(子) に向かって進むイベントをトンネル(Previewのつくイベント)
逆にImageからWindowに向かって進むイベントをバブルと呼びます(Previewのつかないイベント)。

この辺り古くてもいいので、WPFの書籍などを見てみると結構詳しく解説されていますよ。
(むしろ最近の書籍のほうがあまり詳しくないかもしれない)


DragEnterについては、すでに Hongling さんから指摘が入ってるので割愛。

せっかく書いたので、解決済みになってるけど投稿w
解決済み
引用返信 編集キー/
■72920 / inTopicNo.9)  Re[4]: WPFでファイルのドラッグ&ドロップ
□投稿者/ nobb (53回)-(2014/08/01(Fri) 14:21:09)
No72918 (とっちゃん さん) に返信

> Prewview がつかないイベント。。。じゃなくて、つくイベント。。。ですね。
> 自分が書いた内容が逆になってる...orz
逆だったんですねw


> こちらについては、Previewのつくイベントと、Previewのつかないイベントでそれぞれハンドラを用意して
> 通知メッセージを表示すると、どういう順番でなにがきているか?は判断しやすいかと。
付かない方を使っていなかったのは完全な横着です。。すみません。
Previewってついてるからきっと直前に動いて、その後に発火するんでしょ?なら、そこの確認は後でいっか〜
なんて考えていました。


> WPFというか、XAMLのソースを見るとわかるように、ウィンドウなどのコンテントをツリー状に表現していますよね。
>
> 今回のウィンドウ構成なら、
> Window
> +Grid
> ++Border
> +++Image
>
> という親子関係になっていて、これがそのままツリー構造的に内部保持されます。
> これが、要素ツリーと呼ばれる存在です。
>
> このツリーのWindow(トップ、親とも呼ぶ)から、Image(子) に向かって進むイベントをトンネル(Previewのつくイベント)
> 逆にImageからWindowに向かって進むイベントをバブルと呼びます(Previewのつかないイベント)。

解説ありがとうございます。
バブルの方は、Imageで発火し、Border→Grid→Windowという形で登っていくと思いますが、
トンネルの方は、いきなりWindowが起点としてルーティングイベントが発火し、下に下っていくのでしょうか?
AllowDropを設定しているのはImageなのにWindowが起点というのがイマイチ飲み込めていません。。
#Imageで発火してWindowに戻って下る、なんていうのは違うと思うんですが・・・
引用返信 編集キー/
■72925 / inTopicNo.10)  Re[5]: WPFでファイルのドラッグ&ドロップ
□投稿者/ とっちゃん (252回)-(2014/08/01(Fri) 15:03:29)
とっちゃん さんの Web サイト
No72920 (nobb さん) に返信
> ■No72918 (とっちゃん さん) に返信
>
>>Prewview がつかないイベント。。。じゃなくて、つくイベント。。。ですね。
>>自分が書いた内容が逆になってる...orz
> 逆だったんですねw
>
はい。いろいろ書き直してる時に間違えちゃったみたいです><
申し訳ないです。


> 解説ありがとうございます。
> バブルの方は、Imageで発火し、Border→Grid→Windowという形で登っていくと思いますが、
> トンネルの方は、いきなりWindowが起点としてルーティングイベントが発火し、下に下っていくのでしょうか?
> AllowDropを設定しているのはImageなのにWindowが起点というのがイマイチ飲み込めていません。。
> #Imageで発火してWindowに戻って下る、なんていうのは違うと思うんですが・・・

ルーティング処理そのものは、AllowDropの存在にかかわらず行われます。
が、実際のハンドラ呼び出しを行うかどうかは、AlloDrop を見て判断されます。

通常のルーティング処理では、階層ごとにイベントハンドラをキックしろ!という通知を入れつつ
ぐるぐる回るだけなのに対し、
ドラッグドロップ周りだけは、上記のイベントハンドラをキックしろ!の部分が
if( AllowDrop ) イベントハンドラをキック
という形になっていると思えばよいと思います(疑似コードですらないですけどw)

引用返信 編集キー/
■72929 / inTopicNo.11)  Re[6]: WPFでファイルのドラッグ&ドロップ
□投稿者/ nobb (54回)-(2014/08/01(Fri) 16:31:28)
No72925 (とっちゃん さん) に返信
> はい。いろいろ書き直してる時に間違えちゃったみたいです><
> 申し訳ないです。
いえいえ!!謝らないでくださいな!!


> ルーティング処理そのものは、AllowDropの存在にかかわらず行われます。
> が、実際のハンドラ呼び出しを行うかどうかは、AlloDrop を見て判断されます。
>
> 通常のルーティング処理では、階層ごとにイベントハンドラをキックしろ!という通知を入れつつ
> ぐるぐる回るだけなのに対し、
> ドラッグドロップ周りだけは、上記のイベントハンドラをキックしろ!の部分が
> if( AllowDrop ) イベントハンドラをキック
> という形になっていると思えばよいと思います(疑似コードですらないですけどw)
D&Dだけは発火スイッチがもう一つあるようなイメージですね!

いつも長々お付き合い頂きありがとうございます!
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -