我怎样才能没有创build一个窗口的WPF UserControl的位图? 我需要呈现一个WPF UserControl并将其上传到另一个程序。 位图将通过Windows服务呈现,所以创build窗口不是一个选项(我知道有'虚拟'创build窗口的方法,但不幸的是,调用命令来创build窗口的任何东西都不是我的情况下的选项)。 有没有一种方法来呈现UserControl而不绑定到一个窗口?
你有没有尝试旋转用户控件的一个实例,并做这样的事情:
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);
看起来你需要测量,排列。 这对我有效。
结束使用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()
,则用户控件不需要在任何窗口中。
基于IDWMaster的解决方案,我使用System.Windows.Forms.UserControl
做了一点改变。 否则,导出到位图时绑定不是最新的。 这适用于我( 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;