Конечно, здесь вы идете.
Во-первых, вы можете изменить размер WebView
до фактического содержимого. Затем вы масштабируете WebView
до первоначального размера. Для этого потребуется сценарий invoke и ScaleTransform
. Довольно просто, правда.
Как это:
<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;
}
Это приведет к очень высокий, узкий WebView
так:
Но это не то, что вы хотите.
Даже если вы можете изменить размер результирующего прямоугольника так, чтобы он был не таким сумасшедшим, контракт на печать в Windows 8 требует, чтобы вы предоставили ему одну страницу. Это не для вас. В результате вам действительно нужно получить отдельный веб-сайт, по одной странице за раз.
Первый подход - основа того, как это сделать. Но вам нужно исправить размер прямоугольника до размера страницы, переданного вам при задании печати Windows 8. Это будет основано на выборе принтера для пользователя. Например, Letter to A4 (в Великобритании). Затем, используя свойство Stretch кисти, вы можете обеспечить ее самоценность. Затем, используя свойство Transform кисти, вы можете перемещать его вверх и вниз внутри прямоугольника, пока он не покажет страницу, которую вы хотите распечатать.
Вот как:
<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;
}
Так что интерфейс будет что-то вроде этого, где левый столбец является WebView, второй столбец (средний) является все-в-одном, как наш первый раствор, и третий - повторитель, показывающий отдельные страницы, готовые к печати.
Конечно магия действительно в GetWebPages() метод! Я не возражаю сказать, что это простое чудо, сделанное довольно легко, так как C# и Transforms работают.
Обращаем ваше внимание, что это не заполнено. Да, он разбивает страницу для вас, но я не могу быть уверен, сколько маржи вы хотите на своей странице. Поэтому требуемая настройка крошечная, но я хотел бы упомянуть об этом. Это 98% кода, который вам нужен, чтобы разбить WebView и подготовить, если для задачи печати Windows 8 в ответ на событие paginate. Затем пропустите прямоугольники к нему по одному.
Сказав это, возможно, это наиболее полное решение этой проблемы в Интернете. :)
Удачи!
Какова высота RichTextBlock? Установлен ли клип? Интересно, печатает ли высота RTB/Paragraph вместо WebView. –