0

我想拍摄尚未显示的 UserControl 的快照。那是我的代码:

    public Screenshot(MyViewModel viewModel)
    {
        if (viewModel == null)
            return;

        // Create a TabControl, where View is hosted in
        var visualTab = new TabControl();
        visualTab.Width = FrameworkAdjustments.VisualSize.Width;
        visualTab.Height = FrameworkAdjustments.VisualSize.Height;
        visualTab.TabStripPlacement = Dock.Left;

        // Tabs should only be shown, if there are more than one 'SubView'
        Visibility tabVisibility = Visibility.Collapsed;
        if (viewModel.SubViews.Count > 1)
            tabVisibility = Visibility.Visible;
        foreach (var subView in viewModel.SubViews)
        {
            var tab = new TabItem();
            tab.Header = subView.TranslatedId;    // multilanguage header
            tab.Visibility = tabVisibility;
            if (subView.Id == viewModel.ActiveSubView.Id)
            {
                tab.IsSelected = true;
                // Without the following line my UI works, but my TabControl is empty.
                tab.Content = ViewManager.GetViewById(subView.Id);
                // ViewManager.GetViewById(subView.Id); returns a UserControl
            }

            tab.Measure(FrameworkAdjustments.VisualSize);
            tab.Arrange(new Rect(FrameworkAdjustments.VisualSize));
            visualTab.Items.Add(tab);
        }

        _ContentCtrl = new ContentControl() { Width = FrameworkAdjustments.VisualSize.Width, Height = FrameworkAdjustments.VisualSize.Height };
        _ContentCtrl.Content = visualTab;
        _ContentCtrl.Measure(FrameworkAdjustments.VisualSize);
        _ContentCtrl.Arrange(new Rect(FrameworkAdjustments.VisualSize));

        RenderTargetBitmap bmp = new RenderTargetBitmap((int)FrameworkAdjustments.VisualSize.Width, (int)FrameworkAdjustments.VisualSize.Height, 96, 96, PixelFormats.Pbgra32);
        bmp.Render(_ContentCtrl);

        this.ItemBrush = new ImageBrush(bmp);
    }

当我启动我的应用程序时,此代码会为每个“MyViewModel”运行。“MyViewModel”包含一个“子视图”列表,它们是选项卡的内容,它们包含一个“FunctionKeyBar”,其按钮可以通过使用“F1”到“F12”来激活。但是在创建我的屏幕截图后,我不能再使用 F1 到 F12 了。还有其他问题,比如切换语言。是否有其他方法可以创建尚未出现的控件的快照?

感谢所有回复。

问候本尼

4

2 回答 2

2

方法:设置Margin为负以保持隐藏,将控件添加到网格/任何其他容器。

在此处输入图像描述

按着这些次序 :

1)创建一个Task以创建并将您的添加ContentControlGrid.

2) 调用用户自定义CaptureScreen ()函数。

3)Visibility不得隐藏/折叠。Margin可以否定隐藏控件。

在这个例子中,我在一个Button.Click.

async private void Button_Click(object sender, RoutedEventArgs e)
{
    Task<ContentControl> t = AddContentControl();
    ContentControl ctrl = await t;

    RenderTargetBitmap bmp = CaptureScreen(ctrl, 5000, 5000);
    Img.Source = bmp;
}
/* Add the ContentControl to the Grid, and keep it hidden using neg. Margin */
private Task<ContentControl> AddContentControl()
{
    Task<ContentControl> task = Task.Factory.StartNew(() =>
    {
        ContentControl ctrl = null;
        Dispatcher.Invoke(() =>
        {

            ctrl = new ContentControl() { Content = "Not shown", Width = 100, Height = 25, Margin = new Thickness(-8888, 53, 0, 0) };
            Grd.Children.Add(ctrl);
        });

        return ctrl;
    });

    return task;
}
/* Important , wont work with Visibility.Collapse or Hidden */
private static RenderTargetBitmap CaptureScreen(Visual target, double dpiX, double dpiY)
{
    if (target == null)
    {
        return null;
    }
    Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),
                                                    (int)(bounds.Height * dpiY / 96.0),
                                                    dpiX,
                                                    dpiY,
                                                    PixelFormats.Pbgra32);
    DrawingVisual dv = new DrawingVisual();
    using (DrawingContext ctx = dv.RenderOpen())
    {
        VisualBrush vb = new VisualBrush(target);
        ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
    }
    rtb.Render(dv);
    return rtb;
}
于 2016-04-20T10:12:53.377 回答
1

现在我找到了解决方案,感谢 AnjumSKan。我拿了他的代码,稍微改了一下。正如我所说,我需要在应用程序启动或文化改变时创建快照,并且我有多个视图。在我的 FunctionAddContentControl中,我将 Content 添加到具有负边距的 TabControl 中。添加我调用的结尾HiddenTab.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new Action(CreateSnapshotOnRender));

('HiddenTab' 是我的 TabControl,未向用户显示)。这调用了一个名为 的函数CreateSnapshotOnRender,我从中调用 AnjumSKhan 的CaptureScreen- 方法。之后,我再次AddContentControl使用我的下一个内容调用该函数。这看起来如下:

private void CreateScreenshotOnRender()
    {
        HiddenTab.Measure(ViewSize);
        HiddenTab.Arrange(new Rect(ViewSize));
        var snapshot = CaptureScreen(HiddenTab, dpiX, dpiY); 
/* Do anything with snapshot */
        _Index++;      // counter to know thich view is next
        CreateAllScreenshots();
    }

再次感谢 AnjumSKan,因为你把我带到了这里。这就是为什么我将您的答案标记为正确答案。

于 2016-04-28T04:55:25.773 回答