【问题标题】:How to refresh localized attributes in PropertyGrid如何刷新 PropertyGrid 中的本地化属性
【发布时间】:2012-08-30 09:26:32
【问题描述】:

我的本​​地化属性有问题,例如:

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 仍然具有旧区域性显示名称的属性(始终与第一次创建的值相同)。

当我重新启动应用程序时它可以工作,但我不想这样做。有什么解决办法吗?

【问题讨论】:

    标签: c# attributes globalization propertygrid


    【解决方案1】:

    我们可以在一个简单但完整的示例中重现这一点(只需在名称上添加一个计数器,以表示每次发生的翻译):

    [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;
    }
    

    但是,请注意,这可以被称为 很多 次(每次放映 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;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 2011-08-11
      相关资源
      最近更新 更多