Xamarin 以编程方式交换单个 ResourceDictionary
Xamarin swap single ResourceDictionary programmatically
我目前正在尝试让自定义主题与 Xamarin 应用程序一起使用,并且我找到了一种方法可以按照我想要的方式进行这项工作,但它似乎非常低效,所以我想我会问看看你们有没有更好的答案。
所以问题来了,我想构建一个用户可以更改主题的屏幕(会有很多,不仅仅是 light/dark),我想换出当前主题 ResourceDictionary 并将其替换为新选择的主题的 ResourceDictionary。问题是我还希望该应用程序具有其他全局 ResourceDictionaries,我发现的每个教程都建议调用 Resources.MergedDictionaries.Clear(),但那样会摆脱我的其他 ResourceDictionaries。
这是我的Xaml,我不想替换DefaultButton.xaml或LinkButton.xaml,我只想替换LightTheme.xaml。
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.App">
<Application.Resources>
<ResourceDictionary Source="Themes/ResourceDictionaries/LightTheme.xaml" />
<ResourceDictionary Source="Styles/DefaultButton.xaml" />
<ResourceDictionary Source="Styles/LinkButton.xaml" />
</Application.Resources>
</Application>
然后在我的应用程序中class我有
public void ChangeTheme(ThemeOptions theme)
{
ResourceDictionary newRes;
switch (theme)
{
case ThemeOptions.Light:
newRes = new LightTheme();
break;
case ThemeOptions.Dark:
newRes = new DarkTheme();
break;
default:
newRes = new LightTheme();
break;
}
Resources.MergedDictionaries.Clear();
Resources.Add(newRes);
}
显然 DefaultButton.xaml 和 LinkButton.xaml ResourceDictionaries 现在已经被清除了。我可以将它们添加回去,但仅查找和删除主题似乎效率非常低。有没有简单的方法来简单地识别我想要覆盖和替换的 ResourceDictionary?
我相信我可能找到了问题的答案,但没有找到原始问题的答案。我创建了一个“BundledSiteStyles”ResourceDictionary,并将其作为 MergedDictionary 添加到我的每个主题中。然后 App.xaml 文件只加载一个主题,所有样式都随之而来。
所以我的 App.xaml 没有添加 ResourceDictionaries,然后在启动时以编程方式获得活动主题并调用我的 ChangeTheme 函数
public void ChangeTheme(ThemeOptions theme)
{
switch (theme)
{
case ThemeOptions.Light:
Resources = new LightTheme();
break;
case ThemeOptions.Dark:
Resources = new DarkTheme();
break;
default:
Resources = new LightTheme();
break;
}
}
这是我的 LightTheme.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Themes.ResourceDictionaries.LightTheme">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Styles/BundledSiteStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="LinkButtonBackgroundColor">Transparent</Color>
<Color x:Key="LinkButtonTextColor">Blue</Color>
<!-- Add more colours here -->
</ResourceDictionary>
这是我的 BundledSiteStyles.xaml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Styles.BundledSiteStyles">
<ResourceDictionary.MergedDictionaries>
<!-- Add global ResourceDictionaries Here -->
<ResourceDictionary Source="DefaultButton.xaml" />
<ResourceDictionary Source="LinkButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
如果有更 efficient/correct 的方法,请告诉我,但目前看来可行。
假设所有主题都有相同的键,您可以通过遍历它的键来替换它,并替换合并字典中的那些条目。
我没有测试过,但应该是这样的:
var resources = Application.Current.Resources;
foreach (var key in themes.Keys)
resources[key] = themes[key];
我目前正在尝试让自定义主题与 Xamarin 应用程序一起使用,并且我找到了一种方法可以按照我想要的方式进行这项工作,但它似乎非常低效,所以我想我会问看看你们有没有更好的答案。
所以问题来了,我想构建一个用户可以更改主题的屏幕(会有很多,不仅仅是 light/dark),我想换出当前主题 ResourceDictionary 并将其替换为新选择的主题的 ResourceDictionary。问题是我还希望该应用程序具有其他全局 ResourceDictionaries,我发现的每个教程都建议调用 Resources.MergedDictionaries.Clear(),但那样会摆脱我的其他 ResourceDictionaries。
这是我的Xaml,我不想替换DefaultButton.xaml或LinkButton.xaml,我只想替换LightTheme.xaml。
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.App">
<Application.Resources>
<ResourceDictionary Source="Themes/ResourceDictionaries/LightTheme.xaml" />
<ResourceDictionary Source="Styles/DefaultButton.xaml" />
<ResourceDictionary Source="Styles/LinkButton.xaml" />
</Application.Resources>
</Application>
然后在我的应用程序中class我有
public void ChangeTheme(ThemeOptions theme)
{
ResourceDictionary newRes;
switch (theme)
{
case ThemeOptions.Light:
newRes = new LightTheme();
break;
case ThemeOptions.Dark:
newRes = new DarkTheme();
break;
default:
newRes = new LightTheme();
break;
}
Resources.MergedDictionaries.Clear();
Resources.Add(newRes);
}
显然 DefaultButton.xaml 和 LinkButton.xaml ResourceDictionaries 现在已经被清除了。我可以将它们添加回去,但仅查找和删除主题似乎效率非常低。有没有简单的方法来简单地识别我想要覆盖和替换的 ResourceDictionary?
我相信我可能找到了问题的答案,但没有找到原始问题的答案。我创建了一个“BundledSiteStyles”ResourceDictionary,并将其作为 MergedDictionary 添加到我的每个主题中。然后 App.xaml 文件只加载一个主题,所有样式都随之而来。
所以我的 App.xaml 没有添加 ResourceDictionaries,然后在启动时以编程方式获得活动主题并调用我的 ChangeTheme 函数
public void ChangeTheme(ThemeOptions theme)
{
switch (theme)
{
case ThemeOptions.Light:
Resources = new LightTheme();
break;
case ThemeOptions.Dark:
Resources = new DarkTheme();
break;
default:
Resources = new LightTheme();
break;
}
}
这是我的 LightTheme.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Themes.ResourceDictionaries.LightTheme">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Styles/BundledSiteStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="LinkButtonBackgroundColor">Transparent</Color>
<Color x:Key="LinkButtonTextColor">Blue</Color>
<!-- Add more colours here -->
</ResourceDictionary>
这是我的 BundledSiteStyles.xaml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Styles.BundledSiteStyles">
<ResourceDictionary.MergedDictionaries>
<!-- Add global ResourceDictionaries Here -->
<ResourceDictionary Source="DefaultButton.xaml" />
<ResourceDictionary Source="LinkButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
如果有更 efficient/correct 的方法,请告诉我,但目前看来可行。
假设所有主题都有相同的键,您可以通过遍历它的键来替换它,并替换合并字典中的那些条目。
我没有测试过,但应该是这样的:
var resources = Application.Current.Resources;
foreach (var key in themes.Keys)
resources[key] = themes[key];