使用 LoadComponent 加载外部 XAML 文件 [英] Load external XAML file using LoadComponent
问题描述
我发现了一些 证据 证明这是可能的,
I have found some evidence that this is possible,
self.scene = Canvas()
Application.LoadComponent(self.scene, Uri('app.xaml', UriKind.Relative))
但我的代码失败了:
class Program
{
[STAThread]
static void Main(string[] args)
{
Canvas scene = new Canvas();
Application.LoadComponent(scene, new Uri("app.xaml", UriKind.Relative));
}
}
我使用相同的 app.xaml 和构建操作:无"和始终复制".
I am using the same app.xaml with 'Build Action: None', and 'Copy always".
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="System.Windows.Controls.Canvas"
x:Name="ball_design" >
<Canvas x:Name="workaround_canvas" >
<TextBlock x:Name="fps" Canvas.Left="10" Canvas.Top="10" Height="40" Canvas.ZIndex="10000" Text="-- fps" />
<Canvas x:Name="wpfe_ball_0" Width="52" Height="52" Canvas.Left="0" Canvas.Top="30">
<!-- Layer 3/<Group>/<Path> -->
<Path Opacity="0.900000" StrokeThickness="2.000000" Stroke="#ffa6d000" StrokeMiterLimit="1.000000" Fill="#ffcbff00" Data="F1 M 51.000000,26.000000 C 51.000000,39.806641 39.807129,51.000000 26.000000,51.000000 C 12.192871,51.000000 1.000000,39.806641 1.000000,26.000000 C 1.000000,12.193359 12.192871,1.000000 26.000000,1.000000 C 39.807129,1.000000 51.000000,12.193359 51.000000,26.000000 Z"/>
<!-- Layer 3/<Group>/<Path> -->
<Path Opacity="0.740000" Data="F1 M 43.143066,13.087891 C 50.602051,22.888672 49.009766,36.642578 39.590332,43.812500 C 30.170898,50.980469 16.489258,48.842773 9.032715,39.042969 C 1.573242,29.240234 3.166016,15.486328 12.584961,8.316406 C 22.003906,1.149414 35.685547,3.285156 43.143066,13.087891 Z">
<Path.Fill>
<RadialGradientBrush MappingMode="Absolute" GradientOrigin="156.791016,170.453125" Center="156.791016,170.453125" RadiusX="53.626404" RadiusY="53.626404">
<RadialGradientBrush.GradientStops>
<GradientStop Offset="0.000000" Color="#ffffffff"/>
<GradientStop Offset="0.361685" Color="#fff5f7dd"/>
<GradientStop Offset="0.415730" Color="#ffebf0bc"/>
<GradientStop Offset="1.000000" Color="#ffcbff00"/>
</RadialGradientBrush.GradientStops>
<RadialGradientBrush.Transform>
<MatrixTransform Matrix="1.190000,0.165000,-0.165000,-1.281300,-113.414185,241.757843" />
</RadialGradientBrush.Transform>
</RadialGradientBrush>
</Path.Fill>
</Path>
<!-- Layer 3/<Group>/<Path> -->
<Path Fill="#ffffffff" Data="F1 M 23.100586,9.477539 C 24.741699,11.634766 23.116211,15.630859 19.470703,18.404297 C 15.825684,21.178711 11.540039,21.678711 9.899414,19.522461 C 8.258301,17.365234 9.883789,13.369141 13.529297,10.594727 C 17.174316,7.821289 21.459961,7.321289 23.100586,9.477539 Z"/>
</Canvas>
<TextBlock x:Name="dbgwin" FontSize="10" Canvas.Top="10" Canvas.Left="250" Height="500" Width="200" Text="IronPython DLR" />
</Canvas>
</Canvas>
我收到 IOException:找不到资源app.xaml".
I get IOException: Cannot locate resource 'app.xaml'.
什么是解决方案?
推荐答案
LoadComponent 似乎无法加载外部 XAML 文件.
It seems that external XAML file can't be loaded by LoadComponent.
我检查了源代码:
public static void LoadComponent(Object component, Uri resourceLocator)
{
...
// Passed a relative Uri here.
// needs to resolve it to Pack://Application.
//..\..\ in the relative Uri will get stripped when creating the new Uri and resolving to the
//PackAppBaseUri, i.e. only relative Uri within the appbase are created here
Uri currentUri = new Uri(BaseUriHelper.PackAppBaseUri, resourceLocator);
...
}
所以 resourceLocator 应该是一个相对路径.并且会在application:///权限下处理.
So the resourceLocator SHOULD be a relative path. And it will be treated under application:/// authority.
WPF 支持两种权限:application:///和 siteoforigin:///.应用程序:///权限标识应用程序数据文件在编译时已知,包括资源和内容文件.这siteoforigin:///权威标识源文件站点.
WPF supports two authorities: application:/// and siteoforigin:///. The application:/// authority identifies application data files that are known at compile time, including resource and content files. The siteoforigin:/// authority identifies site of origin files.
可能的数据文件有:
封装和部件类似于应用程序和文件,其中应用程序(包)可以包括一个或多个文件(部分),包括:
Packages and parts are analogous to applications and files, where an application (package) can include one or more files (parts), including:
编译的资源文件进入当地议会.
Resource files that are compiled into the local assembly.
编译的资源文件到引用的程序集.
Resource files that are compiled into a referenced assembly.
编译的资源文件到参考程序集.
Resource files that are compiled into a referencing assembly.
内容文件.
原始文件的站点.
前 4 个文件可通过 application://访问,但我正在寻找外部文件,因此唯一的选项是内容文件".
The first 4 files are accessible with application://, but I am looking for external files, so the only option is "Content file".
所以我把 app.xaml 变成了内容文件(详情在 这里)
So I turned app.xaml into content file (details are here)
- 针对内容建立行动
- 复制到输出目录以始终复制
- [程序集:AssociatedContentFile("app.xaml")]
结果抛出了这样的异常:'application/xaml+xml' ContentType 无效.
As result such exception was thrown: 'application/xaml+xml' ContentType is not valid.
public static void LoadComponent(Object component, Uri resourceLocator)
{
...
if (!MimeTypeMapper.BamlMime.AreTypeAndSubTypeEqual(contentType))
{
throw new Exception(SR.Get(SRID.ContentTypeNotSupported, contentType));
}
...
}
所以 LoadComponent 需要 'application/baml+xml' 而不是 'application/xaml+xml'.
So the LoadComponent expects 'application/baml+xml' instead of 'application/xaml+xml'.
我不知道如何将 xaml 作为外部文件存储在application/baml+xml"中,因此假设该任务没有解决方案.
I don't know a way to store xaml as external file in 'application/baml+xml', so assume the task has no solution.
这篇关于使用 LoadComponent 加载外部 XAML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!