1

我现在正在玩一个想法,但我遇到了砖墙。我正在使用控制台应用程序在内存中创建视觉控件(准确地说是 DevExpress 图表控件),然后我尝试使用 VisualBrush 将该控件保存到图像中,但它不起作用,因为(我假设)控件不被绘制到屏幕上。

我把我的代码放在下面,所以你知道我现在在哪里。有谁知道我如何使用控制台应用程序将此控件保存到图像(最好是 jpg,但任何事情都可以......)?我真的不想为了能够保存它而将它渲染到屏幕上,即使是一毫秒...

static void sl_CreateDetail(FrameworkElement chartControl1, CreateAreaEventArgs e)
{
        var brush = new VisualBrush(chartControl1);
        var visual = new DrawingVisual();
        DrawingContext context = visual.RenderOpen();

        context.DrawRectangle(brush, null,
            new Rect(0, 0, chartControl1.ActualWidth, chartControl1.ActualHeight));
        context.Close();

        var bmp = new RenderTargetBitmap((int)chartControl1.ActualWidth,
            (int)chartControl1.ActualHeight, 96, 96, PixelFormats.Pbgra32);

        bmp.Render(visual);
        e.Data = bmp;
}
4

2 回答 2

0

在呈现控件之前,您必须通过调用MeasureArrange手动进行布局。这要求您指定所需的控件大小,例如通过显式设置其 Width 和 Height 属性。

不需要VisualBrush和DrawingVisual,可以直接将控件渲染到RenderTargetBitmap。

chartControl1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
chartControl1.Arrange(new Rect(0, 0, chartControl1.Width, chartControl1.Height));
chartControl1.UpdateLayout();

var bmp = new RenderTargetBitmap((int)chartControl1.ActualWidth,
    (int)chartControl1.ActualHeight, 96, 96, PixelFormats.Pbgra32);

bmp.Render(chartControl1);

如果控件在布局期间(在 Measure 中)计算首选大小,您也许可以使用其DesiredSize属性进行渲染。

chartControl1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
chartControl1.Arrange(new Rect(new Point(), chartControl1.DesiredSize));
chartControl1.UpdateLayout();

另请注意,渲染线程的ApartmentState必须为STA. 在控制台应用程序中,您可以简单地将STAThread属性应用于 Main 方法。

[STAThread]
static void Main(string[] args)
{
    ...
}
于 2012-10-07T07:37:24.087 回答
0

我尝试了 Measure()、Arrange() 等,然后发现如果 Visual 有父级,这些都可以工作!在我的情况下,我从一个容器中删除了 Visual,更新了它的属性(颜色等),然后尝试将它用作 VisualBrush,但它没有得到更新。在 Measure() 和 Arrange() 期间将其留在原始容器中修复它(即使它全部在屏幕外完成)。

于 2013-06-24T13:16:22.063 回答