Loading Loose Xaml with custom controls on WinRT fails unless dummy DataTemplate exists

北慕城南 提交于 2019-12-22 01:32:02

问题


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);

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?


回答1:


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.

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).

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.



来源:https://stackoverflow.com/questions/15105214/loading-loose-xaml-with-custom-controls-on-winrt-fails-unless-dummy-datatemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!