c# - Windows Phone 8.1-Maneje desplazamiento vertical WebView por el elemento ScrollViewer externo
xaml windows-phone (3)
¿Has intentado configurar la propiedad Height de WebView en Auto?
<ScrollViewer x:Name="scrollViewer" >
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="My content" />
<Grid Background="Transparent"
Margin="0"
Grid.Row="1">
<WebView ScrollViewer.ZoomMode="Enabled"
x:Name="WebViewComponent"
Margin="0"
Height="Auto" />
</Grid>
</Grid>
</ScrollViewer>
Problema
Tengo que mostrar un WebView
dentro de un ScrollViewer
en la aplicación Windows Phone 8.1, con los siguientes requisitos:
-
WebView
altura deWebView
debe ajustar en función de su contenido. -
WebView
desplazamiento verticalWebView
debe ser manejado por unScrollViewer
externo. -
WebView
debe manejar desplazamiento horizontal, escala (zoom de pellizco), selección de texto (con el botón de copia predeterminado) y navegación de enlaces.
En la siguiente imagen se muestra mi diseño simulado (a la izquierda) y el mejor ejemplo de funcionalidad similar: una aplicación de correo integrada (a la derecha)
Diseño de muestra XAML:
<ScrollViewer>
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="My content" />
</Grid>
<WebView Grid.Row="1" x:Name="WebViewComponent"></WebView>
</Grid>
</ScrollViewer>
¿Qué probé?
Mida el contenido HTML y ajuste la altura WebView . Esta parte funcionó y con varios ajustes pude establecer la altura correcta para el elemento WebView
.
Suscribirse a un elemento de Borde dentro de una Vista Web - No funcionó . El problema aquí es que en Windows Phone 8.1 parece que un componente WebView
no tiene hijos visuales (al menos no DependencyObject
)
Además, he intentado jugar con las propiedades ManupulationMode
e IsHitTestVisible
sin éxito .
ACTUALIZACIÓN Se agregó el botón de selección y copia de texto a la funcionalidad requerida de WebView
. De alguna manera lo perdí en el contenido de la pregunta original.
He estado enfrentando este problema y obtuve una solución parcial (sin incluir la selección de texto).
Básicamente para poder usar el scrollviewer que contiene la vista web, necesita algo para arrastrar, así que utilizo un rectángulo con el alto y el ancho igual que la vista web.
<ScrollViewer Name="ScrollViewer">
<Grid x:Name="LayoutRoot" Height="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Name="GridHeader">
<Image Stretch="UniformToFill" Source="ms-appx:///Assets/img_default_header.jpg" />
</Grid>
<Grid Grid.Row="1" x:Name="GridNews" Margin="12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<WebView Margin="-6,12,0,-6" Grid.Row="0" x:Name="WebviewContent" VerticalAlignment="Top" DefaultBackgroundColor="Transparent" />
<Rectangle Margin="0,12,0,0" Height="{Binding Height, ElementName=WebviewContent}" Name="RecWeb" VerticalAlignment="Top" Fill ="#00000000" Tapped="RecWeb_Tapped" />
</Grid>
<Grid Name="GridRelatedNews" Grid.Row="2" Margin="12,0">
<ListView ItemsSource="{Binding NewsDetail.RelatedStory}" ScrollViewer.VerticalScrollBarVisibility="Hidden">
</ListView>
</Grid>
</ScrollViewer>
Ahora necesitamos inyectar css y javascript para hacer que la altura de la vista web se adapte al contenido (encontré un ejemplo de código en otro hilo de , olvídate de dónde viene)
string htmlFragment = @"
<html>
<head>
<meta name=""viewport"" content=""width="+width+@", initial-scale=1, user-scalable=no"" />
<script type=""text/javascript"">
function loadLink(x,y){
window.external.notify(''x=''+x+''y=''+y);
var el = document.elementFromPoint(x, y);
el.click();};
</script>
<style>
" + CSS + @"
</style>
</head>
<body onLoad=""window.external.notify(''rendered_height=''+document.getElementById(''content'').offsetHeight);"">
<div id=''content'' style=""font-size:16px; color:#222222;"">" + original +
@"</div>
</body>
</html>";
A continuación, se agregó un evento de notificación webscript webview agregado para determinar la altura representada de la vista web (y el rectángulo):
void WebviewContent_ScriptNotify(object sender, NotifyEventArgs e)
{
if (e.Value.Contains("rendered_height"))
{
if (valuePair != null && valuePair[0] == "rendered_height")
{
double renderedHeight = double.Parse(valuePair[1]);
WebviewContent.Height = renderedHeight;
}
}
}
Me las arreglé para permitir que esta solución pueda hacer clic en algún enlace en el contenido usando este método (el método loadLink javascript):
private async void RecWeb_Tapped(object sender, TappedRoutedEventArgs e)
{
Point p = e.GetPosition(WebviewContent);
int x = Convert.ToInt32(p.X);
int y = Convert.ToInt32(p.Y);
string[] size = { x.ToString(), y.ToString() };
await WebviewContent.InvokeScriptAsync("loadLink",size);
}
Tal vez pueda tomarlo desde allí para agregar un controlador de eventos para su problema de selección de texto. El punto que usa esta solución es también encontrar un controlador de eventos equivalente en javascript.
Lo verifiqué e intenté algunas cosas, pero no pude hacerlo funcionar de la manera que usted lo desea. Puede ser más fácil idear un diseño diferente. Básicamente, algo que no incluye un ScrollViewer
externo.
Una opción (que puede ser un poco hacky, no lo han probado) es inyectar su contenido en la página, a través de algunos JS, y usar solo un
WebView
.Si su contenido es pequeño, puede dejarlo en la parte superior de la página, eliminar
ScrollViewer
y dejar queWebView
maneje todo. ElWebView
será más pequeño, pero funcionará perfectamente.
Estos son solo algunos ejemplos de diferentes diseños. Si me dices por qué no funcionarían, o si me das más información sobre tu problema real, podría encontrar algo más apropiado.