当 WPF 元素具有 StaticResources 时,如何通过其类型实例化它们?

发布于 2024-08-14 04:46:35 字数 1747 浏览 7 评论 0原文

我需要通过设计器的反射实例化 WPF 类型(例如,UserControl 或 Page)。我遇到的问题是,当我尝试使用 Activator.CreateInstance 实例化它们时,我得到一个 TargetInvocableException ,它最终包装了 StaticResource 标记抛出的异常扩大。

澄清:这些类型位于运行时加载的不同程序集中!

显然,Activator.CreateInstance无法实例化使用{StaticResource XXX}<的类型/strong> 标记扩展,即使在类型的定义中定义了静态资源。

因此,如果您拥有的只是以下类型的定义(类型 + xaml 文件):

<Page x:Class="Hurr.Durr">
  <Page.Resources>
    <ControlTemplate x:Key="whatever">
      <TextBlock Text="This is a stupid example."/>
    </ControlTemplate>
  </Page.Resources>
  <ContentControl Template="{StaticResource whatever}" />
</Page>

您将如何将其启动运行时?

顺便说一句,要求您使用 DynamicResource 是不可接受的。 Visual Studio 需要这个吗?然而,VS 能够启动 WPF 框架元素的副本并将其粘贴到设计器中。


这是一个演示该问题的示例应用程序(抱歉,是 beta 2)。

http://cid-f8be9de57b85cc35.skydrive.live.com/ self.aspx/Public/ResourcesGoKaboom.zip

应用程序尝试加载资源字典中包含绘图的页面。我尝试使用 Application.LoadComponentActivator.CreateInstance 动态加载它,但它们都失败了。


好的,上面的例子可以正常运行。问题是我在元素的属性中使用了 StaticResource,该元素引用了该元素中定义的资源。

让我感到困惑的是,这在视觉工作室中有效。因此,在设计师中,一切看起来都还不错,但在现实中,它都是梨形的。恕我直言,这是一个错误,我已将其报告为:

https ://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=519244

不确定 VS 是否失败......失败,或者 StaticResource 扩展是否在 VS 中工作但不起作用现实生活。

I need to instantiate WPF types (say, a UserControl or a Page) via reflection for a designer. The problem I'm having is that when I attempt to instantiate these using Activator.CreateInstance I get a TargetInvocationException which wraps, in the end, an exception thrown by the StaticResource markup extension.

Clarification: The types are in a different assembly that is loaded at runtime!

Apparently, Activator.CreateInstance can't instantiate types that use the {StaticResource XXX} markup extension, even when the static resource is defined in the type's definition.

So, if all you have is the following type's definition (Type + xaml file):

<Page x:Class="Hurr.Durr">
  <Page.Resources>
    <ControlTemplate x:Key="whatever">
      <TextBlock Text="This is a stupid example."/>
    </ControlTemplate>
  </Page.Resources>
  <ContentControl Template="{StaticResource whatever}" />
</Page>

How would you spin this up at runtime?

BTW, requiring that you use DynamicResource instead is not acceptable. Does Visual Studio require this? Yet VS is able to spin up a copy of your WPF framework element and stick it in the designer.


Here's a sample application (beta 2, sorry) that demonstrates the issue.

http://cid-f8be9de57b85cc35.skydrive.live.com/self.aspx/Public/ResourcesGoKaboom.zip

The app attempts to load a Page with a drawing in its resource dictionary. I try to load it dynamically using Application.LoadComponent and Activator.CreateInstance and they both fail.


Okay, the example above works without an issue. The issue was that I was using a StaticResource within an element's attributes that referenced a resource defined within that element.

What was throwing me was that this works within visual studio. So in the designer everything looked okey dokey but IRL it was all pear shaped. IMHO, this is a bug and I've reported it as such:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=519244

Not sure if its a failure of VS to.... fail, or if the StaticResource extension was working in VS but not IRL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桜花祭 2024-08-21 04:46:35

问题似乎出在您尝试加载的页面上。您的页面看起来像这样(省略了一堆 xmlns 等管道):

<AwesomePage Title="AwesomePage" Background="{StaticResource awesomeface}">
    <AwesomePage.Resources>
        <DrawingBrush x:Key="awesomeface" Stretch="Uniform">
            <!-- details snipped -->
        </DrawingBrush>
    </AwesomePage.Resources>
</AwesomePage>

这尝试在定义之前使用 Awesomeface 资源。 StaticResource 不允许这种前向引用:因此 StaticResourceExtension.ProvideValue 失败,并且您会遇到遇到的错误。

要解决此问题,请将边框立即放置在页面内,并将背景设置器从页面移动到边框。然后将所有内容放入边框内。

The problem appears to be with the Page you're trying to load. Your Page looks like this (omitting a bunch of xmlns etc. plumbing):

<AwesomePage Title="AwesomePage" Background="{StaticResource awesomeface}">
    <AwesomePage.Resources>
        <DrawingBrush x:Key="awesomeface" Stretch="Uniform">
            <!-- details snipped -->
        </DrawingBrush>
    </AwesomePage.Resources>
</AwesomePage>

This tries to use the awesomeface resource before it is defined. StaticResource does not allow this kind of forward referencing: therefore the StaticResourceExtension.ProvideValue fails and you get the error you have run into.

To fix this, put a Border immediately inside the Page, and move the Background setter from the Page to the Border. Then put all your content inside the Border.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文