我的本地化属性存在问题,例如:
public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{ }
private static string GetMessageFromResource(string resourceId)
{
var propertyInfo = typeof(Lockit).GetProperty(resourceId, BindingFlags.Static | BindingFlags.Public);
return (string)propertyInfo.GetValue(null, null);
}
}
当我使用具有此属性的属性时,它已在PropertyGrid中本地化,但是当我更改当前CultureInfo时,即使我再次创建此PropertyGrid,它也不会刷新。我尝试通过以下方式手动调用此属性:
foreach (PropertyInfo propertyInfo in myPropertiesInfoTab)
{
object[] custom_attributes = propertyInfo.GetCustomAttributes(false);
}
调用属性构造函数,但新创建的PropertyGrid仍具有旧文化显示名称的属性(始终与首次创建的值相同)。
当我重新启动应用程序时它可以工作,但我不想这样做。有没有解决方案?
答案 0 :(得分:2)
我们可以在一个简单但完整的例子中重现这一点(只需在名称上添加一个计数器,以代表每个翻译):
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Show();
Show();
}
static void Show()
{
using(var grid = new PropertyGrid
{Dock = DockStyle.Fill, SelectedObject = new Foo { Bar = "def"} })
using(var form = new Form { Controls = { grid }})
{
form.ShowDialog();
}
}
class Foo
{
[CheekyDisplayName("abc")]
public string Bar { get; set; }
}
public class CheekyDisplayNameAttribute : DisplayNameAttribute
{
public CheekyDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{ }
private static string GetMessageFromResource(string resourceId)
{
return resourceId + Interlocked.Increment(ref counter);
}
private static int counter;
}
这表明在调用之间缓存了属性。也许最简单的解决方法是将翻译延迟到查询DisplayName
的时间:
public class CheekyDisplayNameAttribute : DisplayNameAttribute
{
public CheekyDisplayNameAttribute(string resourceId)
: base(resourceId)
{ }
private static string GetMessageFromResource(string resourceId)
{
return resourceId + Interlocked.Increment(ref counter);
}
public override string DisplayName
{
get { return GetMessageFromResource(base.DisplayName); }
}
private static int counter;
}
但请注意,这可以称为 lot 次(每次显示36次); 可能想要将值与缓存的文化一起缓存:
private CultureInfo cachedCulture;
private string cachedDisplayName;
public override string DisplayName
{
get
{
var culture = CultureInfo.CurrentCulture;
if (culture != cachedCulture)
{
cachedDisplayName = GetMessageFromResource(base.DisplayName);
cachedCulture = culture;
}
return cachedDisplayName;
}
}