使用RenderTargetBitmap将wpf控件渲染成图片十分好用,但如果控件位于scorllviewer中,那么发生了一个意想不到的结果,各位帮我看看是怎么回事。以下是我的测试代码:
<Window x:Class="ImageRender.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ImageRender" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="30"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" x:Name="scorll"> <Border Width="500" Height="500" Background="Red" x:Name="srouceBorder"> <Border Background="Yellow" Margin="50"> <Border Background="Black" Margin="50"> <Border Background="Blue" Margin="50"> <Border Background="Salmon" Margin="50"> </Border> </Border> </Border> </Border> </Border> </ScrollViewer> <Image x:Name="targetImage" Grid.Column="1"/> <Button Content="render" Grid.Row="1" Click="Button_Click"/> </Grid> </Window>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace ImageRender 17 { 18 /// <summary> 19 /// MainWindow.xaml 的交互逻辑 20 /// </summary> 21 public partial class MainWindow : Window 22 { 23 public MainWindow() 24 { 25 InitializeComponent(); 26 } 27 28 private void Button_Click(object sender, RoutedEventArgs e) 29 { 30 RenderTargetBitmap targetBitmap = new RenderTargetBitmap( 31 (int)srouceBorder.ActualWidth, 32 (int)srouceBorder.ActualHeight, 33 96, 34 96, 35 PixelFormats.Default); 36 37 targetBitmap.Render(srouceBorder); 38 39 targetImage.Source = targetBitmap; 40 } 41 42 43 } 44 }
在前台代码中,scrollviewer下放了一个控件(border),如果scrollviewer的滚动条未滑动,点击渲染,则生成图像正常。
但如果滚动条发生了滑动,那么渲染出来的图像也就错位了,效果如下:
你需要在Render之前Arrange
srouceBorder.Arrange(new Rect(new Size((int)srouceBorder.ActualWidth, (int)srouceBorder.ActualHeight)));
这样做截图对了,不过srocllviewer下的控件本身又显示错了。。。
不过谢谢大侠,有思路了。如果后续有解决srocllviewer下的控件本身又显示错位问题的方法也请告诉我哈
@madgecko: 额,那你可以类似这样。。。
RenderTargetBitmap targetBitmap = new RenderTargetBitmap( (int)srouceBorder.ActualWidth, (int)srouceBorder.ActualHeight, 96, 96, PixelFormats.Default); VisualBrush sourceBrush = new VisualBrush(srouceBorder); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); using (drawingContext) { drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(srouceBorder.ActualWidth, srouceBorder.ActualHeight))); } targetBitmap.Render(drawingVisual); targetImage.Source = targetBitmap;