c# - Conseguir que Viewbox y ScrollViewer trabajen juntos
visual-studio windows-phone-8 (2)
Creo que deberías mirar el controlador de la vista y mirar la muestra de la lente básica, donde han implementado esto. El viewportcontroller, tiene un visor de desplazamiento en su interior, y viewport.
Los fundamentos son los siguientes:
- Mientras que la imagen que tienes es "unzoomed", el scrollviewer tiene control total y ViewportControl no hace nada.
- Cuando comience a pellizcar, bloquee el visor de desplazamiento deshabilitando la barra de desplazamiento vertical Y configurando el viewport.height = scrollviewer.height. Esto neutraliza el scollviewer.
- Puedes hacer un zoom temporal usando Image ScaleTransform.
- Cuando haya terminado de pellizcar, cambie el tamaño de su imagen real para que ocupe espacio real dentro de ViewportControl. Ahora su viewportControl le permitirá desplazarse por toda la imagen ampliada con un bonito rebote.
- Cuando vuelva a alejarse, vuelva a habilitar el visor de desplazamiento. (Establezca la altura a la altura de la pantalla y active la barra de desplazamiento).
Para su información, me olvido completamente de por qué hay un lienzo allí, pero siento que es importante. Vea abajo:
Mientras que la muestra a continuación no hace lo que usted quiere hacer, basé mi código en el MediaViewer dentro de esta muestra y la modifiqué: Muestra de lente básica
Sin embargo hay que tener en cuenta que es para zoom de imagen.
Tengo n mapas de reproducción en los que uso ScrollViewer
para desplazarme por el mapa, y deseo usar ViewBox
junto con PinchManipulations
para acercar y alejar el mapa. Hasta ahora he hecho esto configurando el modo de Manipulation
del ScrollViewer
en control
, sin embargo, esto me da un retraso cuando hago zoom. ¿Hay alguna manera de hacer que ViewBox
y ScrollViewer
funcionen mejor juntos y, por lo tanto, eviten el retraso? El código que tengo hasta ahora es:
ScrollViewer:
<ScrollViewer Grid.Column ="0" Width="768" Height="380" HorizontalScrollBarVisibility="Hidden">
<Viewbox Stretch="None">
<View:Map/>
</Viewbox>
</ScrollViewer>
PinchZoom:
<Grid x:Name="Map" Width="1271" Height="1381.5">
<Grid.RenderTransform>
<ScaleTransform ScaleX="{Binding Path=deltaZoom}" ScaleY="{Binding Path=deltaZoom}"/>
</Grid.RenderTransform>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ManipulationStarted">
<cmd:EventToCommand Command="{Binding Path=ZoomStartedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="ManipulationDelta">
<cmd:EventToCommand Command="{Binding Path=ZoomDeltaCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="ManipulationCompleted">
<cmd:EventToCommand Command="{Binding Path=ZoomCompletedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
El código donde uso el zoom de pellizco:
public ICommand ZoomStartedCommand { get; set; }
public ICommand ZoomDeltaCommand { get; set; }
public ICommand ZoomCompletedCommand { get; set; }
private double _deltaZoom;
public double deltaZoom
{
get
{
return _deltaZoom;
}
set
{
_deltaZoom = value;
RaisePropertyChanged("deltaZoom");
}
}
public double distance;
public MainViewModel()
{
ZoomStartedCommand = new RelayCommand<ManipulationStartedEventArgs>(ZoomStart);
ZoomDeltaCommand = new RelayCommand<ManipulationDeltaEventArgs>(ZoomDelta);
ZoomCompletedCommand = new RelayCommand<ManipulationCompletedEventArgs>(ZoomCompleted);
}
public void ZoomStart(ManipulationStartedEventArgs e)
{
FrameworkElement Element = (FrameworkElement)e.OriginalSource;
var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.Control);
}
public void ZoomDelta(ManipulationDeltaEventArgs e)
{
if (e.PinchManipulation != null)
{
deltaZoom = deltaZoom * e.PinchManipulation.DeltaScale;
}
else
{
FrameworkElement Element = (FrameworkElement)e.OriginalSource;
var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.System);
}
}
public void ZoomCompleted(ManipulationCompletedEventArgs e)
{
FrameworkElement Element = (FrameworkElement)e.OriginalSource;
var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.System);
}
También tuve este problema cuando intenté manejar una gran cantidad de datos en un solo contenedor. No puede simplemente cargar todo el mapa en un cuadro de vista y usar un visor de desplazamiento y esperar que todo funcione bien.
La primera solución para hacer que una aplicación funcione bien en grandes conjuntos de datos es probar la virtualización de la interfaz de usuario . Un control que acepta la virtualización crea solo los elementos necesarios para mostrar la vista actual, o más exactamente, solo los elementos que están visibles en la pantalla. Para entender mejor este concepto, les daré un ejemplo del mundo real. Eche un vistazo a cómo Facebook transmite sus noticias. Carga X publicaciones en los elementos html de X y luego, cuando los usuarios se desplazan hacia abajo, descargan los no visibles y cargan los nuevos.
1.UI Virtualización
Simplemente reutiliza elementos. Este es el concepto de virtualización UI. Tengo que mencionar una característica importante: el desplazamiento diferido (el usuario puede desplazarse pero los resultados solo se muestran después del lanzamiento del clic, esta es una mejora de rendimiento si el usuario desea subir y bajar con la barra de desplazamiento)
Volviendo a su problema. Si el mapa está completamente cargado, es un problema de rendimiento desplazarse o acercarse porque las partes no visibles podrían acercarse y desplazarse también. Imagine lo que hubiera pasado si Google Maps no fuera compatible con la virtualización de la interfaz de usuario. Cuando el usuario intentara acercarse, toda la Tierra se acercaría (toneladas de GB).
2. Virtualización de datos
Sin embargo, su mapa debe estar completamente cargado en algún lugar de la memoria. Si es grande, esto es un problema y ahí viene la virtualización de datos . En lugar de tener todo el mapa completamente cargado, carga solo las secciones necesarias para su visualización. Si desea tener una mejor capacidad de respuesta, puede utilizar el concepto que usa Google Maps. Cargue en la memoria pocos datos más de los que caben en la pantalla cuando se procesa, por lo que la IU no se congelará (hasta que los datos queden en la memoria) cuando intente desplazarse.
Puedes leer más:
Resolví mi problema usando lienzo virtualizado . Ejemplo de aplicación usando lienzo virtualizado: http://pavzav.blogspot.ro/2010/11/virtualized-canvas.html
Es posible que desee echar un vistazo a Wpf Bing Maps Control