如何复制FrameworkElement,包括溢出的内容?

7

我正在使用在http://brianlagunas.com/wpf-copy-uielement-as-image-to-clipboard/找到的代码,用于复制呈现的XAML树形视图。如果内容超出可用高度,该树形视图将被配置为滚动。

const long DPI = 96;
FrameworkElement element = (FrameworkElement)param;
double height = element.ActualHeight;
double width = element.ActualWidth;
RenderTargetBitmap bmp = new RenderTargetBitmap((int)Math.Round(width), (int)Math.Round(height), DPI, DPI, PixelFormats.Default);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
    VisualBrush vb = new VisualBrush(element);
    dc.DrawRectangle(vb, null, new Rect(new Point(), new Size(width, height)));
}
bmp.Render(dv);

DataObject _data = new DataObject();
_data.SetImage(bmp);

当我的内容适合客户端区域时,这个方法很好用:

当客户端区域足够大以避免溢出时的树形视图

但当内容溢出客户端区域时,就会出现问题:

当客户端区域太小且溢出发生时的树形视图

有没有一种方法可以获取整个控件内容,而不必调整屏幕上的元素大小?

编辑: 以下是 Treeview XAML:

    <TreeView x:Name="ProjectTree" Grid.Row="1"
              ItemContainerStyle="{StaticResource ShinyTreeView}"
              HorizontalContentAlignment="Stretch"
              MouseDoubleClick="TreeView_OnMouseDoubleClick"
              Style="{StaticResource CodeExplorerTreeViewStyle}" BorderThickness="0,1"
              VirtualizingPanel.IsVirtualizing="False">
        <i:Interaction.Behaviors>
            <controls:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
        </i:Interaction.Behaviors>
    </TreeView>

将树形视图绑定到按钮命令的按钮:

            <Button Command="{Binding CopyResultsCommand}" CommandParameter="{Binding ElementName=ProjectTree}">
                <Image Height="16" Source="../../Resources/document-copy.png" />
                <Button.ToolTip>
                    <TextBlock Text="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=CodeExplorer_CopyToolTip}" />
                </Button.ToolTip>
            </Button>

我不确定这是否有效,但您是否尝试在TreeView控件上设置VirtualizingStackPanel.IsVirtualizing="False" - Glen Thomas
这可能会强制所有节点进行渲染(尽管我的示例Treeview非常小,所以我看不出任何区别),但似乎并没有改变渲染的bmp。 - ThunderFrame
如果 param 是你想要绘制的 TreeView 控件,它会正常工作。也许你正在将 ScrollViewer 控件传递给该函数。 - Yusuf Tarık Günaydın
我相信我已经传递了Treeview(我已将XAML元素作为原始问题的编辑添加)。也许是ItemContainerStyle的某些问题? - ThunderFrame
一种方法是将控件暂时放置在一个具有无限大小的容器中(例如Canvas)。 - Kevin Gosse
1个回答

1
我对您的代码进行了一些实验。问题似乎在于您使用 element.ActualHeightelement.ActualWidth 来构建位图,这当然等于 TreeView 控件的当前大小(而不是实际更长的内容面板),因此输出中呈现的就是当前大小。
为了解决这个问题,我将 TreeViewScrollViewer.VerticalScrollBarVisibility 设置为 Disabled,然后将其包装在 ScrollViewer 中。这将使您的 TreeView 具有所需的全高度,并仍然具有滚动条以滚动它。现在,当您使用 ActualWidth 和 ActualHeight 构造位图时,您会得到一个全尺寸的位图,并且渲染它会得到所需的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接