redondeados - Cómo extender en lugar de anular los estilos WPF
estilos datagrid wpf (2)
Wpf tiene diferentes niveles de estilos, que se aplican en orden global> local. Un estilo establecido directamente en un control anulará un conjunto de estilos globalmente, como en su ejemplo. Estaba tratando de encontrar una lista de todos los diferentes lugares en que un control busca sus estilos, pero no puedo encontrar uno en este momento. Por lo que sé, tendrá que usar la propiedad BasedOn para heredar un estilo y no anular completamente las propiedades de ese estilo con el estilo que estableció localmente.
Este es un ejemplo de un diccionario de recursos que tiene estilos basados en otro estilo, por lo que no tiene que repetir el enlace de BasedOn
una y otra vez, solo puede establecer el estilo en el elemento específico que desea que tenga ese estilo.
<Window x:Class="TestWpf.RandomStuffWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Stuff Window">
<Window.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type Label}"
x:Key="GreenForegroundLabel">
<Setter Property="Foreground" Value="Green" />
</Style>
<Style TargetType="{x:Type Label}"
x:Key="LargeGreenForegroundLabel"
BasedOn="{StaticResource GreenForegroundLabel}">
<Setter Property="FontSize" Value="28" />
</Style>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<Label Style="{StaticResource GreenForegroundLabel}"
Content="GreenForegroundLabel" />
<Label Style="{StaticResource LargeGreenForegroundLabel}"
Content="LargeGreenForegroundLabel" />
</StackPanel>
</Window>
Quiero usar un tema personalizado en mi aplicación y, por lo que sé, puedo lograrlo utilizando el diccionario de recursos y haciendo referencia a él en App.xaml. Los estilos anularían los valores predeterminados de esta manera:
<Style TargetType="{x:Type Label">
<Setter Property="Foreground" Value="Green" />
</Style>
Ahora, como creo, el estilo de etiqueta predeterminado está anulado con los mismos valores pero todas las fuentes de mis etiquetas son verdes. El problema comienza cuando quiero estilizar una etiqueta en algún lugar otra vez. Cuando quiero cambiar alguna otra propiedad en mi Grid como esta
<Grid.Resources>
<Style TargetType="{x:Type Label">
<Setter Property="FontSize" Value="28" />
</Style>
</Grid.Resources>
Todas las etiquetas dentro de mi cuadrícula están perdiendo su color de primer plano y vuelven a tener el predeterminado (¿no anulé los valores predeterminados en el paso anterior?). Después de algunos intentos, descubrí que para hacer esto correctamente, tengo que agregar otra propiedad a la declaración de Style
BasedOn={StaticResource {x:Type Label}}"
y funciona. Esto es un poco raro para mí porque ahora tendré que repetir El mismo código BasedOn en toda la aplicación y no es así como funciona el estilo, ¡esto debería hacerse automáticamente! Por ejemplo, en HTML + CSS los estilos se heredan y se combinan y en WPF se reemplazan ...
Tenga en cuenta que cuando no uso ningún estilo, los controles aún se ven desde algún punto (¿Temas del sistema?). ¿Cómo puedo decirles que busquen valores predeterminados en otro lugar, de modo que, sin ningún código adicional en los estilos, pensarán que deberían ser verdes de forma predeterminada?
¿Hay alguna forma en que pueda automatizar la configuración de la propiedad BasedOn? O tal vez hay una mejor manera de hacer esto por encima?
Yo tuve el mismo problema. Usé la respuesta de Zack y la mejoré como la siguiente, así que si no especifica un estilo, el valor predeterminado anulado aún se tiene en cuenta. Es básicamente lo que habrías hecho, pero solo una vez en el ResourceDictionary.
<Window x:Class="TestWpf.RandomStuffWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Stuff Window">
<Window.Resources>
<ResourceDictionary>
<!-- Default Label style definition -->
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="Green" />
</Style>
<!-- Extending default style -->
<Style TargetType="{x:Type Label}"
x:Key="LargeGreenForegroundLabel"
BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="FontSize" Value="28" />
</Style>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<Label Content="GreenForegroundLabel" /> <!-- Uses default style -->
<Label Style="{StaticResource LargeGreenForegroundLabel}"
Content="LargeGreenForegroundLabel" />
</StackPanel>
</Window>