Wpf 使用LoadComponent加载外部XAML文件

Wpf 使用LoadComponent加载外部XAML文件,wpf,Wpf,我发现这是可能的 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.Load

我发现这是可能的

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与“Build Action:None”和“Copy always”相同


我收到IOException:找不到资源“app.xaml”


什么是解决方案?

您需要包含整个文件的绝对文件URI://c:/etc

我检查了源代码:

    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:///authority下处理

WPF支持两种权限: 应用程序:///和siteoforigin:///. 应用程序:///权限 标识要删除的应用程序数据文件 在编译时已知,包括 资源和内容文件 siteoforigin:///权限标识 源文件的站点

可能的数据文件包括:

  • 包装和部件类似于 应用程序和文件,其中 应用程序(包)可以包括 一个或多个文件(部件), 包括:

  • 已编译的资源文件 进入当地议会

  • 已编译的资源文件 导入引用的程序集

  • 已编译的资源文件 导入引用程序集

  • 内容文件

  • 源文件的站点

前4个文件可以通过application:///访问,但我正在查找外部文件,因此唯一的选项是“Content file”

因此,我将app.xaml转换为内容文件(详细信息如下)

  • 根据内容构建操作
  • 复制到输出目录以始终复制
  • [程序集:AssemblyAssociatedContentFile(“app.xaml”)]
  • 结果引发了此类异常:“application/xaml+xml”ContentType无效

        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”


    我不知道如何将xaml作为外部文件存储在“application/baml+xml”中,因此假设该任务没有解决方案。

    我做到了这一点。我的具体目标是将ResourceDictionary加载到App类中,这样我就可以从原始xaml文件加载自定义外观。方法如下。首先,在App.xaml中,添加以下内容:

        protected override void OnStartup(StartupEventArgs e) {
            base.OnStartup(e);
            LoadSkin("Skins/Skin1.xaml");
    
        }
    
        private void LoadSkin(string FilePath) {
            XmlReader XmlRead = XmlReader.Create(FilePath);
            Application.Current.Resources = 
                (ResourceDictionary)XamlReader.Load(XmlRead);
            XmlRead.Close();
        }
    
    创建一个“bin\Debug\Skins”文件夹,并添加一个包含以下内容的“Skin1.xaml”:

    <ResourceDictionary 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
        <Style x:Key="ButtonAStyle" TargetType="{x:Type Button}">
            <Setter Property="Control.Background" Value="Green" />
            <Setter Property="Control.Foreground" Value="White" />
        </Style>
    </ResourceDictionary>
    
    
    

    特定于皮肤

    在这种情况下,您必须确保在各个窗口中正确使用样式资源。以下是一个示例:

    <Button 
        Name="button1" 
        Style="{DynamicResource ButtonAStyle}" 
        Click="button1_Click"
    >Button</Button>
    
    按钮
    

    这里有一个简单的技巧可以尝试。在button1_Click()中,尝试添加与上面的App.OnStartUp()中相同的代码,但使用“Skin2.xaml”和“Red”“作为按钮的背景色。皮肤会立即改变,无需重新加载应用程序或窗口。

    为了让LoadComponent在XAML资源上工作,它需要有一个“页面”的构建操作。然后LoadComponent可以工作,即使在控制台应用程序中也是如此


    当想要访问服务器应用程序中从Blend生成的示例数据时,这可能很有用。

    现在我得到ArgumentException:无法使用绝对URI。Hm。。。我提到的代码是SilverLight代码,因此可能LoadComponent无法用于加载外部文件。最新研究表明,使用BAML我们可以加载它。稍后将更改响应。如何获取BAML?1。你的VS版本是什么?我在VS2008中没有看到这样的构建操作“内容复制到输出”吗?2.你确定Skin1.xaml只是被复制,而不是作为资源编译成.exe吗?我使用的是VS 2008。不过,看起来我是在自欺欺人。如果我将“Build Action”设置为“Content”,这对我有效。如果我只是将松散的文件放在bin\Debug\Skins\中,它将不起作用:-P我正在寻找修复方法。密钥使用的是XamlReader,而不是Application.LoadComponent()。我已经更新了这里的代码来反映它。不幸的是,XamlReader.Load只适用于没有out事件的xaml文件
    <Button 
        Name="button1" 
        Style="{DynamicResource ButtonAStyle}" 
        Click="button1_Click"
    >Button</Button>