我正在调试一段使用 CallMethodAction 来触发 UWP 应用中 Storyboard的代码。我的VS已更新到最新(15.8.6)。我从 VS 2017 得到的错误是:
Cannot find method named Begin on object of type Windows.UI.Xaml.Media.Animation.Storyboard that matches the expected signature.
我必须在VS中手动打开异常,否则只会显示:
Unhandled exception at 0x5B79DC3C (Windows.UI.Xaml.dll) in app.exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x1DF30E70, 0x00000003). occurred
经过几次尝试,我发现:
- Storyboard在调试中运行良好。仅在发布时崩溃。
- 我去Storyboard的定义,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>
有人知道为什么异常只发生在发布中吗?
最佳答案
一般情况下,而不是 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
不起作用,在 Release模式下,.NET Native 编译器会删除所有未使用的内容,以便最大限度地减少生成的程序集的大小并优化性能。不幸的是,当使用反射访问未在任何地方直接访问的类型和成员时,这可能会导致问题。
在本例中 Storyboard.Begin()
方法永远不会直接使用,如果您检查 source code的CallMethodAction
,您可以发现该操作使用反射来发现 TargetObject
上的方法。 :
foreach (MethodInfo method in this.targetObjectType.GetRuntimeMethods())
{
...
}
幸运的是,有一种方法可以强制 .NET Native 编译器直接包含该类型,并且可以使用 MissingMetadataException Troubleshooter 来帮助您做到这一点。 (命名的事实是,大多数情况下,这是当类型丢失时会出现的异常)。
在本例中,我已将完整路径放入 Storyboard
( Windows.UI.Xaml.Media.Animation.Storyboard
) 在工具的单一类型部分中输入:
下面选择了访问成员或激活和仅限公共(public)类型和成员。
在右侧,该工具将生成 <Type>
您需要将声明添加到 <Application>
您可以在 UWP 项目的 Properties 文件夹中找到 Default.rd.xml 文件中的元素。在我们的例子中,结果可能如下所示(不包括注释):
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="*Application*" Dynamic="Required All" />
<Type Name="Windows.UI.Xaml.Media.Animation.Storyboard" Dynamic="Required Public" />
</Application>
</Directives>
关于c# - UWP Storyboard 和 CallMethodAction 的仅发布异常(exception),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52656609/