wpf - custom - Agregar un diccionario combinado a un diccionario combinado
xamarin forms custom theme (3)
Parece que no puedo agregar un diccionario fusionado a una colección de diccionarios fusionados dentro de XAML.
Theme.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Mine;component/Themes/Palette.Blue.xaml"/>
<ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/>
</ResourceDictionary.MergedDictionaries>
Recursos de la aplicación
<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 Appication.Resources MergedDictionary (comenta el theme.xaml y descomenta los otros dos diccionarios) ambos se 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.
Este es un error de optimización, mira this enlace
En la creación de cada objeto en XAML, si está presente un estilo predeterminado (es decir, estilo con una clave de Tipo), se debe aplicar ese estilo. Como se puede imaginar hay varias optimizaciones de rendimiento para hacer que la búsqueda (implícita) sea lo más ligera posible. Una de ellas es que no buscamos los Diccionarios de recursos a menos que estén marcados como "que contienen estilos predeterminados". Hay un error: si todos sus estilos predeterminados están anidados en diccionarios combinados de tres niveles (o más profundos), el diccionario superior no se marca, por lo que la búsqueda se salta. La solución alternativa es poner un estilo predeterminado en algo, cualquier cosa, en el diccionario raíz.
Entonces, agregar un estilo ficticio al diccionario raíz corrige esto. 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>
Si esto sucede en uno de sus controles, he encontrado que otra solución es establecer la propiedad DefaultStyleKey
en nulo:
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(null));
No tengo idea de por qué funciona, ¡pero parece que sí!
Su código de muestra tiene un doble signo igual en el origen del diccionario de recursos fusionado 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 complicado 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 vincula recursos de diferentes ensamblajes, se verá diferente. En realidad, en ese caso, sugeriría buscar fusionar sus diccionarios en el código subyacente.