Modo de procesamiento de software – WPF

Tengo un control de usuario WPF para el que necesito forzar la renderización en RenderMode.SoftwareOnly . Como uso .NET 3.5, tuve que hacer algo como,

 var hwndSource = PresentationSource.FromVisual(this) as HwndSource; if (hwndSource != null) { hwndSource.CompositionTarget.RenderMode = RenderMode.SoftwareOnly; } 

Pero esto no funciona en mi aplicación. El progtwig WPF se bloquea en algunas máquinas y la desactivación de la aceleración de hardware en el nivel de registro parece solucionar el problema.

El código anterior está escrito en el evento Loaded de la ventana. Si estoy en lo correcto, el evento Loaded ocurre después de que se procesen los controles ( MSDN ). Entonces, ¿tiene sentido tener el código anterior en ese caso? Si no, ¿qué evento sería apropiado para eso?

Además, ¿la configuración de RenderMode en un visual afectará a los niños? ¿O debo configurar esto específicamente para cada elemento secundario?

¡Cualquier ayuda sería genial!

Esto es lo que hicimos:

  private void Window_Loaded(object sender, RoutedEventArgs e) { if (ForceSoftwareRendering) { HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; HwndTarget hwndTarget = hwndSource.CompositionTarget; hwndTarget.RenderMode = RenderMode.SoftwareOnly; } } 

Funcionó bien para nosotros, EXCEPTO … Esto debe hacerse para cada ventana. En .NET 3.5 no había forma de que la configuración tuviese efecto en toda la aplicación. Y hay algunas ventanas sobre las que no tendrá tanto control, por ejemplo, haga clic con el botón derecho en las ventanas de “contexto”. Descubrimos que no había una buena solución para .NET 3.5, excepto la configuración del registro.

Editado

Aquí está la lógica que usamos para determinar cuándo forzar la representación del software. Fue sugerido por un ingeniero de soporte de Microsoft.

 public bool ForceSoftwareRendering { get { int renderingTier = (System.Windows.Media.RenderCapability.Tier >> 16); return renderingTier == 0; } } 

En .NET 4, Microsoft agregó una configuración para toda la aplicación que funciona perfectamente para nosotros. Es una opción mucho mejor porque no necesita configurarlo en todas las ventanas. Usted acaba de configurarlo una vez y se aplica a todas las ventanas.

http://msdn.microsoft.com/en-us/library/system.windows.media.renderoptions.processrendermode(VS.100).aspx

Editado

La nueva propiedad .NET 4.0 se puede establecer al inicio de la aplicación de esta manera:

 public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { if (ForceSoftwareRendering) RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; } } 

También puede deshabilitar la representación de hardware para todo el proceso poniendo la siguiente línea en el manejador de inicio de la aplicación:

 RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; 

También es posible cambiar durante el tiempo de ejecución

evento-problema
Para el hwnd-source que falta, intente lo siguiente:

  Dispatcher.BeginInvoke(new Action(delegate { HwndSource hwndSource = PresentationSource.FromVisual(this) as System.Windows.Interop.HwndSource; if (null == hwndSource) { throw new InvalidOperationException("No HWND"); } HwndTarget hwndTarget = hwndSource.CompositionTarget; hwndTarget.RenderMode = RenderMode.SoftwareOnly; }),System.Windows.Threading.DispatcherPriority.ContextIdle, null); 

scope de RenderMode
Por lo que yo sé, solo hay una ventana de Win32 para cada ventana de WPF y todo el rest se vuelve nativo en WPF. Es por eso que creo que la configuración de RenderMode refiere a todo el contenido en la ventana donde estaba el visual. El scope es en este caso en toda la ventana.