[英]How can I create subclass at run-time to map some properties then cast it back to parent class?
[英]Hide some properties in PropertyGrid at run-time
我正在做一個項目,允許用戶自定義Control
的屬性。 我有一個表單,它有一個控件,如Label
、 TextBox
、 Button
和PropertyGrid
控件。 當在用戶點擊Label
我顯示的的屬性Label
在ProeprtyGrid
這是使用以下代碼中的所有工作罰款:
propertyGrid1.SelectedObject = SelectedControl;
但我只想顯示一些屬性,如BackColor
、 Font
、 ForeColor
、 Text
。 是否可以隱藏屬性,因為我不希望用戶更改它或向他們顯示? 如果是,如何?
我相信您正在尋找自定義類型描述符。
雖然另一個答案是共享有關PropertyGrid
Browsable
屬性和BrowsableAttributes
的正確信息,但我認為這不是該問題的正確實用解決方案。
為現有控件類(如Label
、 Button
等)設置Browsable
屬性或任何其他自定義屬性是不切實際的。 因為通過這種方式,op 需要覆蓋這些類的所有屬性並用合適的屬性裝飾它們。 甚至最糟糕的是,並非所有的財產都是可覆蓋的。
實際的解決方案是什么?
正如我之前提到的,我相信您正在尋找自定義類型描述符。 您可以提供有關分配新TypeDescriptor
或實現ICustomTypeDescriptor
或從CustomTypeDescriptor
派生的對象的元數據。
例子
例如,我在這里創建了一個從CustomTypeDescriptor
派生的CustomObjectWrapper
類, CustomTypeDescriptor
在構造函數中接受一個對象。 通過這種方式,我可以通過覆蓋GetProperties
來簡單地過濾包裝對象的屬性。
然后我沒有將button1
分配給PropertyGrid
,而是將它包裝在CustomObjectWrapper
並將CustomObjectWrapper
給屬性網格。 這樣它只顯示過濾后的屬性,而這些屬性實際上來自button1
。
這是植入:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
public class CustomObjectWrapper : CustomTypeDescriptor
{
public object WrappedObject { get; private set; }
public List<string> BrowsableProperties { get; private set; }
public CustomObjectWrapper(object o)
:base(TypeDescriptor.GetProvider(o).GetTypeDescriptor(o))
{
WrappedObject = o;
BrowsableProperties = new List<string>() { "Text", "BackColor" };
}
public override PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(new Attribute[] { });
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Where(p=>BrowsableProperties.Contains(p.Name))
.Select(p => TypeDescriptor.CreateProperty(
WrappedObject.GetType(),
p,
p.Attributes.Cast<Attribute>().ToArray()))
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
並作為用法:
propertyGrid1.SelectedObject = new CustomObjectWrapper(button1);
您可以簡單地添加新的屬性名BrowsableProperties
的的CustomObjectWrapper
。 這是公共財產。
請注意,這僅對隱藏屬性有用(如果可以)。 Reza Aghaei 的答案實際上是正確的答案。
我將把它留在這里,因為它適用於另一種情況,當您只想在可以訪問屬性時隱藏它。
原來的
最簡單的方法可能是使用
[Browsable(false)]
指定是否應在“屬性”窗口中顯示屬性或事件。
[Browsable(false)]
public int SecretSquirrels
{
get; set;
}
也正如Marc Gravell所指出的,還有
PropertyGrid.BrowsableAttributes 屬性
獲取或設置與屬性網格附加到的對象關聯的可瀏覽屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.