2010-10-10 13 views
7

Estoy vinculando un ItemsControl con Canvas como ItemsPanelTemplate a un ObservableCollection.Combinando elementosControl con elementos arrastrables - Element.parent always null

Quiero hacer que los objetos se pueden arrastrar con el DraggableExtender tal como fue anunciado en Dragging an image in WPF (no quiero utilizar transforma - Necesito usar la izquierda de la lona y mejores propiedades)

Se define como:

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

el DraggableExtender necesita el padre del elemento a ser el lienzo, pero el padre de mi elemento (ContentPresenter) es nula, por lo que el arrastre no funciona.

Entonces, la pregunta obvia es: ¿qué estoy haciendo mal?

Respuesta

7

Como los elementos no están directamente dentro del lienzo, debe caminar por el árbol visual hasta que encuentre el lienzo. Yo suelo usar el siguiente método de extensión para hacer eso:

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

Ponga el método anterior en una clase estática, e importar el espacio de nombres donde se declara. En el código DraggableExtender, basta con sustituir esta línea:

Canvas canvas = element.Parent as Canvas; 

Con éste:

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

Cheers, que funciona como un encanto. – Pygmy

Cuestiones relacionadas