如何在ItemsControl生成其容器之前或之后更改加载的主题资源字典,但在那时不更改?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在ItemsControl生成其容器之前或之后更改加载的主题资源字典,但在那时不更改?相关的知识,希望对你有一定的参考价值。
我动态加载应用程序资源字典(一次加载3个中的2个:]
- 始终是基本资源字典
- Light.xaml主题文件
- 一个Dark.xaml主题文件
如果主窗口已经为MergedDictionaries
时通常更改Loaded
属性的值,则会出现异常(调用堆栈here):
System.InvalidOperationException:'在内容生成过程中无法调用StartAt。'
[如果我使用MergedDictionaries
更改Dispatcher.BeginInvoke
属性的值,则当我在(1)的代码隐藏中使用资源时,它会通过一个异常表示该资源尚未加载(例如,通过StaticResource
使用资源那不存在)。
我不想使用App.xaml文件,因为对于具有单实例应用程序,我使用了一个从Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
继承并调用App.cs文件中的代码的类。
我可以在应用程序代码中的几个地方调用LoadTheme方法,并且我想使其稳定。
App.cs
(no XAML)
public class App : System.Windows.Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LoadTheme(AppTheme.Light);
var w = new MainWindow();
ShutdownMode = ShutdownMode.OnMainWindowClose;
MainWindow = w;
w.Show();
}
internal ResourceDictionary MLight = null,
MDark = null,
MMain = null;
internal ResourceDictionary GetLightThemeDictionary()
{
if (MLight == null)
{
MLight = new ResourceDictionary() { Source = new Uri("Themes/Light.xaml", UriKind.Relative) };
}
return MLight;
}
internal ResourceDictionary GetDarkThemeDictionary()
{
if (MDark == null)
{
MDark = new ResourceDictionary() { Source = new Uri("Themes/Dark.xaml", UriKind.Relative) };
}
return MDark;
}
internal ResourceDictionary GetMainDictionary()
{
if (MMain == null)
{
MMain = new ResourceDictionary() { Source = new Uri("AppResources.xaml", UriKind.Relative) };
}
return MMain;
}
internal void LoadTheme(AppTheme t)
{
//Dispatcher.BeginInvoke(new Action(() =>
//{
if (Resources.MergedDictionaries.Count == 2)
{
switch (t)
{
case AppTheme.Dark:
Resources.MergedDictionaries[1] = GetDarkThemeDictionary();
break;
default:
Resources.MergedDictionaries[1] = GetLightThemeDictionary();
break;
}
}
else if (Resources.MergedDictionaries.Count == 1)
{
switch (t)
{
case AppTheme.Dark:
Resources.MergedDictionaries.Add(GetDarkThemeDictionary());
break;
default:
Resources.MergedDictionaries.Add(GetLightThemeDictionary());
break;
}
}
else
{
Resources.MergedDictionaries.Clear();
Resources.MergedDictionaries.Add(GetMainDictionary());
LoadTheme(t);
}
//}), System.Windows.Threading.DispatcherPriority.Normal); // how to process this after the ItemsControl has generated its elements?
}
}
我试图做一个测试示例,但是失败了-我创建了一个有效的程序,因为每次应用模板时都会设置ItemsControl.ItemsSource
。在我的实际项目中,我通过数据绑定(有时是手动设置)来设置ItemsSource
,但是我不确定这是我的实际项目中缺少的内容。
我使用.NET Framework 4.7.2,VS 2019,Win 10 Pro。
谢谢。
OnStartup
方法现在看起来像这样(在构建MainWindow
之前,我刚刚加载了基础词典和一个主题):以上是关于如何在ItemsControl生成其容器之前或之后更改加载的主题资源字典,但在那时不更改?的主要内容,如果未能解决你的问题,请参考以下文章
在部署到Servlet容器之前,如何生成包含SpringBoot的War文件
如何在gmail中发送电子邮件之前或之后获取消息ID? [复制]
如何获取包含 ItemsControl 内容的 Panel 实例?
KafkaContainer - 如何在启动()之后在 Spring Boot 中读取 kafka 容器端口作为属性 / 如何在启动之前配置 Kafka 端口