example wpf resources

example - textbox wpf



Estilos implícitos en Application.Resources vs Window.Resources? (4)

Este es realmente el único manejo especial agregado a WPF y fue hecho por diseño. El código que lo implementa se puede encontrar en FrameworkElement , en el método FindImplicitStyleResource , que efectivamente hace:

internal static object FindImplicitStyleResource(FrameworkElement fe, object resourceKey, out object source) { // ... DependencyObject boundaryElement = null; if (!(fe is Control)) boundaryElement = fe.TemplatedParent; // ... }

Entonces, la regla de oro es que los Estilos implícitos siempre se aplican a los controles (es decir, deriva del Control ). Asumiendo que se puede encontrar el Estilo implícito.

Para los elementos utilizados en una plantilla de Control que no se derivan del Control , como TextBlock , la búsqueda de estilo implícita no cruza su elemento primario con plantilla. En su caso anterior, este sería el ComboBox .

Creo que esto se hizo para que los Estilos implícitos que no son de aplicación para TextBlock no se aplicaran inadvertidamente a los elementos de TextBlock utilizados en las plantillas de control, que el desarrollador puede haber sabido o no. Los Estilos implícitos solo se aplicarían a los TextBlocks realmente creados por el desarrollador en su propio XAML.

La aplicación de Estilos implícitos aún permitiría un estilo global, como aumentar el tamaño de la fuente. Pero probablemente haya causado más confusión de lo que vale.

No hay una buena respuesta para decir cuándo usar uno frente a otro, ya que cada uno tiene su función. Obviamente, si no quiere afectar cada TextBlock en su aplicación, no debe poner el estilo en los recursos de la aplicación.

Pero tenga en cuenta que esto afecta a cualquier elemento que no sea Control , como los elementos Shape .

Estaba viendo esta pregunta y me di cuenta de que colocaba un estilo de TextBlock implícito en Application.Resources aplica ese estilo a todos los TextBlocks, incluso a los que están dentro de otros controles como Buttons , ComboBoxes , etc.

<Application.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Blue" /> </Style> </Application.Resources>

Colocar el estilo implícito en Window.Resources no cruza los límites de la plantilla , por lo que cosas como Buttons y ComboBoxes mantienen su texto negro predeterminado.

<Window.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Blue" /> </Style> </Window.Resources>

Además, agregar el estilo predeterminado en Application.Resources hace para que no pueda sobreescribir ese estilo con otro estilo implícito.

<!-- Doesn''t work if implicit style with same property is in Application.Resources --> <ComboBox.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Red" /> </Style> </ComboBox.Resources>

Mis preguntas son:

  • ¿Por qué es esto?
  • ¿Hay otras diferencias entre Application.Resources y Windows.Resources ?
  • ¿Cuándo debería usar uno sobre el otro?

    Entiendo que Application.Resources aplica a toda la aplicación, mientras que Window.Resources aplica solo a la ventana, sin embargo, quiero saber por qué los estilos en Application se tratan de manera diferente a los estilos en Window


La diferencia radica en el alcance de los estilos:

  • cuando se coloca en Application.Resources, se aplicará un estilo a todos los controles en la aplicación
  • cuando se coloca dentro de Windows.Resources, se aplicará un estilo a todos los controles en la ventana

la diferencia es bastante sutil allí, pero lo que significa es que sea cual sea el control del que estamos hablando (incluido uno que está en la plantilla de otro control) obtendrá el estilo de la aplicación. Recursos. pero solo los controles directamente hijos de la ventana obtendrán el estilo de la ventana. Recursos. Un control dentro de la plantilla del control no tendrá el estilo definido en Window.Resources ya que no está directamente en la ventana, mientras que tendrá el estilo definido en Application.Resources ya que está en la aplicación.

en cuanto a su segundo punto, tiene que ver con la precedencia de propiedad de dependencia, creo:

http://msdn.microsoft.com/en-us/library/ms743230.aspx


Muy simple como simple

Si desea que los recursos se compartan entre la aplicación ENTERA, usaría Application.Resources

Si quiere que los recursos se compartan entre la ventana ENTERA, usaría Window.Resources

Si desea que los recursos se compartan entre un único control que usaría (sea cual sea el control). Recursos

Supongamos que tiene varias ventanas pero solo quiere un estilo predeterminado en una, pero no en la otra, entonces debería usar Windoe.Resources


Rachel, no creo que haya nada especial para "Styles". Además, no hay un problema de "cruzar límites de plantilla". La razón de esto es diferente y va a los diferentes "Árboles" en una aplicación de WPF. Con tu pregunta, te imagino que estás imaginando un mundo con la siguiente jerarquía:
- Aplicación => Ventana => Control => Elementos dentro del control

No existe tal jerarquía. Hay árboles diferentes en una aplicación de WPF, los más famosos son el Árbol lógico y el Árbol visual, pero hay más (el árbol de eventos de enrutamiento y también el árbol de búsqueda de recursos, con una semántica ligeramente diferente).

Supongamos el siguiente XAML:

<Window x:Class="SO.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Button x:Name="btn" Click="click">Click Me</Button> </Grid> </Window>

Para este XAML, el árbol lógico se verá así:
- Ventana => Cuadrícula => Botón => Cadena

El bloque de texto dentro del botón no es parte del árbol lógico (aunque es parte del VisualTree).

Buscar recursos pasa por LogicalTree, con una diferencia. Después de que llegue al objeto superior, el algoritmo de recursos de búsqueda buscará en el diccionario de recursos de la aplicación , y luego en el elemento dietario del recurso del tema, y ​​luego en el diccionario de recursos del sistema en este orden.

Ver los siguientes artículos:

Finalmente, para probar mi punto, agregue el siguiente recurso a la aplicación XAML:

<Application x:Class="SO.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:clr="clr-namespace:System;assembly=mscorlib" StartupUri="MainWindow.xaml"> <Application.Resources> <clr:String x:Key="MyResource">Hello Application Resource</clr:String> </Application.Resources> </Application>

y el siguiente código detrás:

private void click(object sender, RoutedEventArgs e) { // Logical Children of btn Debug.WriteLine("Children of btn:"); foreach( var x in LogicalTreeHelper.GetChildren(btn) ) { Debug.WriteLine("{0} : {1}", x, x.GetType()); } // Walk the visual tree Debug.WriteLine("The Visual Tree:"); WalkVisual(0, this); // Find the textblock within the button DependencyObject p = btn; while (p.GetType() != typeof(TextBlock)) p = VisualTreeHelper.GetChild(p, 0); TextBlock tb = p as TextBlock; // Now climp the textblock through the logical tree while (p != null) { Debug.WriteLine("{0}", p.GetType()); p = LogicalTreeHelper.GetParent(p); } // Find a resource for the textbox string s = tb.FindResource("MyResource") as string; Debug.WriteLine("MyResource Content: {0}", s); } private void WalkVisual(int indent, DependencyObject p) { string fmt = string.Format("{{0,{0}}}{{1}}", indent * 4); Debug.WriteLine(fmt, "", p.GetType()); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(p); ++i) { WalkVisual(indent+1,VisualTreeHelper.GetChild(p, i)); } }

Entonces ... una vez que entiendes la primera pregunta (''¿por qué es eso?''), Las otras preguntas se desmoronan. La diferencia entre los recursos de la aplicación y los recursos de la ventana es que los recursos de la aplicación pueden ser originados por cualquier DependencyObject en su aplicación, incluidos aquellos definidos en otros ensambles. Lo usarás cuando esto sea lo que quieres lograr :-)