into form wpf winforms interop resources elementhost

into - wpf in winforms



Carga/Uso de Diccionarios de recursos desde un control WPF alojado en WinForms (3)

Para cargar diccionarios de recursos que están incrustados en el ensamblaje, he utilizado el siguiente fragmento de código para cargarlos durante el tiempo de ejecución:

//using System.Windows ResourceDictionary dict = new ResourceDictionary(); dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative); Application.Current.Resources.MergedDictionaries.Add(dict);

Esto también funcionaría para cargar un diccionario en el directorio ejecutable.

Tengo una aplicación de Windows Forms que necesita alojar un control WPF en tiempo de ejecución. Tengo el alojamiento básico y la interacción completa (usando un control ElementHost) y todo funciona bien hasta que intento hacer algo que requiere que el control WPF haga uso de algunos diccionarios de recursos personalizados que están definidos. (El control de WPF y todos sus diccionarios de recursos están todos definidos en la misma DLL de la Biblioteca de control de WPF).

Tan pronto como eso sucede, recibo un montón de errores que se ven así:

System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey=''DocumentHeaderInterestStyle''

He encontrado una referencia (el enlace parece estar muerto debido al archivo , este podría ser el mismo artículo al que se hizo referencia originalmente). eso habla de esto, pero parece que el artículo se acerca más a las cosas desde el lado de WPF, pero realmente no quiero tener que hacer cambios en el control de WPF ya que todo funciona en una aplicación WPF independiente.

Si la única forma de lograr esto es hacer cambios en el lado de WPF, puedo hacer esos cambios (no soy responsable de la biblioteca de control de WPF, sino de la persona que también trabaja para la misma empresa, así que no hay otro problema). que obtener su tiempo para hacer los cambios.) pero espero algo que pueda hacer en WinForms para que esto funcione.

La biblioteca de control de WPF tiene un archivo de diccionario de recursos llamado "Default.xaml" definido en el proyecto con las siguientes propiedades:

Acción de compilación: Copiar página al directorio de salida: no copiar herramienta personalizada: MSBuild: compilar

La aplicación WPF autónoma tiene la siguiente entrada en su archivo App.xaml:

<ResourceDictionary x:Uid="ResourceDictionary_1"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary x:Uid="ResourceDictionary_2" Source="/SmartClient.Infrastructure;component/Themes/Default.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>

Parece que la biblioteca de control ya debería saber cómo obtener sus recursos. Al utilizar Resources.MergedDictionaries.Add () parece que debería funcionar, pero ¿dónde obtengo la instancia del diccionario existente?


Suponiendo que sepa qué recursos necesita (suena como lo hace), solo debe poder "inyectarlos" usted mismo. Algo como:

var wpfControl = new ...; wpfControl.Resources.Add(...); elementHost.Child = wpfControl;

En su pregunta menciona que existen diccionarios de recursos existentes en la biblioteca de control. Si es así, puedes hacer esto:

var wpfControl = new ...; wpfControl.Resources.MergedDictionaries.Add(/* instance of existing dictionary */); elementHost.Child = wpfControl;


Suponiendo que tiene sus estilos / plantillas / recursos divididos en muchos archivos, Resources1.xaml y Resources2.xaml , puede agregarlos en un solo diccionario de recursos ( AllResources.xaml ). Un diccionario de recursos se puede agregar fácilmente a un control en el archivo xaml del control. Vea el ejemplo a continuación.

(!) Establezca las acciones de compilación Resources1.xaml , Resources2.xaml y AllResources.xaml en Page

Resources1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}"> ... </ControlTemplate> <LinearGradientBrush x:Key="VerticalScrollBarBackground" EndPoint="1,0" StartPoint="0,0"> ... </LinearGradientBrush> <Style x:Key="StyleA" TargetType="{x:Type ScrollBar}"> ... </Style> </ResourceDictionary>

Recursos2.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="StyleB" TargetType="{x:Type ScrollBar}"> ... </Style> <Style x:Key="StyleC" TargetType="{x:Type TextBlock}"> ... </Style> </ResourceDictionary>

AllResources.xaml

Agregue fuentes de diccionarios de recursos como rutas relativas a AllResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources1.xaml" /> <ResourceDictionary Source="Resources2.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>

Finalmente en su UserControl

<UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/projectName;component/PathToTheFileRelativeToProjectRootDirectory/AllResources.xaml <converters:StringToUpperCaseConverter x:Key="StringToUpperCaseConverter" /> <converters:LocalizationEntryToStringCaseConverter x:Key="LocalizationEntryToStringCaseConverter" /> </ResourceDictionary> </UserControl.Resources>