2010-10-10 10 views
7

Sono vincolante a ItemsControl con Canvas come ItemsPanelTemplate in ObservableCollection.Combinazione di ItemsControl con elementi trascinabili - Element.parent sempre nullo

Voglio fare gli elementi trascinabili con il DraggableExtender come scritto in Dragging an image in WPF (io non voglio usare le trasformazioni - ho bisogno di usare la sinistra Canvas e migliori proprietà)

E 'definito come:

<ItemsControl ItemsSource="{Binding Path=Nodes}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas IsItemsHost="True" /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Views:NodeView DataContext="{Binding}"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemContainerStyle> 
      <Style TargetType="ContentPresenter"> 
       <Setter Property="Utilities:DraggableExtender.CanDrag" Value="True" /> 
       <Setter Property="Canvas.Left" Value="{Binding Path=X}" /> 
       <Setter Property="Canvas.Top" Value="{Binding Path=Y}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 

il DraggableExtender ha bisogno il genitore dell'elemento di essere sulla tela, ma la madre di mio elemento (ContentPresenter) è nullo, in modo che il trascinamento non funziona.

Quindi la domanda ovvia è - cosa sto sbagliando?

risposta

7

Poiché gli elementi non sono direttamente all'interno dell'area di disegno, è necessario salire l'albero visivo fino a trovare il quadro. Io di solito uso il seguente metodo di estensione per farlo:

public static T FindAncestor<T>(this DependencyObject obj) 
    where T : DependencyObject 
{ 
    DependencyObject tmp = VisualTreeHelper.GetParent(obj); 
    while(tmp != null && !(tmp is T)) 
    { 
     tmp = VisualTreeHelper.GetParent(tmp); 
    } 
    return tmp as T; 
} 

Mettere il metodo di cui sopra in una classe statica, e importare lo spazio in cui viene dichiarata. Nel codice DraggableExtender, basta sostituire questa linea:

Canvas canvas = element.Parent as Canvas; 

Con questo:

Canvas canvas = element.FindAncestor<Canvas>(); 
+0

Cheers, funziona come un fascino. – Pygmy