2009-02-23 15 views
10

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 toda ella es diccionarios de recursos son definidos en el mismo control WPF Biblioteca de DLL.)Carga/Uso de diccionarios de recursos desde un control WPF alojado en WinForms

Tan pronto como esto sucede, aparece un montón de errores que se parecen a esto:

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

He encontrado un reference (enlace aparece muerto debido al archivo, thispodrí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 manera 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 compañía, así que no es un problema que no sea obtener su tiempo para hacer los cambios.) pero estoy esperando algo que pueda hacer en el lado de WinForms para que esto funcione.

La biblioteca de controles WPF tiene un archivo de diccionario de recursos denominado "Default.xaml" se define en el proyecto con las siguientes propiedades:

ampliar la acción: Página Copiar al Directorio de salida: No copiar Herramienta personalizada: MSBuild : Compilar

el autónomo WPF aplicación tiene la siguiente entrada en el archivo es 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 debe saber cómo t o obtener sus recursos. Al utilizar Resources.MergedDictionaries.Add() parece que debería funcionar, pero ¿dónde obtengo la instancia del diccionario existente?

Respuesta

4

Suponiendo que sepa qué recursos necesita (suena como lo hace), debería ser capaz de "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í, sólo puede hacer esto:

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

dónde estaría el "clave" y "valor" provienen de la llamada que añadir? –

+0

Eso tiene más sentido, pero ¿no deberían fusionarse los diccionarios? He actualizado mi pregunta con más información sobre cómo se ve el aspecto de WPF. –

+0

Eres rockado, funcionó mágicamente. Realmente salvaste mi tiempo. –

1

Para diccionarios de recursos de carga que están incrustados en el conjunto, he utilizado el siguiente fragmento de 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 haría también funcionan para cargar un diccionario en el directorio ejecutable.

0

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.

(!) Conjunto Resources1.xaml, Resources2.xaml y AllResources.xaml construir acciones para 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> 

Resources2.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

Añadir fuentes de diccionarios de recursos como relativos caminos a la 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> 

Por último, 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> 
Cuestiones relacionadas