Come rendere un UserControl WPF a una bitmap senza creare una finestra

Come posso rendere un UserControl WPF a una bitmap senza creare una finestra? Devo eseguire il rendering di un UserControl WPF e caricarlo su un altro programma. Le bitmap verranno renderizzate tramite un servizio Windows, quindi la creazione di una finestra non è un’opzione (so che esistono modi per “virtualmente” creare windows, ma sfortunatamente tutto ciò che chiama un comando per creare una finestra NON è un’opzione nel mio caso). C’è un modo per RENDERE UserControl senza vincolarlo a una finestra?

Hai provato a far ruotare un’istanza del controllo utente e fare qualcosa del genere:

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

Sembra che tu debba misurare, organizzare. Questo ha funzionato per me.

Finito con un HwndHost senza windows effettive.

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

Apparentemente, se si chiama control.UpdateLayout() dopo aver misurato e organizzato, il controllo utente non deve necessariamente trovarsi in nessuna finestra.

Basato sulla soluzione IDWMaster, l’ho fatto in modo leggermente diverso usando System.Windows.Forms.UserControl . Altrimenti i binding non erano aggiornati quando avveniva l’esportazione in bitmap. Questo funziona per me ( this è il controllo WPF da renderizzare):

 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;