问题描述
我在 xaml 中有一个具有不同皮肤的 wpf 应用程序,如下所示:
I have a wpf application with different skins in xaml like this:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<skins:SkinResourceDictionary ExpressRetailSource="Skins/ExpressRetailColors.xaml"
Lager157Source="Skins/Lager157Colors.xaml" />
<skins:SkinResourceDictionary ExpressRetailSource="Skins/ExpressRetailImages.xaml"
Lager157Source="Skins/Lager157Images.xaml" />
<skins:SkinResourceDictionary ExpressRetailSource="Skins/ExpressRetailStyles.xaml"
Lager157Source="Skins/Lager157Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
这是在 app.xml 文件中 - 在我的配置文件中,我选择了这样的皮肤,
This is in the app.xml file - and in my config file i pick a skin like this,
public App()
{
ExpressConfiguration.CopyConfigToProgramData();
var skinConfig = ExpressConfiguration.GetParamValue("Skin", "ExpressRetail");
switch (skinConfig.ToLower())
{
case "expressretail":
{
Skin = Skin.ExpressRetail;
break;
}
case "lager157":
{
Skin = Skin.Lager157;
break;
}
}
}
public static Skin Skin { get; set; }
无论如何,我可以在不重新编译的情况下更改配置文件中的皮肤,但我的目标是能够更改三个文件:..colors.xaml、...Images.xaml 和 ...styles.xaml重新编译项目.在我的解决方案中,它看起来像这样:
Any way, i can offcourse change skin in the config file without recompile but my goal is to be able to change the three files: ..colors.xaml, ...Images.xaml and ...styles.xaml without recompile the project. In my solution it look like this:
我希望它们作为内容文件,并且能够复制到输出的某个地方,这样它们就可以在不重新编译的情况下进行更改.前 ->
I want them as content files, and be able to copie to the output somewhere so they can be change without recompilation. Ex ->
<Border x:Name="border" CornerRadius="15" Background="White" BorderBrush="Black"
BorderThickness="2" >
如果我不希望按钮上有任何角,请将 CornerRadius 更改为 0!
change CornerRadius to 0 if i dont want any corners on my buttons !
推荐答案
如果您将有效的未编译资源字典作为 .xaml 文件放在 exe 旁边的文件夹中,那么您可以使用与您使用的相同类型的 xaml 合并它与编译到您的 exe 中的资源字典一起使用.
If you put a valid uncompiled resource dictionary as a .xaml file in the folder alongside your exe then you can merge it using the same sort of xaml you'd use with a resource dictionary which is compiled into your exe.
这是我提到的示例中的 app.xaml.
Here's app.xaml from the sample I mentioned.
<Application x:Class="Wpf_Dynamic_XAML_FlatResourceDictionary.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="FlatFile.xaml"/>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
在示例 FlatFile.xaml 中是一个资源字典,其属性为 Content 和 copy if newer.
In the sample FlatFile.xaml is a resource dictionary whose properties are Content and copy if newer.
您可以从解决方案中完全省略它,而是手动复制 exe 旁边的资源字典,它仍然会合并.
You could omit that from the solution entirely and copy the resource dictionary manually next to the exe instead and it would still merge.
你可以在代码中做同样的事情.
You may do the equivalent in code.
在我们游戏的地图构建器中,您可以选择将未编译的 .xaml 文件合并为资源字典.然后,这允许您在地图编辑器外部构建内容并将其导入其中.用户从特定文件夹中的文件列表中选择一个文件名.该应用程序根本不引用内容,用户可以根据需要在外部添加或删除文件.
In the map builder for our game you can choose to merge in an uncompiled .xaml file as a resource dictionary. This then allows you to build content external to the map editor and import into it.The user picks a file name off a list of files in a specific folder.The application has no reference to the content at all and a user can add or remove files externally as they wish.
var rdUrl = System.IO.Path.Combine(FilesIO.MapsCustomResourcesFolder, vm.SelectedFile.Name + ".xaml");
try
{
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(rdUrl, UriKind.Absolute);
Application.Current.Resources.MergedDictionaries.Add(rd);
}
catch (Exception ex)
{
// Some user message stuff
}
请记住,如果您让用户手动编辑资源字典,那么他们很可能会做出破坏它的更改.在 app.xaml 中合并的无效资源字典会在加载时崩溃您的应用程序.代码和错误捕获可以明确告诉用户他们破坏了资源字典并允许他们继续使用您的应用.
Bear in mind that if you let the users manually edit a resource dictionary then they could well make changes which break it. An invalid resource dictionary merged in app.xaml will crash your app on load.Code and error trapping can explicitly tell a user they broke their resource dictionary and allow them to carry on using your app.
您也可以使用 XamlReader.Load() 从文件生成资源字典并合并该资源字典.
You could alternatively use XamlReader.Load() to generate a resource dictionary from a file and merge that resource dictionary.
这篇关于是否可以在源代码之外的 xaml 中使用皮肤?(更改 xaml 无需重新编译)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!