【发布时间】:2009-03-16 23:18:54
【问题描述】:
我有一个 .NET 自定义控件,它以与文化相关的方式显示信息。为了提高性能,我在控件中缓存了一些信息,而不是每次都生成它。我需要知道文化是否发生了变化,以便我可以适当地重新生成这些内部信息。
我有什么活动吗?还是我每次绘画时都必须测试文化设置,看看它是否发生了变化?
【问题讨论】:
我有一个 .NET 自定义控件,它以与文化相关的方式显示信息。为了提高性能,我在控件中缓存了一些信息,而不是每次都生成它。我需要知道文化是否发生了变化,以便我可以适当地重新生成这些内部信息。
我有什么活动吗?还是我每次绘画时都必须测试文化设置,看看它是否发生了变化?
【问题讨论】:
您可以处理SystemEvents.UserPreferenceChanged 事件:
SystemEvents.UserPreferenceChanged += (sender, e) =>
{
// Regional settings have changed
if (e.Category == UserPreferenceCategory.Locale)
{
// .NET also caches culture settings, so clear them
CultureInfo.CurrentCulture.ClearCachedData();
// do some other stuff
}
};
Windows 还将WM_SETTINGSCHANGE message 广播到所有窗体。您可以尝试通过覆盖 WndProc 来检测它,所以它看起来像:
// inside a winforms Form
protected override void WndProc(ref Message m)
{
const int WM_SETTINGCHANGE = 0x001A;
if (m.Msg == WM_SETTINGCHANGE)
{
// .NET also caches culture settings, so clear them
CultureInfo.CurrentCulture.ClearCachedData();
// do some other stuff
}
base.WndProc(ref m);
}
请注意,您可能还想调用 CultureInfo.CurrentCulture.ClearCachedData() 以使新创建的线程的文化信息无效,但请记住,现有线程的 CurrentCulture 不会更新,如 MSDN 中所述:
ClearCachedData方法不刷新现有线程的Thread.CurrentCulture属性中的信息。但是,未来的线程将具有新的CultureInfo属性值。
【讨论】:
我怀疑你可以通过让你的代码通过一个中心属性改变文化来做到这一点,它本身会做一些事情,比如引发一个事件;但要非常小心:静态事件是一种非常简单的方法,可以让大量对象卡在内存中(即 GC 将它们视为活动的)。如果你采用这种方法,你可能想看看WeakReference...
【讨论】: