使用未呈现的控件的可视刷?

时间:2012-10-06 22:47:12

标签: wpf image wpf-controls rendering visualbrush

我现在正在玩弄一个想法而且我已经碰到了一堵砖墙。我正在使用一个控制台应用程序在内存中创建一个可视控件(精确的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;
}

2 个答案:

答案 0 :(得分:0)

在渲染控件之前,您必须通过调用MeasureArrange手动执行其布局。这要求您指定所需的控件大小,例如通过明确设置其宽度和高度属性。

不需要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)
{
    ...
}

答案 1 :(得分:0)

我尝试了Measure(),Arrange()等,然后发现如果Visual有父母,这些DO会起作用!在我的情况下,我从一个容器中删除Visual,更新其属性(颜色等),然后尝试将其用作VisualBrush并且它没有得到更新。在Measure()和Arrange()的持续时间内将其保留在原始容器中(即使它已在屏幕外完成)。