wpf - 如何截取 ScrollViewer 的内容
问题描述
我想截取 a 中的任何内容ScrollViewer
,而不仅仅是ViewPort
. 但是到目前为止,我尝试的所有操作都会导致完全黑色的图像或仅显示部分内容而其他所有内容都是黑色的图像。我认为这可能是因为我没有指定任何背景,但是改变 myWindow
或 my TreeView
to的背景White
并没有改变任何事情。你能告诉我哪里出了问题,或者我怎么能截取 a 的全部内容ScrollViewer
?
这是我放在一起的一个小示例(显示主窗口后按“P”)。
主窗口(只是一个TreeView
太小Window
而无法显示全部内容的窗口):
<Window x:Class="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:ScreenshotTest"
mc:Ignorable="d"
Title="MainWindow"
Height="200" Width="300"
KeyDown="Window_KeyDown">
<TreeView x:Name="Tree">
<TreeViewItem Header="Node 1 - Lorem ipsum dolor sit amet, consetetur sadipscing elitr" IsSelected="True" IsExpanded="True">
<TreeViewItem Header="Node 1.1" />
<TreeViewItem Header="Node 1.2" IsExpanded="True">
<TreeViewItem Header="Node 1.2.1"/>
</TreeViewItem>
<TreeViewItem Header="Node 1.3" IsExpanded="True">
<TreeViewItem Header="Node 1.3.1" />
<TreeViewItem Header="Node 1.3.2" />
<TreeViewItem Header="Node 1.3.3" />
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Node 2 - sed diam nonumy eirmod tempor invidunt ut labore et dolore" IsExpanded="True">
<TreeViewItem Header="Node 2.1"/>
<TreeViewItem Header="Node 2.2" IsExpanded="True">
<TreeViewItem Header="Node 2.2.1"/>
</TreeViewItem>
<TreeViewItem Header="Node 2.3" IsExpanded="True">
<TreeViewItem Header="Node 2.3.1" />
<TreeViewItem Header="Node 2.3.2" />
<TreeViewItem Header="Node 2.3.3" />
</TreeViewItem>
</TreeViewItem>
</TreeView>
</Window>
以及窗口后面的代码:
Class MainWindow
Private Sub Window_KeyDown(sender As Object, e As KeyEventArgs)
If e.Key <> Key.P Then
Exit Sub
End If
Dim sv As ScrollViewer = GetFirstChildOfType(Of ScrollViewer)(Me.Tree)
Me.CaptureScreen(sv.Content, "C:\Temp\Screenshot.png")
End Sub
Private Shared Function GetFirstChildOfType(Of T As DependencyObject)(obj As DependencyObject) As T
Dim result As T
Dim child As DependencyObject
If (obj Is Nothing) Then
Return Nothing
End If
If (VisualTreeHelper.GetChildrenCount(obj) = 0) Then
Return Nothing
End If
For index As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj)
child = VisualTreeHelper.GetChild(obj, index)
result = TryCast(child, T)
If (result Is Nothing) Then
result = GetFirstChildOfType(Of T)(child)
End If
If (result IsNot Nothing) Then
Return result
End If
Next index
Return Nothing
End Function
Private Sub CaptureScreen(source As UIElement, filename As String)
Dim height As Double
Dim renderHeight As Double
Dim width As Double
Dim renderWidth As Double
Dim renderTarget As RenderTargetBitmap
Dim vb As VisualBrush
Dim dv As DrawingVisual
Dim encoder As PngBitmapEncoder
Try
height = source.RenderSize.Height
renderHeight = height
width = source.RenderSize.Width
renderWidth = width
renderTarget = New RenderTargetBitmap(Convert.ToInt32(renderWidth), Convert.ToInt32(renderHeight), 96, 96, PixelFormats.Pbgra32)
vb = New VisualBrush(source)
dv = New DrawingVisual
Using dc As DrawingContext = dv.RenderOpen
dc.DrawRectangle(vb, Nothing, New Rect(New Point(0, 0), New Point(width, height)))
End Using
renderTarget.Render(dv)
encoder = New PngBitmapEncoder
encoder.Frames.Add(BitmapFrame.Create(renderTarget))
Using fs As IO.FileStream = New IO.FileStream(filename, IO.FileMode.Create, IO.FileAccess.Write)
encoder.Save(fs)
End Using
Catch ex As Exception
Stop
End Try
End Sub
End Class
我对 C# 中的答案也很好。
解决方案
经过大量的试验和错误,我发现,我做错了几件事。
首先,我用错了UIElement
. 我不得不拿第一个StackPanel
而不是第一个ScrollViewer
。
其次,虽然我Window
的背景设置为白色,但我里面的所有控件Window
都没有背景,这可能就是我生成的图片是黑色的原因。
因此,只需将我的代码的一个功能更改为
Private Sub Window_KeyDown(sender As Object, e As KeyEventArgs)
Dim panel As StackPanel
If e.Key <> Key.P Then
Exit Sub
End If
panel = GetFirstChildOfType(Of StackPanel)(Me.Tree)
panel.Background = Brushes.White
panel.UpdateLayout()
Me.CaptureScreen(panel, "C:\Temp\Screenshot.png")
End Sub
成功了,现在我至少得到一张白色背景的照片和我的所有元素TreeView
,而不仅仅是屏幕上可见的那些。
现在我还有一些其他问题,但这是另一个问题的问题。
推荐阅读
- c# - 邮递员请求有效,但 Restsharp C# 无效 (oauth1)
- python - 使用 Pandas 系列中进行的 group_by 计算填充 Pandas 数据框
- javascript - 如何解析网页并获取指示内容
- rust - 当第一个编译器无法构建板条箱时,您可以使用不同的编译器吗?
- java - PasswordField 'bullets' 没有在使用 Gluon 客户端插件构建的 Android 应用程序中正确显示
- flutter - 如果产品尺寸不同,颤振添加到新购物车
- wildfly - Wildfly 24、Java 11.0.11 添加外部安全提供程序
- react-slick - react-slick 最后一张幻灯片在加载时首先显示
- shared-libraries - 在 Yocto 中将 .so 和符号链接添加到 .so
- docker - Rabbitmq 没有从集群配置开始