我找到了一些evidence这是可能的,
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'。
<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'。
什么是解决方案?
答案 0 :(得分:4)
我让这个工作。我的具体目标是将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”作为按钮的背景颜色。皮肤瞬间变化,无需重新加载应用程序或窗口。
答案 1 :(得分:3)
似乎LoadComponent无法加载外部XAML文件。
我检查了源代码:
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支持两个权限: application:///和siteoforigin:///。 应用程序:///权限 识别应用程序数据文件 在编译时已知,包括 资源和内容文件。该 siteoforigin:///权限标识 原始网站文件。
可能的数据文件是:
包装和零件类似于 应用程序和文件,其中 应用程序(包)可以包括 一个或多个文件(部分), 包括:
已编译的资源文件 进入当地集会。
已编译的资源文件 进入引用的程序集。
已编译的资源文件 进入引用程序集。
内容文件。
原始网站文件。
可以使用application://访问前4个文件,但我正在查找外部文件,因此唯一的选项是“内容文件”。
所以我将app.xaml转换为内容文件(详情为here)
结果抛出了这样的异常:'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'。
我不知道在“application / baml + xml”中将xaml存储为外部文件的方法,所以假设任务没有解决方案。
答案 2 :(得分:0)
您将需要包含整个文件的绝对文件URI:// c:/ etc ..因为Relative仅在应用程序的资源中使用。
答案 3 :(得分:0)
为了使LoadComponent能够处理XAML资源,它需要具有“Page”的构建操作。然后,即使在控制台应用程序中,LoadComponent仍可正常工作。
当想要在服务器应用程序中访问从Blend生成的样本数据时,这可能很有用。