Certo, ecco qua.
Innanzitutto, è possibile ridimensionare lo WebView
nel contenuto effettivo. Quindi, ridimensiona lo WebView
nella dimensione originale. Richiederebbe un richiamo di script e un ScaleTransform
. Abbastanza semplice, davvero.
Ti piace questa:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<WebView x:Name="MyWebView" Source="http://www.stackoverflow.com" />
</Grid>
void MyWebView_LoadCompleted(object sender, NavigationEventArgs e)
{
var _Original = MyWebView.RenderSize;
// ask the content its width
var _WidthString = MyWebView.InvokeScript("eval",
new[] { "document.body.scrollWidth.toString()" });
int _Width;
if (!int.TryParse(_WidthString, out _Width))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
// ask the content its height
var _HeightString = MyWebView.InvokeScript("eval",
new[] { "document.body.scrollHeight.toString()" });
int _Height;
if (!int.TryParse(_HeightString, out _Height))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
// resize the webview to the content
MyWebView.Width = _Width;
MyWebView.Height = _Height;
// scale the webview back to original height (can't do both height & width)
var _Transform = (MyWebView.RenderTransform as ScaleTransform)
?? (MyWebView.RenderTransform = new ScaleTransform()) as ScaleTransform;
var _Scale = _Original.Height/_Height;
_Transform.ScaleX = _Transform.ScaleY = _Scale;
}
Questo si tradurrà in un molto alto e stretto WebView
come questo:
Ma non è questo ciò che si desidera.
Anche se è possibile ridimensionare il rettangolo risultante in modo che non sia a forma di pazzo, il contratto di stampa in Windows 8 richiede di fornire una singola pagina. Non fa l'impaginazione per te. Di conseguenza, ciò di cui hai realmente bisogno è di recuperare il singolo sito Web, una pagina alla volta.
Il primo approccio è la base su come farlo. Ma hai bisogno di aggiustare la dimensione del rettangolo alle dimensioni della pagina che ti sono state passate dall'attività Stampa di Windows 8. Questo sarà basato sulla selezione della stampante dell'utente. Ad esempio, Lettera contro A4 (nel Regno Unito). Quindi, usando la proprietà Stretch del pennello, puoi assicurarti che si ritiri da solo. Quindi, usando la proprietà Transform del pennello, è possibile farlo scorrere su e giù all'interno del rettangolo fino a quando non viene rivelata la pagina che si desidera stampare.
Ecco come:
<Grid Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="995" />
<ColumnDefinition Width="300" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<WebView Grid.Column="0" x:Name="MyWebView" Source="http://www.stackoverflow.com" HorizontalAlignment="Right" />
<Rectangle Grid.Column="1" x:Name="MyWebViewRectangle" Fill="Red" />
<ScrollViewer Grid.Column="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="MyPrintPages" VerticalAlignment="Top" HorizontalAlignment="Left">
<Rectangle Height="150" Width="100" Fill="White" Margin="5" />
<Rectangle Height="150" Width="100" Fill="White" Margin="5" />
<Rectangle Height="150" Width="100" Fill="White" Margin="5" />
<Rectangle Height="150" Width="100" Fill="White" Margin="5" />
<Rectangle Height="150" Width="100" Fill="White" Margin="5" />
</ItemsControl>
</ScrollViewer>
</Grid>
public MainPage()
{
this.InitializeComponent();
MyWebView.LoadCompleted += MyWebView_LoadCompleted;
}
void MyWebView_LoadCompleted(object sender, NavigationEventArgs e)
{
MyWebViewRectangle.Fill = GetWebViewBrush(MyWebView);
MyPrintPages.ItemsSource = GetWebPages(MyWebView, new Windows.Foundation.Size(100d, 150d));
MyWebView.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
WebViewBrush GetWebViewBrush(WebView webView)
{
// resize width to content
var _OriginalWidth = webView.Width;
var _WidthString = webView.InvokeScript("eval",
new[] { "document.body.scrollWidth.toString()" });
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// resize height to content
var _OriginalHeight = webView.Height;
var _HeightString = webView.InvokeScript("eval",
new[] { "document.body.scrollHeight.toString()" });
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// create brush
var _OriginalVisibilty = webView.Visibility;
webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
var _Brush = new WebViewBrush
{
SourceName = webView.Name,
Stretch = Stretch.Uniform
};
_Brush.Redraw();
// reset, return
webView.Width = _OriginalWidth;
webView.Height = _OriginalHeight;
webView.Visibility = _OriginalVisibilty;
return _Brush;
}
IEnumerable<FrameworkElement> GetWebPages(WebView webView, Windows.Foundation.Size page)
{
// ask the content its width
var _WidthString = webView.InvokeScript("eval",
new[] { "document.body.scrollWidth.toString()" });
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// ask the content its height
var _HeightString = webView.InvokeScript("eval",
new[] { "document.body.scrollHeight.toString()" });
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// how many pages will there be?
var _Scale = page.Width/_ContentWidth;
var _ScaledHeight = (_ContentHeight * _Scale);
var _PageCount = (double)_ScaledHeight/page.Height;
_PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);
// create the pages
var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
for (int i = 0; i < (int)_PageCount; i++)
{
var _TranslateY = -page.Height * i;
var _Page = new Windows.UI.Xaml.Shapes.Rectangle
{
Height = page.Height,
Width = page.Width,
Margin = new Thickness(5),
Tag = new TranslateTransform { Y = _TranslateY },
};
_Page.Loaded += (s, e) =>
{
var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
var _Brush = GetWebViewBrush(webView);
_Brush.Stretch = Stretch.UniformToFill;
_Brush.AlignmentY = AlignmentY.Top;
_Brush.Transform = _Rectangle.Tag as TranslateTransform;
_Rectangle.Fill = _Brush;
};
_Pages.Add(_Page);
}
return _Pages;
}
Così l'interfaccia utente sarà qualcosa come questo, dove la colonna di sinistra è il WebView, la seconda colonna (al centro) è l'all-in-one come la nostra prima soluzione, e il terzo è un ripetitore che mostra le singole pagine pronte per la stampa.
Naturalmente la magia è davvero nei GetWebPages metodo()! Non mi dispiace dire che è una semplice meraviglia resa abbastanza semplice dal modo in cui funzionano C# e Transforms.
Si prega di notare, questo è non completo. Sì, rompe la pagina per te, ma non posso essere sicuro di quanto margine vuoi sulla tua pagina. Quindi il tweaking richiesto è minuscolo, ma volevo menzionarlo. Questo è il 98% del codice necessario per interrompere una visualizzazione Web e la preparazione se per l'attività di stampa di Windows 8 in risposta per l'evento impaginato. Quindi passa i rettangoli ad esso uno alla volta.
Detto questo, questa è probabilmente la soluzione più completa per questo problema su Internet. :)
Buona fortuna !!
Qual è l'altezza di RichTextBlock? È impostato per tagliare? Mi chiedo se sta stampando l'altezza della RTB/Paragrafo invece di WebView. –