简体   繁体   English

如何在不创建窗口的情况下将WPF UserControl呈现到位图

[英]How to render a WPF UserControl to a bitmap without creating a window

How can I render a WPF UserControl to a bitmap without creating a window? 如何在不创建窗口的情况下将WPF UserControl呈现到位图? I need to render a WPF UserControl and upload it to another program. 我需要渲染一个WPF UserControl并将其上传到另一个程序。 The bitmaps will be rendered through a Windows Service, so creating a window is not an option (I know there's ways to 'virtually' create windows, but unfortunately anything that calls a command to create a window is NOT an option in my case). 位图将通过Windows服务呈现,因此创建一个窗口不是一个选项(我知道有几种方法'虚拟'创建窗口,但不幸的是,任何调用命令创建窗口的东西都不是我的选择。 Is there a way to RENDER the UserControl without binding it to a Window? 有没有办法将UserControl RENDER而不将其绑定到Window?

Have you tried spinning up an instance of the user control and doing something like this: 您是否尝试过旋转用户控件的实例并执行以下操作:

UserControl control = new UserControl1();

control.Measure(new Size(300, 300));
control.Arrange(new Rect(new Size(300,300)));

RenderTargetBitmap bmp = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);

bmp.Render(control);

var encoder = new PngBitmapEncoder();

encoder.Frames.Add(BitmapFrame.Create(bmp));

using (Stream stm = File.Create(@"c:\test.png"))
   encoder.Save(stm);

It looks like you need to Measure, Arrange. 看起来你需要测量,安排。 This worked for me. 这对我有用。

Ended up using an HwndHost with no actual window. 使用没有实际窗口的HwndHost结束。

void cwind()
    {
        Application myapp = new Application();
        mrenderer = new WPFRenderer();
        mrenderer.Width = 256;
        mrenderer.Height = 256;

        HwndSourceParameters myparms = new HwndSourceParameters();
        HwndSource msrc = new HwndSource(myparms);
        myparms.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);

        msrc.RootVisual = mrenderer;
        myapp.Run();
    }
    static IntPtr ApplicationMessageFilter(
IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        return IntPtr.Zero;
    }

显然,如果在测量和排列后调用control.UpdateLayout() ,则用户控件不需要在任何窗口中。

Based on IDWMaster's solution I did it a bit differently using the System.Windows.Forms.UserControl . 基于IDWMaster的解决方案,我使用System.Windows.Forms.UserControl做了一点不同的工作。 Otherwise the bindings were not up-to-date when the export to bitmap happened. 否则,当导出到位图时,绑定不是最新的。 This works for me ( this is the WPF control to render): 这对我有用( this是要渲染的WPF控件):

System.Windows.Forms.UserControl controlContainer = new System.Windows.Forms.UserControl();
controlContainer.Width = width;
controlContainer.Height = height;
controlContainer.Load += delegate(object sender, EventArgs e)
{
    this.Dispatcher.BeginInvoke((Action)delegate
    {
        using (FileStream fs = new FileStream(path, FileMode.Create))
        {
            RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
            bmp.Render(this);
            BitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bmp));
            encoder.Save(fs);
            controlContainer.Dispose();
        }
    }, DispatcherPriority.Background);
};

controlContainer.Controls.Add(new ElementHost() { Child = this, Dock = System.Windows.Forms.DockStyle.Fill });
IntPtr handle = controlContainer.Handle;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM