Implicit styles in Application.Resources vs Window.Resources?

This is really the only special handling added to WPF and it was done by design. The code that implements it can be found in FrameworkElement, in the method FindImplicitStyleResource, which effectively does:

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

So the rule of thumb is that implicit Styles are always applied to controls (i.e. derives from Control). Assuming the implicit Style can be found.

For elements used in a ControlTemplate that do not derive from Control, such as TextBlock, the implicit Style look up will not cross it's templated parent. In your case above, this would be the ComboBox.

I believe this was done so that non-application implicit Styles for TextBlock were not inadvertently applied to TextBlock elements used in control templates, which the developer may or may not have known were there. The implicit Styles would only be applied to TextBlocks actually created by the developer in their own XAML.

The application implicit Styles would still allow global styling, such as increasing font size. But has probably caused more confusion than it's worth.

There is no good answer to say when to use one versus the other, as they each have their function. Obviously if you don't want to affect every TextBlock in your application, you shouldn't put the style in the application resources.

But keep in mind that this affects any non-Control element, such as Shape elements.


Pretty plain as simple

If you want Resources to be shared among the ENTIRE application you would use Application.Resources

If you want Resources to be shared among the ENTIRE Window you would use Window.Resources

If you want Resources to be shared among a single control you would use (Whatever Control).Resources

Lets say you have multiple windows but you only want a default style in one but not the other then you would use Windoe.Resources


Rachel, I don't think there is anything special to "Styles". Moreover, there isn't an issue of "crossing template boundaries". The reason for this is different and it goes to the different "Trees" in a WPF applicaiton. By your question I recon you are picturing a world with the following hierarchy:
- Application => Window => Control => Elements within the control

There is no such hierarchy. There are different trees in a WPF applicaiton, the most famous are the Logical Tree and the Visual Tree, but there are more (the routing event tree and also the resource lookup tree, with slightly different semantics).

Assume the following 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>

For this XAML, the logical tree will look like:
- Window => Grid => Button => String

The textblock inside the button is not part of the logical tree (it is part of the VisualTree though).

Looking up for resources goes by the LogicalTree, with one difference. After it reaches the top object, the finding resource algorithm will look at the Application resource dictionary, and then at the Theme resource diectionary, and then at the System resource dictionary in this order.

See following articles:

  • About trees: http://msdn.microsoft.com/en-us/library/ms753391.aspx
  • About finding resources: http://msdn.microsoft.com/en-us/library/ms750613.aspx#staticdynamic, and look for the section 'Dynamic Resource Lookup Behaviour'

Finnaly, to prove my point, add the following resource to the applicaiton 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>

and the following code behind:

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));
    }
}

So ... once you understand the first question ('why is that'), the other questions fall apart. The different between application resources and window resources is that application resources can be fount by any DependencyObject in your application, including those defined in other assemblies. You'll use it when this is what you want to acheive :-)

u.