使用Findresource加载资源会引发异常 - WPF / C#

时间:2009-02-03 09:59:45

标签: wpf resources

我正在WPF中编写CustomControl。我在我的Themes / Generic.xaml中有一些DataTemplates,在resourcedictionary级别,为它们分配了x:Key。

现在从同一个控件类代码中,我想找到并加载该资源,这样我就可以动态地为代码中的某些东西做出贡献。

我试过base / this.FindResource(“keyvalue”),this.Resources [“”]等。

它一直返回找不到资源,因此为null。

该资源在generic.xaml中非常有用。

请帮忙。

7 个答案:

答案 0 :(得分:7)

答案有点迟,但可能会让其他人受益。

您尝试访问的资源是在主题级别,要从程序集中的任何位置访问它,必须由ComponentResourceKey标识:

<Style TargetType="{x:Type TreeViewItem}" 
       x:Key="{ComponentResourceKey {x:Type local:MyTVIStyleSelector}, tviBaseStyle}">
  <!-- style setters -->
</Style>

然后在你的XAML中你会像这样引用它:

<Style TargetType="{x:Type TreeViewItem}" 
       x:Key="{ComponentResourceKey {x:Type local:MyTVIStyleSelector}, tviStyle_1}"
       BasedOn={StaticResource {ComponentResourceKey {x:Type local:MyTVIStyleSelector}, tviBaseStyle}}>
  <!-- style setters -->
</Style>

并在你的代码中这样:

ComponentResourceKey key = new ComponentResourceKey(typeof(MyTVIStyleSelector), "tviStyle_1");
Style style = (Style)Application.Current.TryFindResource(key);

还有一种冗长的XAML语法形式,看起来像这样(但它只是一样):

<Style TargetType="{x:Type TreeViewItem}" 
       x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:MyTVIStyleSelector}, ResourceId=tviBaseStyle}">
  <!-- style setters -->
</Style>

请注意,即使必须设置TypeInTargetAssembly,它也不会限制对汇编中其他类型的此资源的访问。

答案 1 :(得分:3)

在使用FindResource之前,请确保您已将自定义控件作为子项添加到另一个控件。我很确定当你使用FindResource时,它会爬上控件层次结构,直到找到匹配为止。如果您的控件没有父级,则无法找到您要查找的资源。

答案 2 :(得分:2)

您可以像这样加载资源字典:

ResourceDictionary myDictionary = Application.LoadComponent(new Uri("/MyAssembly;component/Themes/Generic.xaml", UriKind.RelativeOrAbsolute)) as ResourceDictionary;

然后,您可以通常的方式查找其中的资源,例如myDictionary [“keyvalue”]

答案 3 :(得分:1)

由于您正在构建自定义控件,我假设您在generic.xaml文件中定义了ControlTemplate?如果是这样,那么如果你将DataTemplate添加到ControlTemplate的Resources部分,如下所示:

<ControlTemplate>
    <ControlTemplate.Resources>
        <!-- Data Templates Here -->
    </ControlTemplate.Resources>

    <!-- Rest of Control Template -->
</ControlTemplate>

然后假设已经应用/加载了控件模板,那么您将能够在控件中使用对this.FindResource()的调用来查找数据模板。

答案 4 :(得分:1)

x:Key和DataType是mutualy exclusiv。在内部,如果设置DataType,WPF会生成一个DataTemplateKey类型的键。因此,使用ComponentResourceKey调用FindResource会引发异常,因为使用此键无法找到该资源。使用

frameworkElement.FindResource(new DataTemplateKey(typeof(yourType)));

对于DataTemplate,其中DataType = {x:Type local:yourType}已定义或

frameworkElement.FindResource(new ComponentResourceKey(typeof(yourType), "ressId"));

对于DataTemplate,其中x:Key = {ComponentResourceKey TypeInAssembly = {x:Type l:yourType},ResourceId = ressId}已定义。不要在同一模板中定义DataType和x:Key。

答案 5 :(得分:0)

我不确定我是否认为您需要在XAML中定义您的使用或静态资源以及新的x:Key,它与您想要更改的内容相对应。

另一种选择是,如果您使用包含模板的文件合并这样的资源:

<ResourceDictionary.MergedDictionaries>
  <ResourceDictionary Source="SomeTemplate.xaml"/>
</ResourceDictionary.MergedDictionaries>

在适当的地方尝试找到资源

HTH, 埃里克

答案 6 :(得分:0)

向两者致敬。

我尝试将资源转移到CT的资源部分。即便如此,当我查看运行时,比如在OnApplyTemplate或EndInit()等中,this.Resources中没有对象:-(虽然它全部都在控件的Generic.xaml中。

所以它始终返回null。