背景
我知道使用 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 专家那里得到更详细、更准确的答案(或者只是一个正确的答案,以防我完全不在这儿)。最佳答案
因为查找资源最需要遍历逻辑元素树(以查找与祖先关联的资源)或查看当前元素的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;
因此,您无法在构造函数内执行任何取决于所设置的属性的操作。
为了证实上述内容,来自 FindResource
的文档:
If the resource is not found on the calling element, the parent element in the logical tree is searched next, then the application, then themes, and finally system resources. This lookup methodology is identical to how the tree is searched if a resource were requested by a dynamic resource reference in markup.
遍历逻辑树当然是通过Parent
属性完成的;这是直观的,但在 LogicalTreeHelper.GetParent
的文档中也清楚地说明了这一点:
This method is merely a wrapper that gets the appropriate type version (
FrameworkElement
orFrameworkContentElement
) of theFrameworkElement.Parent
orFrameworkContentElement.Parent
property; so unless you are unable to determine the current type, you might want to check the respective instance properties instead.
关于c# - 为什么无法在控件的构造函数中获取资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19363082/