2010-02-23 18 views
10

En mi aplicación WPF tengo un lienzo en el que dibujo. Anteriormente manejé el dibujo en el código de atrás, pero ahora he descompuesto todo en un ViewModel. Esto me da algunos desafíos.Encuadernación WPF Canvas Children a una ObservableCollection

Tengo algunos objetos de InkPresenter sosteniendo pulsaciones. Earier les añaden como los niños a la lona en el código detrás - de esta manera:

// Build an InkPresenter: 
var someInkPresenter = BuildInkPresenter(..); 
//_myCanvas is the <Canvas> I want to display it in: 
_myCanvas.Children.Add(someInkPresenter); 

ahora - no la construcción del InkPresenter en el código subyacente de la XAML que sostiene _myCanvas que tengo que hacer esto de manera diferente. Lo que me gustaría hacer es crear un InkPresenter y agregarlo a una colección:

public ObservableCollection<InkPresenter> Drawings; 

Mi problema ahora es cómo obligar a la lona a este ObservableCollection - y tienen los InkPresenters muestran cuando se añade a la colección. ¿Puedo lograr esto utilizando enlaces de datos de alguna manera?

Respuesta

16

Creo que puede hacer esto con ItemsControl + ItemsPanelTemplate. De esta manera:

<ItemsControl ItemsSource="{Binding YourCollection}"> 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    </ItemsControl> 

Para leer más acerca de este enfoque se refieren a Dr.WPF: ItemsControl: A to Z (P is for Panel)

+0

Thx! Suena razonable. Lo echaré un vistazo! – stiank81

+1

Este es normalmente el enfoque que tomaría, pero en este caso es probable que se encuentre con problemas porque los InkPresenters no van a ser hijos directos del Canvas como lo son cuando los agrega en el código. En cambio, Visual Tree va a tener un ContentPresenter adicional inyectado alrededor de cada elemento de InkPresenter. Para que este método funcione, debería considerar extraer los datos reales (trazos) de cada InkPresenter y almacenar una colección de esos en su máquina virtual. A continuación, puede crear un ItemsControl personalizado que anule GetContainerForItemOverride para devolver un InkPresenter. –

+0

No puedo estar de acuerdo John John ... Es un ItemsControl. Utiliza UIElement como contenedor predeterminado ... – Anvaka

10

La solución Anvaka sugerido es grande, pero como John Bowen señaló que necesita saber un poco más , si realmente desea vincular sus elementos a las propiedades adjuntas Canvas.

He aquí un ejemplo de cómo se unen a Canvas.Left y Canvas.Top:

<ItemsControl ItemsSource="{Binding YourCollection}"> 
<ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
</ItemsControl.ItemsPanel> 
<ItemsControl.ItemContainerStyle> 
    <Style TargetType="ContentPresenter"> 
     <Setter Property="Canvas.Left" Value="{Binding YourModelLeft}" /> 
     <Setter Property="Canvas.Top" Value="{Binding YourModelTop}" /> 
    </Style> 
</ItemsControl.ItemContainerStyle> 

Por cierto, he encontrado la solución en this question, después de que trató la sugerencia de Anvaka, donde la unión no funcionó .

Esperemos que esto ayude a los demás, buscando la misma respuesta.

+0

Gracias, exactamente lo que estaba buscando. – Cousken

Cuestiones relacionadas