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:
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.