【问题标题】:Visual brush using control which isn't rendered?使用未呈现的控件的视觉画笔?
【发布时间】:2012-09-27 16:33:53
【问题描述】:

我目前正在考虑一个想法,但我遇到了障碍。我正在使用控制台应用程序在内存中创建视觉控件(准确地说是 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;
}

【问题讨论】:

    标签: wpf image wpf-controls rendering visualbrush


    【解决方案1】:

    在渲染控件之前,您必须通过调用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)
    {
        ...
    }
    

    【讨论】:

    • 我进行了测量/排列,但没有成功。我已经准备好 STA 线程了。我不得不迅速改变我的方法,以便让一些东西适用于一个小型演示。我会改变我的方法并尽快(在接下来的几天内)尝试你的完整建议。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多