3

これは最も基本的な質問です.TragDropTargetで変更されたTreeViewコントロールの変更をどのように更新するのですか?DragDropTargetを使用したSilverlight TreeViewのObservableCollectionへの双方向データバインディング

ここに私の取り引きです:私は議題項目を保持するTreeViewを持っています。すべてが同じデータ型(WCFAgendaItem)であり、ChildItemsプロパティで表される子を持つ階層にロードされます。すべてがObservableCollectionにラップされ、MVVM Lightを使用してTreeViewにバインドされます。見ることができる素晴らしい作品です。また、ユーザーがドラッグアンドドロップを使用して、さまざまな他のソースからのこのアジェンダに新しいアイテムを並べ替え、再編成し、追加することもできるようにしたいとします(イメージスライドのListViewなど)。一貫性と簡単なシリアライゼーションのために、すべての新しい項目も同じデータ型のWCFAgendaItemを持ちます。

私の問題です:ドラッグアンドドロップは、ツールキットのドラッグドロップ機能を使用してUI上で美しく動作します。しかし、私はViewModelにTreeViewの内容の変更を理解させる方法を知りません。図から

コード(Agenda.xaml):

<controlsToolkit:TreeViewDragDropTarget Grid.Row="1" Grid.Column="0" x:Name="ddtAgenda" AllowDrop="True" 
              HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" > 
     <sdk:TreeView Width="375" ScrollViewer.HorizontalScrollBarVisibility="Auto" 
         ScrollViewer.VerticalScrollBarVisibility="Visible" ItemsSource="{Binding DailyAgenda, Mode=TwoWay}" ItemTemplate="{StaticResource hdtAgenda}"> 
     </sdk:TreeView> 
    </controlsToolkit:TreeViewDragDropTarget> 

ビューモデルコード(AgendaViewModel.cs)(後に)

<UserControl.Resources> 
    <AHHSTeam_SLClassroomManagerMVVM_Helpers_Converters:BooleanVisibilityConverter x:Key="BooleanVisibilityConverter"/> 
    <sdk:HierarchicalDataTemplate x:Key="hdtAgenda" ItemsSource="{Binding ChildItems, Mode=TwoWay}" > 
     <Grid HorizontalAlignment="Left"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="{Binding ImageThumbnailWidth}" /> 
       <ColumnDefinition Width="250" /> 
      </Grid.ColumnDefinitions> 
      <Image Grid.Column="0" Source="{Binding ThumbnailURL}" Width="{Binding ImageThumbnailWidth}" Height="{Binding ImageThumbnailHeight}" Visibility="{Binding HasImage, Converter={StaticResource BooleanVisibilityConverter}}" > 
       <ToolTipService.ToolTip> 
        <Image Source="{Binding ResizedImageURL}" /> 
       </ToolTipService.ToolTip> 
      </Image> 
      <TextBlock Grid.Column="1" Text="{Binding Title}" TextWrapping="Wrap" /> 
     </Grid> 
    </sdk:HierarchicalDataTemplate> 
    <Style TargetType="sdk:TreeViewItem" > 
     <Setter Property="IsExpanded" Value="True" /> 
    </Style> 
</UserControl.Resources> 

(トップアップ) - >私はCollectionChangedを聞いてみましたが、それまでは動作していないようです。

(コンストラクタ内)

  //add notification of agenda changes 
      DailyAgenda.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(DailyAgenda_CollectionChanged); 

モデルから(イベント)

void DailyAgenda_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     System.Windows.MessageBox.Show("Daily agenda updated, now has " + e.NewItems.Count.ToString() + " top-level elements."); 
    } 

コード(WCFAgendaItem.cs)

[ContentProperty("ChildItems")] 
public partial class WCFAgendaItem: INotifyPropertyChanged 
{ 
    private ObservableCollection<WCFAgendaItem> _childItems = new ObservableCollection<WCFAgendaItem>(); 

    public ObservableCollection<WCFAgendaItem> ChildItems 
    { 
     get 
     { 
      return _childItems; 
     } 
     set 
     { 
      _childItems = value; 
     } 
    } 
... 

私がて、CollectionChangedのリスニングはどのような場合には適切ではないことを得ることはかなり確信していますこのデータが最上位レベルで変化するだけではないことを考えると、私はBlend(MVVM Light、覚えています)のEventToCommandを見ましたが、TreeView固有のイベントはSelectionChangedのように見えますが、これはどちらかとは思われません。私は、TreeViewDragDropTargetにEventToCommandトリガーを置くことを見ましたが、UIのやりとりの仕方をオーバーライドする方法ではありませんか?私は、WCFAgendaItemのINotifyPropertyChangedがこれに当てはまるとは思わない:アイテムのタイトルを編集するために後でそれを必要としているが、アイテムが移動したときに役立つようには見えない。

多分私が探しているのはストレッチですが、私が実際にやりたいことは、Silverlightがデータ結合がWCFAgendaItemコレクションの順序と内容の両方で動作し、すべてのコレクションの再加工を行うことを理解することですUIインタラクションに基づいています。コレクションが修正された後、更新イベントを聞くことができます。その後、TreeViewにバインドされた変更されたObservableCollectionをクロールし、WCFを介してフラット化/シリアル化/更新することができます。

理想的な状況にならない:必要に応じて、私はTreeViewItemsをクロールするつもりですが、それを実行する必要がある場合でも、いつ行うかは固まっています。私はコードを書いていないので、ViewModelにすべて戻す方法が必要です。 Drop()にアタッチして、ドロップロジックを修正する必要がありますか?私はツールキットから始まるカスタムドラッグドロップの実装に関するいくつかの古い記事を見つけましたが、特にMVVMの状況で、修正されたツリービューを保存する方法については誰も言及していません。

ついに{

これをタイプしながらそれはViewModelににかなりの量の作業だけれども、私は、有用である可能性がthis articleを見つけました。これは有望で、私は調査するつもりですが、私はまだ簡単なことを望んでいます。また、記事が書かれてから、Toolkitイベントが少し変わったように見えます。

答えて

0

このタイプのDragDrop機能を実装する際に問題が発生しました。根本的な原因は、ItemDragCompletedイベント(EventHandler)もItemDroppedOnSource(DragEventHandler)も、アイテムがドロップされたときのインデックスを渡していないようです。

私が保護されたメソッドを公開するためにDragDropTargetをサブクラス化することになった:

int GetDropTargetInsertionIndex(TItemsControlType dropTarget, DragEventArgs args) 

私は、基礎となるコレクションにに指定されたインデックスの項目を挿入するための責任を負うために添付ビヘイビアを使用。

基本的なコードがStackOverflowの回答に(あまりにも広範なデカップリングのために)含まれているのは広すぎるのですが、それはブログの主題リストにあります。その間、上記の情報が役立つことを願っています。それは確かに私にとって解決策の鍵でした。

イアン

関連する問題