創造的プログラミングと粘土細工プログラミング関連Blog私の興味の端から端までをお届けします!【免責事項】このサイトの情報は私の個人的な見解で、私以外の意見を代弁するものではありません。【NetOffice】【WPF】ドラッグアンドドロップでExcelを起動する。ProjectWPFアプリケーションの所定の箇所にExcelファイルをドラッグアンドドロップすることで、Excelアプリケーションを起動し、ブックを開く方法を紹介します。Excel</Label></Grid></Window>今回はラベルコントロールにExcelファイルをドロップできるようにします。Label.AllowDropの属性をtrueにすることで、ドロップできるようになります。ドロップ時のハンドリングを行うために、Dropイベントを設定します。});}}DragEventArgsからDataFormats.Filedropを指定してGetDataメソッドを呼び出すと、ドロップしたファイルのパスがstringの配列で取得できます。今回は、ファイルが存在する事と拡張子が.xlsまたはxlsxになっているかどうかで、そのファイルがExcelファイルであるかどうかの判定を行っています。Excelファイルであると判定されたファイルはExcelブックとして開きます。今回は、ブックを開くだけにとどめていますが、シートのデータを読み取ったり、シートに何か書き込んだり、チェックしたり応用技は色々ありそうです。ドラッグアンドドロップだけではなく、起動中のExcelにアタッチして何かすると言うこともできます。tmp;}}}たとえばクリックしたTreeViewItem内のTextBlockなどを指定して、トップにあるTreeViewとTextBlockを渡すと。TextBlockの親に存在するTreeViewItemを見つけ出し、さらにその親のTreeViewItemを見つけるという振る舞いをする。tmp;}}}参考http://pro.art55.jp/?eid=1033030VisualTreeHelperを利用して探す方法はhttp://pro.art55.jp/?eid=1303998のサンプルコードに記述してます。Tweet0WPFcomments(0)trackbacks(0)【WPF】TreeViewのアイテムをドラッグアンドドロップをするには(5)TreeView.ItemsSourceに代入するオブジェクトを考えなおす。意外にまれなケースで実際には違うことが多いのかなって思った。Frameworkにあるクラスやらそういうのがあると、ちと話がややこしくなってくるね。基本的には"Value"というプロパティ名を保障しておけば、ダックタイピング的にはOKなはずなので、そういう方向で修正できないかちとかんがえてみよ。今日は眠いでおしまい。Tweet0WPFcomments(2)trackbacks(0)【WPF】TreeViewのアイテムをドラッグアンドドロップをするには(5)TreeView.ItemsSourceに代入するオブジェクトを考える。Projectなかなかドラッグアンドドロップにたどり着けない訳ですが、今回もドラッグアンドドロップとは関係ありません。前々回あたりに書いたとおり、私はさくっとサンプルコードがかけるレベルではなく、TreeViewには不慣れです。今回もTreeViewの基礎的な事を知ったかぶりさせていただきます。いうことで、今回は、ItemsControl系のコントロールでの定石であるItemsSource経由でのデータ表示について考えたいと思います。TreeViewは、ListBox、ListView、DataGridなどと違い階層に構造になっており、ItemsSourceに代入するオブジェクトも階層構造になっている必要がります。そのあたりがちょっぴり難易度があがってしまう原因になってしまいます。ポイントを簡単にまとめると下記のことを開発者はしなければなりません。TreeView.ItemsSourceプロパティに代入するクラスを自作する。TreeView.ItemTemplateプロパティに代入するDateTemplateを自作する。}}TreeViewNode<T>クラスはヘッダー情報と、それに付随するコンテンツのコレクションを持つクラスとなります。子供のコレクションが追加や削除が起こる場合は、変更通知をサポートするObservableCollection<TreeViewNode<T>>にしておくと良いでしょう。ドラッグアンドドロップをサポートする場合は、コレクションの変更通知は必須となるので、注意が必要です。コレクション自体を入れ替えて、INotifyPropertyChanged経由で変更通知するのもありかもしれませんが・・・Childrenがnullである状態を許すようなクラスは個人的にはお勧めしません(笑)上記のクラスは、使ってみると分かると思いますが、非常に使いにくいです。一つはトップレベルのコレクションをどうするかという問題が発生します。Addがサポートされていないため、サンプルコードなどを記述したい場合、ツリーを構築するのが面倒になります。いうことで、ちょっと改造してみます。}}}IListSourceを継承することにより、トップレベルからTreeViewNodeを利用できようにしてみました。WPFではIListSource継承することにより、コレクションクラスでないものに対してもBindingオブジェクトを通じて、それをコレクションと見なすような挙動をしてしてくれるようになります。一つがIEnumerable<TreeViewNode<T>>を継承させる事です。IEnumerable<TreeViewNode<T>>を継承させて、Addメソッドをサポートしたいので、継承させてみました。(追記:IListSourceを継承せず、IEnumerable<TreeViewNode<T>>のみを継承させた場合、コレクションがIEnumerable<TreeViewNode<T>>で実現できることしか実現できなくなってしまいます。ObservableCollection<TreeViewNode<T>>がコレクションの本体であった場合でもコレクションの変更通知がサポートされなくなってしまいます。)実際に使ってみると、サンプルデータを作るにはとっても便利になります(笑)IListSourceをサポートしているためトップのコレクションもTreeViewNodeで記述できます。Addメソッドがサポートされているため、外延表現でリストの初期化が可能となります。source;さらにサンプルデータを記述するという観点だけで話を広げると、上記のTreeViewNode<T>クラスをXAMLで記述しインスタンスを作成する事もできます。下記のように記述できます。/></HierarchicalDataTemplate></TreeView.ItemTemplate></TreeView></Grid></Window>上記をみると分かると思いますが、ListViewNode<T>をTreeViewコントロールに適用する場合、TreeViewコントロール自身は、どのオブジェクトがコレクションになたるのか、どのオブジェクトがヘッダーになるのか分からないため、ItemTemplateを自作する必要があります。/></HierarchicalDataTemplate>今回用意したサンプルデータだと上記のように記述することでツリー表示が可能となります。このあたりがListBoxやDataGridとはかなり違うところで私自身ふなれなところです。TreeViewNodeの話に戻します。今回、用意したTreeViewNodeクラスはヘッダーとコレクションの情報を保持するクラスでした。考え方を変えて、ヘッダー情報付きコレクションと考えてみてはどうでしょうか。書き換えるとこうなります。}}継承よりコンポジットに方が世の中うまく回ることが多いですが、あえてこのようなクラスにしてしまうというのもありかもしれません。この場合は「ヘッダー情報付きコレクションクラス」です。こちらの方がXAMLで記述した場合すっきりします。}}「ヘッダーと子供のコレクションを管理するノードクラス」か「ヘッダー付きコレクションクラス」と見るか、どちらが良いかのか私には判断できるほどの経験がないので結論を出せませんが、まあ色々試してみると面白いと思います(笑)ちなみにValueに対して変更通知をサポートしたいのであれば、INotifyPropertyChangedを継承する必要があります。ObservableCollection<TreeViewNode<T>>を継承したかたちでは、ObservableCollection<TreeViewNode<T>>自身がINotifyPropertyChangedから派生しているので、OnPropertyChangedメソッドを継承元から呼び出すことができます。コーディング量が減るというメリットが得られるだけです・・・一応書いておきました。Sunday05:10TreeViewコントロールを利用することでツリー構造をもつ対象をヴィジュアル的にツリー表示することが可能となります。TreeViewは内部的にはTreeViewItemのコレクションを包含しています。System.Windows.Controls.TreeViewItemは、System.Windows.Controls.HeaderedItemsControlから派生している事から、TreeViewItemはヘッダー付きItemsControlといえます。TreeViewItemは、一つのヘッダーに対して、子供としてのコレクションが存在し、その子供のコレクションの要素もまたTreeViewItemとなり、TreeViewItemの親子な関係が構築できます。TreeViewコントロールをXAMLで宣言的に記述すると下記のようにかけます。/></TreeViewItem></TreeViewItem></TreeView>上記を見れば分かると思いますが、TreeViewの内部に複数のTreeViewItemが存在し、TreeViewItemの内部にも、複数のTreeViewItemが構築できます。Sunday04:07この連日の投稿以外では、当ブログでTreeViewコントロールの話題を扱ったことがありません。個人的にはTreeViewコントロールというのは嫌いです。理由の一つはアホなSEがTreeViewを使えば問題解決できると思ってるからです。それに関してはこれ以上触れませんが(笑)ほかの理由としては、TreeViewコントロールは、アプリケーション提供者が恣意的に分類した構造をユーザに無理強いしてしまう恐れがあるからです。Cドライブ直下にあるディレクリ構造。これはユーザにそう見せたくて、あのような構造になっているでしょうか?もちろんそんな訳がなく、一般ユーザから見れば、自分の目当てのファイルを探しにくい構造になっています。Windowsのディレクトリ構造はバージョンによって多少異なりますが、同じバージョンであれば変更なく、ユーザが十分に学習していく時間があるので、ツリー表示しても、そのうち問題にならなくなる可能性があります。一つ例をあげるとURLに使われているDNS(www.google.jpなど)もし仮にエッチなサイトを検索したと思い、誰かに頼んでエッチなサイト検索アプリケーションを作ってもらったとします。このアプリケーションはDNSをドット区切りで右からツリー表示して、表示していたとします。DNSの分類からエッチなサイトを見つけようとしても、最終的にそのWebサイトを見なければ目的のサイトかどうか分かりません。これは完全に分類方法とユーザが何をしたかったのかという事に対する解がミスマッチです。ここまでひどい例はないと思いますが、案外よくあることです。ツリー表示というのは、多角的な知見が存在するものに対して恣意的に分類を選択されてしまうというのは否めません。目的に対してベストチョイスするというのは案外難しいと思います。そもそも分類してしまうということが、自体がデメリットになってしまうこともあるでしょう。いうことで自分が作成しているアプリケーションにメニュー表示以外でツリー表示したことがありません。そもそもアホな人が分類方法も提供せずにTreeViewを使って!って言ってくるので、全力で反対せざるをえません。ちなみに一階層のグループ化は時々使っています。ユーザが必要な時にグループ化できるというのはユーザビリティ的に優れていると思います。Project今回は「System.Windows.DragDropクラス」を利用したドラックアンドドロップの基本を解説します。ポイントは下記の通りです。1.ユーザが行ったジェスチャーをドラッグと判定する。2.DragDrop.DoDragDropメソッドでドラッグが開始したことをコンピュータに通知する。3.ドロップが可能なコントロールにAllowDropをTrueに設定しておく。4.ドロップされた後の挙動をハンドリングする。サンプルコードで上記のポイントの実装部分を解説します。1.ユーザが行ったジェスチャーをドラッグと判定する。今回のサンプルコードでは、青色のLabelコントロールでマウスの左ボタンが押されたら、一律ドラッグが開始されたと判定することにしました。DragDropEffects.Move);}今回はマウスの左ボタンダウンが、ドラッグ開始のジェスチャーであるとしたので、ラベル上でマウスダウン以外の判定は行っていませんが、必要であればマウスがダウンされてマウスをダウンしたまま何ピクセル移動すればドラッグだとか、もっと細かく判定することも可能です。バブリングやトンネリングのイベントの伝搬を利用すれば、複数コントロールを一括して同じイベントハンドラで処理することもできます。その時はドラッグ対象のコントロールかどうかをしっかり判定する必要があります。2.DragDrop.DoDragDropメソッドでドラッグが開始したことをコンピュータに通知する。ドラッグは、WPFの場合、マウスをクリックした状態で移動させてもドラッグしているとコンピュータは見なしません。マウスをクリックした状態で移動させるというジェスチャーが行われたと判定されたら、DragDrop.DoDragDropメソッドでドラッグ開始された事を通知する必要があります。することではじめてドラッグ関連のイベントは、発砲する事になります。ちなみにドラッグアンドドロップ関連のイベントは各コントロールに存在し、また、DragDropクラスの添付イベントとして存在しているので確認することをお勧めします。DragDropEffects.Move);}サンプルコードでは、マウスの左ボタンをクリックしたタイミングでDragDrop.DoDragDropメソッドを呼び出しています。注目すべきは第二引数です。オブジェクトはドロップ時に取得することが可能です。渡したい情報を設定することをお勧めします。3.ドロップが可能なコントロールにAllowDropをTrueに設定しておく。ドロップが可能な領域にAllowDropをTrueに設定する必要があります。どのタイミング設定するかという事は意外に重要です。常にTrueにしておきたいのであればXAMLで設定すると実現できますが、常にTrueである場合、特定のドラッグ元からしかドロップを受け付けたくない場合などの要求があった場合には問題となります。その場合は、ドラッグが開始されるタイミングの直前までに何らかのかたちでAllowDropを制御する必要があります。今回のサンプルコードはXAMLで常にTrueを設定しています。...AllowDrop="True"Drop="OnDrop"...></Label>試しにこのアプリケーションを実行し、デスクトップにあるアイコンをドラッグさせて、赤いラベルにドラッグしてみてください。ドロップできるような見た目になると思います。4.ドロップされた後の挙動をハンドリングする。ドロップされた後の挙動をハンドリングするには、ドロップしたい対象のDropイベントをハンドリングする必要があります。ドラッグ開始時と同様、バブリング/トンネリングで複数コントロールを一括してハンドリングする事もできます。複数コントロールに同じハンドラを設定する事でも実現できます。今回のサンプルコードではドロップ可能なラベルコントロールにDropイベントをハンドリングしています。オブジェクトを取り出すことができます。オブジェクトが組み込まれており、たとえばデスクトップからドラッグアンドドロップさせた場合、ドラッグさせたファイルパスを受け取ったりすることもできます。今回は、受け取った文字列をドロップしたラベルコントロールに設定しています。以上が、ドラッグアンドドロップの簡単な実装です。応用力をつけたいのであれば、DragDrop.DoDragDropメソッドやDragEventArgsの詳細を調べたりDragDropの各添付イベントの調べたりすると良いでしょう。Saturday04:34JUGEMテーマ:コンピュータWPFでドラッグアンドドロップしたいという質問をBlogで何度も質問を受けているので、ちゃんと説明しようと思い立ちました。TreeView内のアイテムをドラッグアンドドロップさせるにはどうすれば良いのかというところを最終的に理解できる内容にしたいと思います。今回は、そもそもドラッグアンドドロップを実現するにはどういう方法があるのかという事を解説したいと思います。WPFでドラッグアンドドロップでするにはいくつかの方法が考えられます。1.System.Windows.DragDropクラスを利用する。2.System.Windows.Controls.Primitives.Thumbコントロールを利用する。SDKのMouseDragElementBehaviorを利用しコントロールの座標を変更する。2と3はドロップというアクションが明示的なものではなく、ドラッグさせるという事が主な目的になります。それに対して1はドラッグとドロップのアクションがイベントとして連動するので、比較的簡単にドラッグアンドドロップが実現できると思います。SDKを利用したことがない方は一度自分でコードを書いてみて、動かしてみるとイメージがつくと思います。自分が実現したいことが、単にコントロールを動かしたいだけでドラッグアンドドロップじゃなかったなど、勘違いに気づけるかもしれません。Thumbを利用したサンプルコードhttp://pro.art55.jp/?eid=1181623http://pro.art55.jp/?eid=1181572MouseDragElementBehaviorを利用したサンプルコードhttp://pro.art55.jp/?eid=1303847System.Windows.DragDropクラスに関しても過去に何度も投稿していますがあえて新しく投稿してみようと思います。ProjectTreeViewコントロール上でドラッグアンドドロップを実現したサンプルコードをアップしてきます。要素技術が広範囲にわたるため、今回の投稿では解説はしません。ある程度の粒度でわかりやすく解説できる自信とこころに余裕があれば実現したいと思います。entries【NetOffice】【WPF】ドラッグアンドドロップでExcelを起動する。(08/09)【WPF】TreeViewのアイテムをドラッグアンドドロップをするには(5)TreeView.ItemsSourceに代入するオブジェクトを考えなおす。(08/07)【WPF】TreeViewのアイテムをドラッグアンドドロップをするには(5)TreeView.ItemsSourceに代入するオブジェクトを考える。IListがIReadOnlyListを継承してない理由。IListがIReadOnlyListを継承してない理由。IListがIReadOnlyListを継承してない理由。IListがIReadOnlyListを継承してない理由。(02/22)【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。(01/16)【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。(01/16)【NetOffice】【Excel】死なないExcelプロセスをKillする。trackback【.NET】Installerを継承してWindowsサービスをインストールする際に引数を指定。(05/26)【雑記】オラクル、サンを買収。(12/07)【WPF】ListBoxやListViewの行番号を出力する。図があってとてもわかりやすい。伸光とてもわかりやすいです。忠男4章がリレーショナルデータベースな内容になってます。ページ数があまりありませんが、ポイントがものすごく的確にまとまっていて、感動します。»)テンキーレス、静音のRealForce91UBK-S。スコスコ感がたまらなく気持ちいいです。家と会社で2台持ってます。2013年10月10日。Frameworkとお付き合いする人のバイブルですね。»)recommendキャット・シッターの君に。私のイラストレータデビュー本です。