Visual brush using control which isn't rendered?

为君一笑 提交于 2019-12-04 05:01:55

问题


I'm playing around with an idea at the moment and I've hit a brick wall. I'm using a console app to create a visual control (DevExpress chartcontrol to be precise) in memory, I'm then trying to save that control to an image using a VisualBrush but it won't work because (I assume) the control isn't drawn to the screen.

I've put my code in below so you know where I am at the moment. Does anyone know how I could possibly save this control to an image (ideally jpg, but anything will do...) using a console app? I really don't want to have to render it to the screen even for a millisecond just to be able to save it...

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;
}

回答1:


Before rendering the control you would have to manually do its layout by calling Measure and Arrange. This requires that you specify the desired size of the control, e.g. by explicitly setting its Width and Height properties.

There is no need for VisualBrush and DrawingVisual, you can directly render the control to the 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);

If the control calculates a preferred size during layout (in Measure), you could perhaps use its DesiredSize property for rendering.

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

Note also that the rendering thread's ApartmentState must be STA. In a console application you could simply apply the STAThread attribute to the Main method.

[STAThread]
static void Main(string[] args)
{
    ...
}



回答2:


I tried Measure(), Arrange(), etc, then discovered that these DO work if the Visual has a parent! In my case I was removing the Visual from one container, updating its properties (colour, etc), then trying to use it as a VisualBrush and it wasn't getting updated. Leaving it in the original container for the duration of Measure() and Arrange() fixed it (even though it was all done offscreen).



来源:https://stackoverflow.com/questions/12764554/visual-brush-using-control-which-isnt-rendered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!