使用 LoadComponent 加载外部 XAML 文件 [英] Load external XAML file using LoadComponent

查看:20
本文介绍了使用 LoadComponent 加载外部 XAML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一些 证据 证明这是可能的,

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.

MSDN

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)

  1. 针对内容建立行动
  2. 复制到输出目录以始终复制
  3. [程序集: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屋!

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