Cómo combinar recursos importados y locales en el control de usuario de WPF

82

Estoy escribiendo varios controles de usuario de WPF que necesitan recursos compartidos e individuales.

He descubierto la sintaxis para cargar recursos desde un archivo de recursos separado:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>

Sin embargo, cuando hago esto, no puedo agregar recursos localmente, como:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
    <!-- Doesn't work: -->
    <ControlTemplate x:Key="validationTemplate">
        ...
    </ControlTemplate>
    <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
        ...
    </style>
    ...
</UserControl.Resources>

He echado un vistazo a ResourceDictionary.MergedDictionaries, pero eso solo me permite fusionar más de un diccionario externo, no definir más recursos localmente.

¿Debo estar perdiendo algo trivial?

Cabe mencionar: estoy alojando mis controles de usuario en un proyecto de WinForms, por lo que poner recursos compartidos en App.xaml no es realmente una opción.

Tor Haugen
fuente

Respuestas:

157

Me lo imaginé. La solución involucra MergedDictionaries, pero los detalles deben ser los correctos, como este:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- This works: -->
        <ControlTemplate x:Key="validationTemplate">
            ...
        </ControlTemplate>
        <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
            ...
        </style>
        ...
    </ResourceDictionary>
</UserControl.Resources>

Es decir, los recursos locales deben estar anidados dentro de la etiqueta ResourceDictionary. Entonces, el ejemplo aquí es incorrecto.

Tor Haugen
fuente
5

Puede definir recursos locales dentro de la sección MergedDictionaries:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- import resources from external files -->
            <ResourceDictionary Source="ViewResources.xaml" />

            <ResourceDictionary>
                <!-- put local resources here -->
                <Style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
                    ...
                </Style>
                ...
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
Lu55
fuente
5

Utilice MergedDictionaries .

Obtuve el siguiente ejemplo de aquí.

Archivo1

<ResourceDictionary 
  xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
  xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml " > 
  <Style TargetType="{x:Type TextBlock}" x:Key="TextStyle">
    <Setter Property="FontFamily" Value="Lucida Sans" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="Foreground" Value="#58290A" />
  </Style>
</ResourceDictionary>

Archivo 2

   <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="TextStyle.xaml" />
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary> 
Preet Sangha
fuente
Gracias, pero no suerte. Su ejemplo parece correcto, pero en realidad no funciona. Recibo el mensaje "La propiedad 'Recursos' está configurada más de una vez".
Tor Haugen
Sé acerca de MergedDictionaries. Pero no me dejan combinar una referencia de diccionario externo con recursos definidos localmente de la manera que quiero. Como ya se dijo, hay un ejemplo en la página a la que se refiere, pero no funciona.
Tor Haugen
2
Para cualquiera que reciba ese error de "establecer más de una vez": todos los demás recursos deben estar dentro de la primera etiqueta <ResourceDictionary>.
Hexo