UWP故事板和CallMethodAction的仅发行例外

时间:2018-10-05 00:03:35

标签: c# uwp

我正在调试一段代码,该代码使用CallMethodAction来触发UWP应用中的情节提要。我的VS已更新至最新版本(15.8.6)。我从VS 2017中得到的错误是:

  

在类型为的对象上找不到名为Begin的方法   符合预期的Windows.UI.Xaml.Media.Animation.Storyboard   签名。

我必须在VS中手动打开例外,否则它将显示:

  

app.exe中0x5B79DC3C(Windows.UI.Xaml.dll)处未处理的异常:   0xC000027B:发生应用程序内部异常   (参数:0x1DF30E70、0x00000003)。发生

经过几次尝试,我发现:

  1. 情节提要在调试时可以正常工作。仅在发布时崩溃。
  2. 我转到情节提要的定义,Begin的签名是:
public void Begin();

看起来不错。 (它可用于调试...)

Storyborad和DataTriggerBehavior的设置如下:

<Storyboard x:Name="ShowOverlay">
  ... // doesn't really matter
</Storyboard>

<core:DataTriggerBehavior Binding="{Binding LogUploadStatus, Converter={StaticResource LogUploadStatusToBoolConverter}, ConverterParameter={StaticResource LogUploadStatusIdle}}" Value="False">
  <core:CallMethodAction TargetObject="{Binding ElementName=ShowOverlay}" MethodName="Begin" />
</core:DataTriggerBehavior>

有人知道为什么该异常仅在发行版中发生吗?

1 个答案:

答案 0 :(得分:1)

通常,您可以使用CallMethodAction代替ControlStoryboardAction。这是为支持控制Storyboard元素而构建的特定行为:

<Storyboard x:Name="ShowOverlay">
  ...
</Storyboard>

<core:DataTriggerBehavior Binding="{Binding LogUploadStatus, Converter={StaticResource LogUploadStatusToBoolConverter}, ConverterParameter={StaticResource LogUploadStatusIdle}}" Value="False">
  <core:ControlStoryboardAction Storyboard="{StaticResource ShowOverlay}"
                                ControlStoryboardOption="Play" />
</core:DataTriggerBehavior>

关于ControlMethodAction无法正常工作的原因,在发布模式下,.NET Native编译器会删除所有未使用的内容,以使其最小化生成的程序集的大小并优化性能。不幸的是,这在使用反射来访问类型和成员时会引起问题,而这些类型和成员不能直接在任何地方访问。

在这种情况下,永远不会直接使用Storyboard.Begin()方法,如果您检查CallMethodAction的{​​{3}},则可以发现该操作使​​用反射来发现{{1 }}:

TargetObject

幸运的是,有一种方法可以强制.NET Native编译器直接包括该类型并可以帮助您做到这一点,您可以使用source code(由于在大多数情况下这是您的例外,因此命名)将在缺少类型时得到)。

在这种情况下,我已在工具的单一类型部分中将foreach (MethodInfo method in this.targetObjectType.GetRuntimeMethods()) { ... } Storyboard)类型的完整路径放置了:

MissingMetadataException Troubleshooter

然后在下面选择访问成员或激活仅公开类型和成员

该工具将在右侧生成Windows.UI.Xaml.Media.Animation.Storyboard声明,您需要将其添加到 Default.rd.xml 文件中的<Type>元素中在您的UWP项目的属性文件夹中。在我们的情况下,结果可能如下所示(不包括注释):

<Application>