我的 winforms 應用程式中有一個 PropertyGrid,它顯示了一些選定物件的屬性。我希望某個屬性有時會顯示,有時不會,根據我的選擇,(假設每次在運行時按下特定按鈕時可瀏覽性都會發生變化)。使用 BrowsableAttribute 在運行時之前設定可瀏覽性非常容易,據我所知,屬性是在設計時設定的,因此我需要另一個解決方案。在很多地方我找到了這段代碼:
public static void ChangeBrowsability(SomeObject obj, string propertyName, bool isBrowsable)
{//usage: supposed to change browsability at runtime
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(obj)[propertyName];
BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
FieldInfo browsableField = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
browsableField.SetValue(attrib, isBrowsable);
}
第一個問題是browsableField是始終空出于某種原因,我想知道這是為什么。也可能歡迎此代碼的替代解決方案。
uj5u.com熱心網友回復:
你無法改變屬性定義的現實——它們被嵌入到 IL 中;然而,你可以撒謊和欺騙。winformsPropertyGrid不直接進入反射 - 它使用間接路由 via TypeDescriptor,并且TypeDescriptor 默認使用反射。但是,您可以實作自己的描述符實作,改變一切,特別是(這種情況)PropertyDescriptor.IsBrowsable。這是好訊息。
壞訊息是這很難。喜歡; 真的很難;您必須非常非常關心此功能才能使用它。它涉及:
- 捕獲傳出的基于反射的
ICustomTypeDescriptor,因此您可以將其用作基礎 - 實作您自己的
ICustomTypeDescriptor將屬性公開為“裝飾器” - 注冊一個
TypeDescriptionProvider暴露你自己的型別描述符的 - 捕獲基于傳出的反射,
PropertyDescriptorCollection以便您可以將它們用作基礎 - 實作您自己的
PropertyDescriptors裝飾器,轉發大部分 API,除了IsBrowsable您要添加自己的邏輯的地方
可行,但是:非常復雜和令人費解,老實說:使用基本上過時且十年未見愛的 API。一個有效的例子很容易遇到數百行 C#,所以超出了我在這里可以合理提供的范圍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/339229.html
上一篇:出現滾動條時如何正確應用修改后的C#WinFormListBox邊框顏色
下一篇:MySQL——視圖的介紹
