2010-08-05 23 views
20

Parece que no puedo agregar un diccionario fusionado a una colección de diccionarios fusionados dentro de XAML.Agregar un diccionario combinado a un diccionario combinado

Theme.xaml

<ResourceDictionary.MergedDictionaries> 
    <ResourceDictionary Source="/Mine;component/Themes/Palette.Blue.xaml"/> 
    <ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/> 
</ResourceDictionary.MergedDictionaries> 

de recursos de aplicaciones

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/Mine;component/Themes/Theme.xaml"/> 
      <!-- 
      <ResourceDictionary Source=="/Mine;component/Themes/Palette.Blue.xaml"/> 
      <ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/> 
      --> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Nota: si pongo ambos ResourceDictionaries en el Appication.Resources MergedDictionary (comente el tema .xaml y descomentar el othe dos diccionarios) ambos cargan correctamente. Sin embargo, por la forma en que se definen nuestros recursos, esto puede significar que se cargarán bastantes recursos, y para la carga dinámica me gustaría poder definir las plantillas.

+0

es el código completo del theme.xaml? porque creo que solo necesita iniciar y finalizar con la etiqueta ResourceDictionary para que funcione – dnr3

+0

No, en realidad ya está en un diccionario fusionado. Simplemente no parece heredar. –

Respuesta

34

Este es un error de optimización, ver this enlace

En la creación de cada objeto en XAML, si un estilo por defecto está presente (es decir, estilo w/una llave de tipo) que estilo debe se aplicado. Como puede imagine que hay varias optimizaciones de rendimiento para hacer que (implícita) busque un peso ligero como sea posible. Uno de ellos es que no miramos dentro de Diccionarios de recursos a menos que estén marcados como "que contienen los estilos predeterminados".Hay un error: si todos sus estilos predeterminados están anidados en diccionarios fusionados de tres niveles profundos (o más profundo), el diccionario superior no se marca por lo que la búsqueda se salta. El problema es poner un estilo predeterminado a algo, cualquier cosa, en el diccionario raíz .

Así que la adición de un maniquí del estilo de las correcciones del diccionario esta raíz. Ejemplo

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/Mine;component/Themes/Theme.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
     <!-- Dummy Style, anything you won't use goes --> 
     <Style TargetType="{x:Type Rectangle}" /> 
    </ResourceDictionary> 
</Application.Resources> 
+0

¡A LAS ÚLTIMAS! ¡Gracias por esta respuesta! – Vaccano

+0

Me he encontrado con este problema exacto en .NET 4 y esto lo resuelve. – dex3703

+4

Por alguna razón, esto no funciona para mí. Al iniciar, arroja una excepción (DependencyProperty.UnsetValue no es válido para 'primer plano') lo que indica que los diccionarios de recursos no se están agregando. El mío está configurado de manera idéntica al código anterior en .NET 4.5. – erodewald

0

Su código de muestra tiene un doble signo igual en el origen del diccionario de recursos fusionados App.xaml para Palette.Blue.xaml. Supongo que esto es un error tipográfico para su ejemplo publicado aquí, y no es su verdadero problema.

Puede ser difícil averiguar cómo vincular todos los recursos directamente en XAML. La forma más fácil de hacerlo es desde el panel de Recursos en Blend. Creé una aplicación de Silverlight con archivos de recursos nombrados como su ejemplo, luego abrí el proyecto en Mezcla y los vinculé muy rápidamente.

App.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication1.App"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Theme.xaml" /> 
       <!-- 
       <ResourceDictionary Source="Palette.Blue.xaml"/> 
       <ResourceDictionary Source="Template.xaml"/> 
       --> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

Theme.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="Palette.Blue.xaml"/> 
     <ResourceDictionary Source="Template.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

Template.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style TargetType="TextBox"> 
     <Setter Property="Margin" Value="10" /> 
     <Setter Property="Width" Value="250" /> 
    </Style> 
    <Style x:Key="ReadOnlyTextBoxStyle" TargetType="TextBox"> 
     <Setter Property="IsReadOnly" Value="True" /> 
     <Setter Property="Foreground" Value="Black" /> 
     <Setter Property="IsTabStop" Value="False" /> 
     <Setter Property="Margin" Value="10" /> 
     <Setter Property="Width" Value="250" /> 
    </Style> 
</ResourceDictionary> 

Palette.Blue.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <SolidColorBrush x:Key="BlueSolidColorBrush" Color="SkyBlue" /> 
</ResourceDictionary> 

MainPage.xaml

<UserControl x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel x:Name="LayoutRoot" Background="Honeydew"> 
     <TextBox Text="Read Only Textbox" 
       Style="{StaticResource ReadOnlyTextBoxStyle}" /> 
     <TextBox Text="Blue Textbox" 
       Background="{StaticResource BlueSolidColorBrush}" /> 
     <TextBox Text="Read Only, Blue Textbox" 
       Style="{StaticResource ReadOnlyTextBoxStyle}" 
       Background="{StaticResource BlueSolidColorBrush}" /> 
    </StackPanel> 
</UserControl> 

Por supuesto, si va a asociar recursos de diferentes montajes que se verá diferente. En realidad, en ese caso, sugeriría buscar fusionar sus diccionarios en el código subyacente.

+1

Eso fue aparentemente un error de transcripción (no en el archivo real). Sé cómo agregar cada recurso individualmente (a través de un código detrás o crear un nuevo MergedDictionary) pero el problema parece tener que ver con agregar un Dictuario combinado a un ResourceDictionary cualquiera como la fuente o parte de un diccionario separado fusionado. –

+0

Comprueba la acción de compilación de tus archivos xaml del diccionario. Es posible que deba cambiarlo de la Página predeterminada a Recurso. –

0

Si esto está ocurriendo en uno de sus propios controles que he encontrado que otra solución es establecer la propiedad DefaultStyleKey a nulo:

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(null)); 

no tengo idea de por qué esto funciona, pero ¡parece ser!

Cuestiones relacionadas