WPF屏幕截图不包括标题栏

4
我实现了第一个答案中的代码来回答这个问题,它的表现很好,但是它不包括标题栏,而这对我的需求非常重要。有没有人知道我做错了什么?
我更新了我的示例,展示了所有被注释掉的失败尝试。 下面是我的代码:
Window shellView = Application.Current.MainWindow;

Rect bounds = VisualTreeHelper.GetDescendantBounds(shellView);
//Rect bounds = new Rect(new Size(shellView.ActualWidth, shellView.ActualHeight));
//Rect bounds = shellView.RestoreBounds;
//Rect bounds = VisualTreeHelper.GetContentBounds(shellView);
//Rect bounds = new Rect(new Size(VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualWidth,
//    VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualHeight));

RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
DrawingVisual visual = new DrawingVisual();

string fileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
{
    using (DrawingContext context = visual.RenderOpen())
    {
        VisualBrush visualBrush = new VisualBrush(shellView);
        context.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
    }

    renderTarget.Render(visual);
    PngBitmapEncoder bitmapEncoder = new PngBitmapEncoder();
    bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

    using (Stream stm = File.Create(fileName))
    {
        bitmapEncoder.Save(stm);
    }
}

根据XAMIMAX的要求,以下是我可以分享的经过更改名称的XAML代码:

<Window x:Class="MyProject.Shell.Views.Shell.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ap="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
        xmlns:controls="clr-namespace:MyProject.Common.Support.Controls;assembly=MyProject.Common.Support"
        xmlns:converters="clr-namespace:MyProject.Common.Support.Converters;assembly=MyProject.Common.Support"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:dts="clr-namespace:MyProject.Common.Support.DataTemplateSelectors;assembly=MyProject.Common.Support"
        xmlns:enums="clr-namespace:MyProject.Shell.Enums"
        xmlns:enums1="clr-namespace:MyProject.Common.Support.Enums;assembly=MyProject.Common.Support"
        xmlns:ikriv="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
        xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:m="clr-namespace:MyProject.Common.Support.MarkupExtensions;assembly=MyProject.Common.Support"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:resources="clr-namespace:MyProject.Shell.Views.Shell.Resources"
        xmlns:ss="clr-namespace:MyProject.Common.Support.StyleSelectors;assembly=MyProject.Common.Support"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:views="clr-namespace:MyProject.NotificationModule.Client.Views;assembly=MyProject.NotificationModule.Client"
        xmlns:constants="clr-namespace:MyProject.Shell"
        x:Name="shell"
        Title="{Binding MyProjectApplicationTitle}"
        Width="1024"
        Height="768"
        MinWidth="800"
        MinHeight="600"
        Background="{DynamicResource PrimarySolidColorBrush}"
        Icon="/Resources/Embedded/MyProject.ico"
        mc:Ignorable="d">

        <controls:LocalizationScope.Content>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <Grid.Children>

                    <Grid Grid.Row="1">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding NavigationBarWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                              MinWidth="38"
                                              MaxWidth="400" />
                    </Grid>

                </Grid.Children>
            </Grid>
        </controls:LocalizationScope.Content>
</Window>

希望这些XAML能够提供足够的帮助。我也尝试了这个链接中的示例生成WPF窗口截图,但结果相同:没有标题栏。


在我的电脑上,标题栏也显示出来了。我能看一下你的窗口代码吗?这样我就能理解我们之间的差别了。 - nalka
你修改了窗口以拥有自定义标题栏吗?(这可以通过使用 WindowStyle="None"AllowsTransparency="True" 来实现) - nalka
不。使用标准标题栏:Title="{Binding MyApplicationTitle}" - Phil N DeBlanc
@XAMLMAX,你看到我帖子里的链接了吗?这个代码基本上和之前一模一样,只是加了一个SaveFileDialog来让用户选择保存截图的位置。所以并不是混搭代码。我尝试过这个:Rect bounds = new Rect(new Size(shellView.Width, shellView.Height)); 但标题栏还是没有显示出来。 - Phil N DeBlanc
@XAMlMAX ActualWidth也不起作用。我已经添加了我的窗口的XAML头信息并修剪了代码。希望这对你有足够的帮助。 - Phil N DeBlanc
显示剩余5条评论
1个回答

1
感谢@Clemens给我发送的链接,我能够使用该页面上的一些代码来编写这个工作方法。它抓取了比活动窗口多几个像素,但对我来说可以工作!
    private void TakeScreenshot()
    {
        var rect = new Rect();
        GetWindowRect(GetForegroundWindow(), ref rect);

        var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
        var result = new Bitmap(bounds.Width, bounds.Height);
        using (var graphics = Graphics.FromImage(result))
        {
            graphics.CopyFromScreen(new System.Drawing.Point(bounds.Left, bounds.Top), System.Drawing.Point.Empty, bounds.Size);
        }

        string fileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
        if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
        {

            result.Save(fileName, ImageFormat.Png);

            _dialogService.ShowInfoDialog(_localizationService["Shell.Views.Shell.HelpMenu.ScreenshotSaved"] + $"{fileName}");
        }
    }

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