3

下面是最基本的問題:我如何偵聽通過DragDropTarget修改的TreeView控件中更改內容的更新?使用DragDropTarget對Silverlight TreeView上的ObservableCollection進行雙向數據綁定

所以這裏是我的交易:我有一個TreeView持有議程項目。所有的數據類型都是相同的(WCFAgendaItem),並且被加載到一個層次結構中,子層表示爲屬性ChildItems。整個事情被封裝在一個ObservableCollection中,並使用MVVM Light綁定到TreeView。非常適合查看。我還希望用戶能夠使用拖放來重新排序,重新組織和添加來自各種其他來源(例如圖像幻燈片的ListView)的此議程的新項目。爲了一致性和簡單的序列化,所有新項目也將具有相同的WCFAgendaItem數據類型。

這是我的問題:使用工具包的拖放功能,拖放功能可以在UI上精美地工作。但我不知道如何讓ViewModel瞭解TreeView內容的變化。

從視圖代碼(Agenda.xaml):

(向上頂)

<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> 

(稍後)

<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) - >我試着收聽CollectionChanged,到目前爲止似乎沒有工作

(在構造函數中)

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

(事件)從模型(WCFAgendaItem.cs)

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."); 
    } 

代碼

[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中的EventToCommand(記住MVVM Light),但是唯一的TreeView特定的事件看起來像是SelectionChanged,看起來也不錯。我研究了在TreeViewDragDropTarget上放置EventToCommand觸發器,但是不是那些覆蓋UI交互發生的方法嗎?我不認爲WCFAgendaItem上的INotifyPropertyChanged適合這種情況:儘管稍後我會希望用它來編輯項目標題,但當項目移動時,它似乎不會幫助我。

也許我在尋找的是一種延伸,但我真正想要發生的是讓Silverlight理解數據綁定對WCFAgendaItem集合的排序和內容都起作用,並且執行所有集合重構本身基於UI交互。然後我可以在集合被重寫之後監聽更新事件 - 之後,我可以將修改的ObservableCollection綁定到TreeView,並通過WCF對其進行平鋪/序列化/更新。

失敗的理想情況:我願意抓取TreeViewItems,如果需要的話,但即使這就是我需要做的事情,我堅持什麼時候去做。另外我需要一種方法將所有返回給ViewModel,所以我不寫代碼。我是否需要附加到Drop()並重寫刪除邏輯?我發現了幾篇關於從Toolkit開始的自定義拖放實現的舊文章,但沒有人提到如何將修改過的TreeView保存出來,尤其是在MVVM情況下。

終於{

雖然打字了這一點,我發現this article這可能是有用的,儘管這在視圖模型的工作相當數量。這是有希望的,我會進行調查,但我仍然抱着更簡單的希望。自文章寫入以來,它看起來似乎工具包事件發生了一些變化。

}

回答

0

我也遇到了實現這種類型的DragDrop功能的問題。根本原因似乎是,既不是ItemDragCompleted事件(事件處理程序),也沒有ItemDroppedOnSource(DragEventHandler)通過在該項目中滴加索引。

我最終以暴露保護方法繼承了DragDropTarget:

int GetDropTargetInsertionIndex(TItemsControlType dropTarget, DragEventArgs args) 

然後我用附加的行爲承擔插入指定索引處的項目進入到下面的收集責任。

恐怕底層代碼過於膨脹的StackOverflow的答案(主要是由於大量的去耦),以包括但它是我的主題在博客列表中。在此同時,我希望以上信息能幫助,它肯定是關鍵,我的解決方案。

伊恩