locked
TreeView で並べ替えた結果を記録するには? RRS feed

  • 質問

  • Silverlight Toolkit を使うと、
    TreeView で Item の並べ替えを行えることは確認しました。
     
    では、
    並べ替えた結果をデータベースに記録したいのですが、
    Silverlight ではどう行うのでしょう?
     
    Item の Drop 時に何かしらの処理が必要だと思うのですが、
    Silverlight の良い事例が見つかりません。
     
     
     
     
     
     
    <UserControl x:Class="dragdrop._2.treeview.MainPage"
       xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"  ...>
       <Grid x:Name="LayoutRoot" Background="White">
          ...
          <toolkit:TreeViewDragDropTarget AllowDrop="True" ...>
             <sdk:TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource NameTemplate}" ... />
          </toolkit:TreeViewDragDropTarget>
       </Grid>
    </UserControl>
    こんな風に書いて
     
     

    こんな TreeView を用意し
     
     

    Item を Drag して並べ替え
     
     

    この並びをデータベースに保存したい。
     
     
     
    参考 (どれも古い)

    • 編集済み custar 2011年12月31日 13:22
    2011年12月31日 13:03

回答

  • SilverlightにはSilverlightのお作法というか、考え方みたいなのが根底にあって、
    UI側で要素を取得して(この場合はdrop先を取得して)弄くるみたいなことは推奨せずに
    DataContextの変化を観測するような作りになっているんだと思います。
    その辺ご理解されるとスムーズにいけるんじゃないでしょうか。

    具体的に今回の要件で言うと、

    >Item を Drag して並べ替え

    した時点でTreeView.ItemsSourceの階層構造が変わっていますので

    >この並びをデータベースに保存したい。

    のであればそのままItemsSourceの構造をデータベースに保存すれば良いです。
    • 回答の候補に設定 山本春海 2012年1月24日 7:37
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月4日 16:40
  • Silverlightというか、Xamlを使用する環境全般ですが
    MVVM(Model-View-ViewModel)パターンという設計パターンを採用していることが多いです。

    Xamlの持つデータバインディング機構とCommandパターンをフル活用して
    できるだけViewに依存しないようにしようする(というか各層がなるべく疎結合であろうとする)パターンです。

    Introduction to Model/View/ViewModel pattern for building WPF apps - Tales from the Smart Client - Site Home - MSDN Blogs

    このあたりが初出っぽいですが、昔のことはあまり詳しくないので興味があれば調べてみてください。

    Silverlightに沿った解説だと、

    MVVMによるSilverlightアプリケーションの開発:CodeZine

    実例で学ぶアプリケーション開発 MVVM 編 | Visual Studio 2010 ソリューション サンプル | MSDN
    等が、とっかかりとしては分かり易いかなと思います。

    「TreeViewはどうすんだ?」
    とか、そこまで細かいことまで載ってる資料は無いので
    基本の考え方を学んで各自応用していく・・・みたいな感じで。

    ご参考までに。
    ☆TFC Software http://www.tfc-software.com/
    ☆プログラミングに関するブログ http://www.tfc-software.com/Blogs.aspx
    • 回答の候補に設定 山本春海 2012年1月24日 7:38
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月6日 14:24
  • Uchida さん:

    >Item を Drag して並べ替え
    した時点で TreeView.ItemsSource の階層構造が変わっています
    かずき_okazuki さん:

    Drag & Dropで並び替えを確認したところ、
    ちゃんと見た目だけでなくコレクション内のデータの並びも更新されていた
    お二人の仰っていること、こちらでも確認できました。
     
    TreeViewDragDropTarget の Event
    Drop では変化は見られませんでしたが、
    ItemDragCompleted で確認取れました。
     
    なるほど。有り難うございました。
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月8日 16:57

すべての返信

  • Drag している Item は取得できるのだが、
    何処に挿入しようとしているのか取得できなかった。
     
    以下によると、
    Drop 先 (destination) を特定できない、と言っている。
     
     
     
    こんなの javascript のライブラリでは当たり前の事なのに、
    なんでこんな不十分な状態でリリースしてるんだ?
    2012年1月3日 4:02
  • SilverlightにはSilverlightのお作法というか、考え方みたいなのが根底にあって、
    UI側で要素を取得して(この場合はdrop先を取得して)弄くるみたいなことは推奨せずに
    DataContextの変化を観測するような作りになっているんだと思います。
    その辺ご理解されるとスムーズにいけるんじゃないでしょうか。

    具体的に今回の要件で言うと、

    >Item を Drag して並べ替え

    した時点でTreeView.ItemsSourceの階層構造が変わっていますので

    >この並びをデータベースに保存したい。

    のであればそのままItemsSourceの構造をデータベースに保存すれば良いです。
    • 回答の候補に設定 山本春海 2012年1月24日 7:37
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月4日 16:40
  • UI側で要素を取得して(この場合はdrop先を取得して)弄くるみたいなことは推奨せず
    へぇ、そんなんですか。
     
    そうとは知らず、
    以下の方法で destination を特定できるな、と試している処でした。
     
     
    private void TreeViewDragDropTarget_Drop(object sender, DragEventArgs e)
    {
       SelectionCollection selections
          = ((ItemDragEventArgs)e.Data.GetData("System.Windows.Controls.ItemDragEventArgs")).Data
          as SelectionCollection;
    
       if (selections != null)
       {
          Point pos = e.GetPosition(this.LayoutRoot);
          var elements = VisualTreeHelper.FindElementsInHostCoordinates(pos, this.LayoutRoot);
          var items = from el in elements
                     where el is TreeViewItem
                     select el;
          ...
       }
    }
    

    2012年1月4日 17:21
  • >Item を Drag して並べ替え

    した時点でTreeView.ItemsSourceの階層構造が変わっていますので

    >この並びをデータベースに保存したい。

    のであればそのままItemsSourceの構造をデータベースに保存すれば良いです。
    本当ですか!?
    確かめてみます。
     
    取ってきたデータを ObservableCollection に収めて、
    変化のある毎に何かしらコードを書かなきゃならないのかな?
    と面倒臭げに考えていた処でした。
    2012年1月4日 17:29
  • SilverlightにはSilverlightのお作法というか、考え方みたいなのが根底にあって、
    その「考え方」とは何というのでしょうか?
    何か名前がありますか?
     
    また、
    その辺の事を身に付けるには何が良いのでしょうか?
    何かお薦めはありますか?

    • 編集済み custar 2012年1月6日 9:57
    2012年1月6日 9:57
  • Silverlightというか、Xamlを使用する環境全般ですが
    MVVM(Model-View-ViewModel)パターンという設計パターンを採用していることが多いです。

    Xamlの持つデータバインディング機構とCommandパターンをフル活用して
    できるだけViewに依存しないようにしようする(というか各層がなるべく疎結合であろうとする)パターンです。

    Introduction to Model/View/ViewModel pattern for building WPF apps - Tales from the Smart Client - Site Home - MSDN Blogs

    このあたりが初出っぽいですが、昔のことはあまり詳しくないので興味があれば調べてみてください。

    Silverlightに沿った解説だと、

    MVVMによるSilverlightアプリケーションの開発:CodeZine

    実例で学ぶアプリケーション開発 MVVM 編 | Visual Studio 2010 ソリューション サンプル | MSDN
    等が、とっかかりとしては分かり易いかなと思います。

    「TreeViewはどうすんだ?」
    とか、そこまで細かいことまで載ってる資料は無いので
    基本の考え方を学んで各自応用していく・・・みたいな感じで。

    ご参考までに。
    ☆TFC Software http://www.tfc-software.com/
    ☆プログラミングに関するブログ http://www.tfc-software.com/Blogs.aspx
    • 回答の候補に設定 山本春海 2012年1月24日 7:38
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月6日 14:24
  • Uchida さん、情報有り難うございます。
     
    MVVM(Model-View-ViewModel)パターンという設計パターン
    あぁ、やっぱりそういうことですね。
     
    もしかしたらそっちの話になるのかな、と思っていたので、
    昨日 RSS で更新された MSDN の中に以下の記事があったので読んていました。
    まだ MVVM の記事は読んだことありません。
     
     
    言葉だけが宙を舞い、何の話か全く頭に残りませんでしたが。
     
    「TreeViewはどうすんだ?」とか、
    そこまで細かいことまで載ってる資料は無いので
    基本の考え方を学んで各自応用していく・・・みたいな感じで。
    めげずに読んでみます。
     
     
    MVVM に関して読み始める前に持っている疑問は、
    取ってきたデータを ObservableCollection に収めて、
    変化のある毎に何かしらコードを書かなきゃならないのかな?
    と面倒臭げに考えていた
    という処にも少し含ませていまして、
    実際 IDE を使っている時に、
    今自分は何処を実装しているのか把握しにくいと感じています。
     
    MSDN を読みながらその通りやっているが、
    MVVM のどの部分を書いてるのかな?
    何処までを IDE が分担してくれているのかな?
    とよく分かっていないことが多々あります。
     
    上記 ObservableCollection の話では、
    ObservableCollection の特徴が MDSN に載っていますから、
    それを使った方が良いのかもしれませんが、
    もしかして、xaml でのバインディング時に既に IDE が内部でそうしてくれているのか?
    と疑問がよく浮かびます。
     
     
    IDE の silverlight アプリケーションのテンプレートを使い、
    IDE 上の仕組みを使って Control を配置したり、
    必要な所で Code Behind を追加したりすれば、
    そのアプリケーションは勝手に MVVM 的な構造になってるのかな?
    とか、
    LightSwitch を使うと
    深く考えなくても MVVM 的な構造になっているのかな?
    と考えてしまいますが、そうではないのですかね?



    • 編集済み custar 2012年1月7日 6:33
    2012年1月6日 19:04
  • IDEつかってドラッグアンドドロップしてコードビハインド書いてと無意識にやってたらMVVMパターンにはならないことのほうが多いと思います。

    TreeViewは、こちらで確認したところDrag & Dropで並び替えを確認したところ、ちゃんと見た目だけでなくコレクション内のデータの並びも更新されていたのですが、そちらの話は解決っぽいですか?


    かずき Blog:http://d.hatena.ne.jp/okazuki/ VS 2010のデザイナでBlendのBehaviorをサポートするツール公開してます。 http://vsbehaviorsupport.codeplex.com/
    2012年1月7日 13:51
  • IDEつかってドラッグアンドドロップしてコードビハインド書いてと無意識にやってたら 
    MVVMパターンにはならないことのほうが多いと思います。
    やはりそうですよね。
     
    TreeViewは、こちらで確認したところDrag & Dropで並び替えを確認したところ、
    ちゃんと見た目だけでなくコレクション内のデータの並びも更新されていたのですが、
    そちらの話は解決っぽいですか?
    いえ、未だです。

    先の返事を書いてた時、
    風邪引いて寝込んでたので未だ取り掛かれていません。
    未だ寝込んでます。

    • 編集済み custar 2012年1月7日 22:42
    2012年1月7日 22:42
  • Uchida さん:

    >Item を Drag して並べ替え
    した時点で TreeView.ItemsSource の階層構造が変わっています
    かずき_okazuki さん:

    Drag & Dropで並び替えを確認したところ、
    ちゃんと見た目だけでなくコレクション内のデータの並びも更新されていた
    お二人の仰っていること、こちらでも確認できました。
     
    TreeViewDragDropTarget の Event
    Drop では変化は見られませんでしたが、
    ItemDragCompleted で確認取れました。
     
    なるほど。有り難うございました。
    • 回答としてマーク 山本春海 2012年1月27日 8:21
    2012年1月8日 16:57