【问题标题】:Why does resources cannot be fetched in a control's constructor为什么无法在控件的构造函数中获取资源
【发布时间】:2013-10-14 23:21:35
【问题描述】:

背景

我知道使用 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 专家那里获得更详细和准确的答案(或者只是一个正确的答案,以防我完全离开这里)。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    因为查找资源最多涉及遍历逻辑元素树(查找与祖先关联的资源)或查看当前元素的Resources

    在这两种情况下这是不可能的,除非ParentResources 已分别设置为其“正确”值;这些是属性,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的文档:

    如果在调用元素上找不到资源,则父元素 接下来搜索逻辑树中的元素,然后是应用程序, 然后是主题,最后是系统资源。这种查找方法是 与在请求资源时搜索树的方式相同 标记中的动态资源引用。

    走逻辑树当然是通过Parent属性完成的;这很直观,但在LogicalTreeHelper.GetParent 的文档中也清楚地说明了这一点:

    这个方法只是一个获取适当类型版本的包装器 (FrameworkElementFrameworkContentElement)的 FrameworkElement.ParentFrameworkContentElement.Parent 属性;所以 除非您无法确定当前类型,否则您可能需要 请检查相应的实例属性。

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多