Estilos de todo el ensamblaje / nivel de raíz en la biblioteca de clases de WPF

Tengo un ensamblaje de biblioteca de clases C # (2008 / .NET 3.5) que admite WPF (basado en este artículo ).
He creado varias ventanas y ahora estoy intentando crear un conjunto de estilos común para ellas. Sin embargo, como es una biblioteca de clases (en lugar de una aplicación WPF), no tengo un app.xaml (y su aplicación contenida y sus correspondientes recursos de aplicación) en los que almacenar estos estilos para el acceso global.

Entonces: ¿Cómo puedo crear un conjunto de definiciones de estilo de nivel superior que puedan ver todos los archivos xaml en el ensamblaje, dado que no tengo app.xaml (ver más arriba) ? ¿Y / o es posible agregar un app.xaml que funcione a una biblioteca de clases?

Para su información, intenté crear un ResourceDictionary en un archivo ResourceDictionary.xaml, e incluirlo en cada ventana dentro de un bloque “Window.Resources”. Eso resultó para resolver el estilo de los botones, etc … pero no para la ventana que lo rodea. Puedo poner Style="{StaticResource MyWindowStyle}" en el bloque de apertura de la ventana, y se comstack y aparece bien en la ventana de diseño de VS, pero durante el tiempo de ejecución real obtengo una excepción de análisis (no se pudo encontrar MyWindowStyle; supongo que Visual Studio ve el diccionario incluido después de la línea en cuestión, pero la CRL hace las cosas de forma más secuencial y, por lo tanto, aún no ha cargado el ResourceDictionary).


Gracias por las ideas, pero aún así no hay … aparentemente, una biblioteca de clases NO admite implícitamente el uso de generic.xaml. Agregué generic.xaml a mi proyecto de biblioteca de clases y configuré su Build Action en “Resource”. Contiene:

      

La ventana xaml que quiero que use el tema se ve así:

  ...Buttons, etc...  

Aunque la ventana de VS Design no muestra la ventana con el estilo MyWindow (es decir, fondo negro), se comstack bien y se inicia. Sin embargo, cuando la aplicación que contiene esta biblioteca de clases realiza una llamada que hace que se muestre esta ventana, obtengo una excepción XamlParseException:

No se puede encontrar el recurso llamado ‘{MyWindow}’.

También intenté omitir el parámetro Estilo, para ver si la ventana usaría el estilo de manera predeterminada (y lo intenté con la clave x: Key en generic.xaml incluida y sin ella). No hay errores, pero cualquier cosa definida en generic.xaml tampoco apareció.

¿Estoy haciendo algo mal aquí, o alguna otra idea sobre cómo se podría permitir el uso de estilos personalizados comunes en una ventana (es decir, no es necesario definir los estilos en el xaml de cada ventana)? Con la advertencia de que esto NO es una ¿solicitud?

Intenta agregar

 Style={DynamicResource MyStyle} 

No puedes usar un StaticResource en este caso.

Esto suena como un trabajo para la tematización.

  1. Agregue un /themes/generic.xaml ResourceDictionary a su proyecto.
  2. Agregue lo siguiente a AssemblyInfo.cs: [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
  3. ?
  4. ¡Lucro!

Cualquier control que agregue a genérico será utilizado por todos los controles. También puede crear temas específicos del perfil (Luna, Aero, etc.) incluyendo un archivo ResourceDictionary con el nombre del tema correcto en el directorio de themes .

Aquí hay un enlace a más información: crear y aplicar temas personalizados

Si no tiene una app.xaml, todavía puede cargarla en los recursos de nivel de aplicación, pero tiene que escribir código (no xaml) para hacerlo, similar a esto …

 void LoadIt() { ResourceDictionary MyResourceDictionary = new ResourceDictionary(); MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative); App.Current.Resources.MergedDictionaries.Add( MyResourceDictionary ) } 

Echa un vistazo a este sitio para ver un ejemplo: http://ascendedguard.com/2007/08/one-of-nice-features-about-wpf-is-how.html

El Dr. WPF (o la persona anteriormente conocida como Dr. WPF) tiene una excelente publicación sobre el tema.

Aquí hay un extracto de la publicación donde crean el objeto Aplicación y agregan recursos:

 if (Application.Current == null) { // create the Application object new Application(); // merge in your application resources Application.Current.Resources.MergedDictionaries.Add( Application.LoadComponent( new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml", UriKind.Relative)) as ResourceDictionary); } 

Como mi ensamblaje está alojado a través de interoperabilidad, tuve que agregar la configuración de ShutdownMode de la siguiente manera y apagar cuando haya terminado:

 new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown }; 

Funcionó a las mil maravillas.

Si lo carga en Window.Resource, el diccionario solo está disponible para los elementos secundarios de esa ventana. Necesitas tenerlo disponible para la ventana y sus hijos.

Intenta cargarlo en tu archivo app.xaml. Eso debería convertirlo en un recurso de nivel de aplicación, no en un recurso de nivel de ventana.

Así que después de pasar mucho tiempo finalmente me di cuenta de esto. Así es cómo:

  1. En la biblioteca de controles de WPF, agregue una nueva carpeta llamada themes .
  2. Dentro de la carpeta de themes , agregue un diccionario de recursos llamado generic.xaml .
  3. Dentro de generic.xaml , agregue su recurso usando la siguiente syntax:

      
  4. En su control, use la siguiente syntax para acceder a este recurso:

     Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}" 

Cosas a tener en cuenta:

  1. Visual Studio normalmente realiza los pasos 1 y 2 automáticamente cuando crea una nueva biblioteca de controles de WPF.
  2. No entiendo completamente el propósito del primer parámetro de ComponentResourceKey , pero es obligatorio. Usa el nombre del control que consumirá este recurso.
  3. El diseñador de Visual Studio no pudo localizar el recurso en mi caso. Podría ser un problema de caché, no estoy seguro. En el tiempo de ejecución, sin embargo, funciona perfectamente.
  4. Puede leer más detalles sobre esta syntax en este artículo de MSDN .

Espero que esto haga algunas vidas más fáciles.