除非存在虚拟 DataTemplate,否则在 WinRT 上加载带有自定义控件的松散 Xaml 会失败 [英] Loading Loose Xaml with custom controls on WinRT fails unless dummy DataTemplate exists

查看:23
本文介绍了除非存在虚拟 DataTemplate,否则在 WinRT 上加载带有自定义控件的松散 Xaml 会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 ReactiveUI 中,我在某个时间点运行此代码:

In ReactiveUI, I run this code at a certain point:

const string template = "<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:routing='using:ReactiveUI.Routing'>" +
    "<routing:ViewModelViewHost ViewModel=\"{Binding}\" VerticalContentAlignment=\"Stretch\" HorizontalContentAlignment=\"Stretch\" IsTabStop=\"False\" />" +
"</DataTemplate>";

var theTemplate = XamlReader.Load(template);

在其他平台上,这很好用(xmlns 声明当然不同),但是在 {WinRT/Metro/Windows Store} 上,这会引发未指定的错误:

On other platforms, this works great (the xmlns declaration is different of course), but on {WinRT / Metro / Windows Store}, this throws an Unspecified Error:

WinRT information: The type 'ViewModelViewHost' was not found. [Line: 1 Position: 253]

扭曲

但是,如果您在页面上包含虚拟资源:

The Twist

However, if you include a dummy resource on the page:

<Page.Resources>
    <DataTemplate x:Name="Foo">
        <routing:ViewModelViewHost ViewModel="{Binding}" />
    </DataTemplate>
</Page.Resources>

...然后它起作用了!什么给?

...then it works! What gives?

推荐答案

twist"让我觉得这一定是因为应用程序没有正确的 XAML 元数据来实例化的类型 - 而不是使用反射来解析类型XAML 文件,如 WPF/Silverlight,WinRT 使用代码生成通过 IXamlMetadataProvider 接口解析(有一个不错的描述 这里; 听起来像你在做什么,另见 后续).添加引用会强制正确生成此元数据代码.如果是这种情况,您应该可以通过简单地将类型本身添加到某个未使用的键下的资源中来实现相同的效果,而无需数据模板.

The "twist" makes me think this must be because the application does not have correct XAML metadata for the type being instantiated - rather than using reflection to resolve types in XAML files like WPF/Silverlight, WinRT uses code generation to resolve via the IXamlMetadataProvider interface (there's a decent description here; this sounds like what you're doing, see also the followup). Adding the reference forces this metadata code to be generated properly. If this is the case, you should be able to achieve the same effect by simply adding the type itself to the resources under some unused key, without the data template.

查看应用程序的obj"目录,Visual Studio 会生成一个 XamlTypeInfo.g.cs 文件来实现 IXamlMetadataProvider.这应该包含失败类型的条目 - 在您添加虚拟引用的情况下,应该有实例化类型所需的完整详细信息.如果没有这个,我发现可能有一些对类型类型的引用,但信息不足 - 但是这会阻止失败行为(在可能具有自定义元数据提供程序的依赖 DLL 中查找类型).

Have a look in your application's "obj" directory, Visual Studio generates a XamlTypeInfo.g.cs file to implement IXamlMetadataProvider. This should contain an entry for the type that is failing - in the case where you have added a dummy reference, there should be full details required to instantiate the type. Without this, I've found it's possible to have some reference to type type, but insufficient information - however this prevents the fallthrough behaviour (looking up the type in a dependent DLL which might have a custom metadata provider).

除了在最终应用程序本身中添加对库类型的虚拟引用之外,我找到的唯一解决方案是应用 Bindable 类型的属性.虽然这应该与 C++ 相关,但我发现这可以在 C# 中使用以强制类型始终出现在为 XAML 类型元数据生成的代码中.

Other than adding a dummy reference to the library type in the final application itself, the only solution I found for this is to apply the Bindable attribute to the type. While this is supposed to relate to C++, I found this can be used in C# to force a type to always appear in the code generated for XAML type metadata.

这篇关于除非存在虚拟 DataTemplate,否则在 WinRT 上加载带有自定义控件的松散 Xaml 会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆