我知道使用FindResource方法获取资源在从控件的构造函数中完成时将无效,因为它始终返回null。
public class MyButton : Button
{
public MyButton()
{
Style = FindResource("myStyle") as Style;
}
}
我知道可以通过OnApplyTemplate方法完成。
public override void OnApplyTemplate()
{
Style = FindResource("myStyle") as Style;
base.OnApplyTemplate();
}
为什么呢?我认为它与VisualTree的加载有关,但我希望从WPF专家那里得到更详细和准确的答案(或者只是一个正确的答案,我完全不在这里)。
答案 0 :(得分:4)
因为查找资源最多涉及遍历逻辑元素树(查找与祖先关联的资源)或查看当前元素的Resources
。
在这两种情况下,除非分别将Parent
或Resources
设置为“正确”值,否则无法进行此操作;这些是属性,XAML序列化引擎在构造函数运行后设置它们。也就是说,当你写
<Button Height="80" Width="150" />
XAML反序列化器最终做的相当于
var button = new Button(); // element is instantiated
button.Height = 80; // ...and THEN properties are set
button.Width = 150;
因此,您不能在构造函数内部执行任何操作,这取决于所设置的属性。
的文档中证实以上内容如果在调用元素上找不到资源,则为父元素 接下来搜索逻辑树中的元素,然后搜索应用程序, 然后是主题,最后是系统资源。这种查找方法是 与请求资源时如何搜索树相同 标记中的动态资源引用。
走逻辑树当然是通过Parent
属性完成的;这很直观,但在LogicalTreeHelper.GetParent
的文档中也清楚地说明了这一点:
此方法仅是获取适当类型版本的包装器 (
FrameworkElement
或FrameworkContentElement
)FrameworkElement.Parent
或FrameworkContentElement.Parent
属性;所以 除非您无法确定当前类型,否则您可能想要 改为检查相应的实例属性。