studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones .net wpf canvas custom-controls scrollviewer

.net - para - manual de programacion android pdf



ScrollBars no son visibles después de cambiar las posiciones de los controles dentro de un Canvas (3)

Creé un control canvas personalizado que hereda de WPF Canvas . Lo estoy usando así en la ventana principal -

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <RTD:RTDesignerCanvas Margin="5" Background="White" x:Name="canvas1" Focusable="True" AllowDrop="True"> </RTD:RTDesignerCanvas> </ScrollViewer>

Todo funciona bien, pero cuando trato de establecer la posición de los controles dentro de esta manera

Canvas.SetTop(item, 200);

las barras de desplazamiento no son visibles y el control está oculto en algún lugar. Curiosamente, si agrego otro control, las barras de desplazamiento son visibles y puedo desplazarme hacia abajo para ver el control anterior.

Intenté usar

base.InvalidateVisual(); base.UpdateLayout(); base.InvalidateArrange();

después de cambiar los elementos Top o Left pero no pasa nada; ¿Me estoy perdiendo algo o esto sucede debido a algún error?

Actualización :

para aclarar, digamos que tengo un lienzo que tiene su width , height como 100, 100. Ahora si muevo un control (ya agregado en el lienzo) utilizando Canvas.SetLeft(myControl, 200) entonces se moverá a una posición que no es visible de forma predeterminada y las barras de desplazamiento también están deshabilitadas, por lo que no hay forma de ver ese control.

Ahora si agrego otro control a Canvas, ScrollBars aparece correctamente y puedo ver el control anterior desplazándome.


Akjoshi,

Tiene que ser un error. La próxima vez que el lienzo quede oculto, ejecute Snoop y verifique dónde está. Comprueba las siguientes propiedades del lienzo: ActualWidth , ActualHeight , Opacity , Visibility


La respuesta de Quartermeister me ayudó a resolver este problema.

Tuve que usar base.InvalidateMeasure() explícitamente después de cada operación para actualizar el lienzo y hacer visibles las barras de desplazamiento.


¿ Anuló MeasureOverride en su Lienzo personalizado? Canvas siempre informará un Tamaño deseado de (0, 0), por lo que ScrollViewer nunca pensará que necesita desplazarse.

Vea esta respuesta de que sugiere usar una cuadrícula en lugar de un lienzo y usar la propiedad de margen para el posicionamiento. The Grid informará su tamaño según el tamaño y la posición de sus hijos, por lo que el ScrollViewer sabrá que necesita desplazarse.

Actualizar:

ScrollViewer le pedirá a su hijo que solicite mucho tamaño como lo solicita, y solo tendrá que desplazarse si el niño es más grande que ScrollViewer. Para que se desplace correctamente, tendrá que informar un DesiredSize que sea lo suficientemente grande como para incluir todos sus controles secundarios. Puedes hacerlo anulando MeasureOverride de esta manera:

protected override Size MeasureOverride(Size constraint) { base.MeasureOverride(constraint); var desiredSize = new Size(); foreach (UIElement child in Children) { desiredSize = new Size( Math.Max(desiredSize.Width, GetLeft(child) + child.DesiredSize.Width), Math.Max(desiredSize.Height, GetTop(child) + child.DesiredSize.Height)); } return desiredSize; }

Una solución más fácil, sin embargo, es aprovechar el hecho de que la clase Grid ya se medirá de esta manera. Puede usar la propiedad Margen de los elementos secundarios para colocarlos exactamente en lugar de las propiedades Canvas.Left y Canvas.Top. Si actualmente estás haciendo

Canvas.SetLeft(item, 100); Canvas.SetTop(item, 200);

para un artículo en el lienzo, podrías hacer

item.Margin = new Thickness(100, 200, 0, 0);

para colocarlo en el mismo lugar dentro de una rejilla de una celda.