由于Control.Name属性被标记为[Browsable(false)],导致Name属性无法显示,请问怎么解决呢?我要让所有的控件(比如TextBox,Button,ComboBox)都能显示Name出来,所以不能用派生子控件的方式去做
解决方案 »
- 截取字符串问题
- 求助DataGridView中实现数据的增删改查并和数据库中的表同步!!!
- c#中要使从数据库里得到的数据在dataGrid里某一列进行算术判断一下,若大于100就用红体显示怎么实现,请高手赐教
- 复合框赋值的问题-急!
- 把excel转换成sql时打开excel和没打开excel读出来的datatable行数是不一样的??
- 下面是语言的程序,我想转化成c#,请问怎么转化
- Socket通信问题,求教
- DataGridView打印精灵组件 ,欢迎大家使用!+ 并代做.NET程序
- C# DirectShow开发的问题
- 请问C#中的SQL语句如何正确书写?
- 如何判断一个字符串中是否存在相同的字符
- 请教 关于winform下的System.Drawing.Image开发
http://space.itpub.net/12639172/viewspace-488958
btn.Name="MyName";
btn.Text="OK";propertyGrid1.SelectedObject=btn;在propertyGrid1控件上,会显示btn的Text属性会OK,但是不会显示Name属性,我希望把Name属性也要显示出来因为我的SelectedObject在运行时可能是不同的控件,所以不能通过从Button派生出自己的自定义Button来实现
。。
只能在PropertyGrid,TypeConverter等上面考虑,你不能修改SelectedObject对象啊,那不就影响这些控件的正常使用了吗?。
TextBox tx = new TextBox();
propertyGrid1.BrowsableAttributes = new AttributeCollection(new BrowsableAttribute(false));
propertyGrid1.SelectedObject = tx;
反正要精确控制属性的显示,只能派生一个类才行。
btn.Name = "MyName";
btn.Text = "OK"; propertyGrid1.BrowsableAttributes = new AttributeCollection(new BrowsableAttribute(false));
propertyGrid1.BrowsableAttributes = new AttributeCollection(new ReadOnlyAttribute(false));
propertyGrid1.SelectedObject = btn;
propertyGrid1.BrowsableAttributes = new AttributeCollection();
就可以显示出来,但是有一个问题,如果有子对象的话,子对象的Name显示不了比如放一个Panel,在Panel放一个Button
propertyGrid1.SelectedObject=panel1;
然后你在PropertyGrid面板中选中Controls这个属性,并打开,会弹出新的一个对话框,里面没有Name属性
PropertyDescriptor pd= TypeDescriptor.CreateProperty(typeof(Control),"Name",typeof(string));
然后把这个属性描述添加进去,但是我不知道添加到哪里
但是动态创建的类型虽然可以给PropertyGrid使用,但是诸如你点击Controls属性,在那个弹出窗口里添加的子控件又是不可控制的,最多只能控制第一层的PropertyGrid的SelectObject,之后属性里弹出的PropertyGrid控制不到,除非更改类本身的属性类型,那样还不如继承一个类定制更好。
{
private static TypeDescriptionProvider defaultTypeProvider =
TypeDescriptor.GetProvider(typeof(Control)); public ControlDescriptionProvider() : base(defaultTypeProvider) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
return new TitleCustomTypeDescriptor(defaultDescriptor);
}
}
class TitleCustomTypeDescriptor : CustomTypeDescriptor
{
public TitleCustomTypeDescriptor(ICustomTypeDescriptor parent)
: base(parent)
{
customFields.Add(new NamePropertyDescriptor());
} private List<PropertyDescriptor> customFields = new List<PropertyDescriptor>(); public override PropertyDescriptorCollection GetProperties()
{
return new PropertyDescriptorCollection(base.GetProperties()
.Cast<PropertyDescriptor>().Union(customFields).ToArray());
} public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return new PropertyDescriptorCollection(base.GetProperties(attributes)
.Cast<PropertyDescriptor>().Union(customFields).ToArray());
}
} class NamePropertyDescriptor : PropertyDescriptor
{
public NamePropertyDescriptor() : base("(Name)", null) { } public override bool CanResetValue(object component)
{
return false;
} public override Type ComponentType
{
get
{
return typeof(Control);
}
} public override object GetValue(object component)
{
Control control = (Control)component;
return control.Name;
} public override bool IsReadOnly
{
get
{
return false;
}
} public override Type PropertyType
{
get
{
return typeof(string);
}
} public override void ResetValue(object component)
{
throw new NotImplementedException();
} public override void SetValue(object component, object value)
{
Control control = (Control)component;
control.Name = value.ToString();
} public override bool ShouldSerializeValue(object component)
{
return false;
}
}下面是测试代码:ControlDescriptionProvider provider = new ControlDescriptionProvider();
TypeDescriptor.AddProvider(provider, typeof(Control));
//下面测试下Label,任何控件都可以。
Label label = new Label();
label.Name = "123";
propertyGrid1.SelectedObject = label;
{
private static TypeDescriptionProvider defaultTypeProvider =
TypeDescriptor.GetProvider(typeof(Object)); public ObjectDescriptionProvider() : base(defaultTypeProvider) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
return objectType.GetProperty("Name") == null ? defaultDescriptor : new NameCustomTypeDescriptor(defaultDescriptor);
}
}
class NameCustomTypeDescriptor : CustomTypeDescriptor
{
public NameCustomTypeDescriptor(ICustomTypeDescriptor parent)
: base(parent)
{
customFields.Add(new NamePropertyDescriptor());
} private List<PropertyDescriptor> customFields = new List<PropertyDescriptor>(); public override PropertyDescriptorCollection GetProperties()
{
return new PropertyDescriptorCollection(base.GetProperties()
.Cast<PropertyDescriptor>().Union(customFields).ToArray());
} public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return new PropertyDescriptorCollection(base.GetProperties(attributes)
.Cast<PropertyDescriptor>().Union(customFields).ToArray());
}
} class NamePropertyDescriptor : PropertyDescriptor
{
public NamePropertyDescriptor() : base("(Name)", null) { } public override bool CanResetValue(object component)
{
return false;
} public override Type ComponentType
{
get
{
return typeof(Object);
}
} public override object GetValue(object component)
{
Object control = (Object)component;
return control.GetType().GetProperty("Name").GetValue(control, null);
} public override bool IsReadOnly
{
get
{
return false;
}
} public override Type PropertyType
{
get
{
return typeof(string);
}
} public override void ResetValue(object component)
{
throw new NotImplementedException();
} public override void SetValue(object component, object value)
{
Object control = (Object)component;
control.GetType().GetProperty("Name").SetValue(control, value, null);
} public override bool ShouldSerializeValue(object component)
{
return false;
}
}示例:ObjectDescriptionProvider provider = new ObjectDescriptionProvider();
TypeDescriptor.AddProvider(provider, typeof(Object));
//下面测试下ToolStripMenuItem,任何控件都可以。
ToolStripItem toolItem = new ToolStripMenuItem();
toolItem.Name = "123";
propertyGrid1.SelectedObject = toolItem;
{
public NamePropertyDescriptor() : base("(Name)", null) { }
class ObjectDescriptionProvider : TypeDescriptionProvider
{
public ObjectDescriptionProvider() : base(TypeDescriptor.GetProvider(typeof(Object))) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
PropertyInfo pi = objectType.GetProperty("Name");
if (pi != null && pi.PropertyType==typeof(string))
{
BrowsableAttribute[] bas = (BrowsableAttribute[])pi.GetCustomAttributes(typeof(BrowsableAttribute), false);
if (bas.Length > 0 && !bas[0].Browsable)
return new NameCustomTypeDescriptor(defaultDescriptor);
}
return defaultDescriptor;
}
} class NameCustomTypeDescriptor : CustomTypeDescriptor
{
public NameCustomTypeDescriptor(ICustomTypeDescriptor parent)
: base(parent)
{
} public override PropertyDescriptorCollection GetProperties()
{
PropertyDescriptorCollection pdc = base.GetProperties();
PropertyDescriptor[] pds = new PropertyDescriptor[pdc.Count + 1];
pds[0] = new NamePropertyDescriptor();
pdc.CopyTo(pds, 1);
return new PropertyDescriptorCollection(pds);
} public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection pdc = base.GetProperties(attributes);
PropertyDescriptor[] pds = new PropertyDescriptor[pdc.Count + 1];
pds[0] = new NamePropertyDescriptor();
pdc.CopyTo(pds, 1);
return new PropertyDescriptorCollection(pds);
}
} class NamePropertyDescriptor : PropertyDescriptor
{
public NamePropertyDescriptor() : base("(Name)", null) { } public override bool CanResetValue(object component)
{
return false;
} public override Type ComponentType
{
get
{
return typeof(object);
}
} public override object GetValue(object component)
{
return component.GetType().GetProperty("Name").GetValue(component, null);
} public override bool IsReadOnly
{
get
{
return false;
}
} public override Type PropertyType
{
get
{
return typeof(string);
}
} public override void ResetValue(object component)
{
throw new NotImplementedException();
} public override void SetValue(object component, object value)
{
component.GetType().GetProperty("Name").SetValue(component, value, null);
} public override bool ShouldSerializeValue(object component)
{
return false;
}
}
{
public ObjectDescriptionProvider() : base(TypeDescriptor.GetProvider(typeof(object))) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
PropertyInfo pi = objectType.GetProperty("Name");
if (pi != null&&pi.PropertyType==typeof(string) )
{
BrowsableAttribute[] bas = (BrowsableAttribute[])pi.GetCustomAttributes(typeof(BrowsableAttribute), false);
if (bas.Length > 0 && !bas[0].Browsable)
return new NameCustomTypeDescriptor(defaultDescriptor);
}
return defaultDescriptor;
}
} class NameCustomTypeDescriptor : CustomTypeDescriptor
{
public NameCustomTypeDescriptor(ICustomTypeDescriptor parent)
: base(parent)
{
pd = TypeDescriptor.CreateProperty(parent.GetType().GetField("_objectType", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(parent) as Type, "Name", typeof(string), BrowsableAttribute.Yes);
}
private PropertyDescriptor pd;
public override PropertyDescriptorCollection GetProperties()
{
PropertyDescriptorCollection pdc = base.GetProperties();
PropertyDescriptor[] pds = new PropertyDescriptor[pdc.Count + 1];
pds[0] = pd;
pdc.CopyTo(pds, 1);
return new PropertyDescriptorCollection(pds);
} public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection pdc = base.GetProperties(attributes);
PropertyDescriptor[] pds = new PropertyDescriptor[pdc.Count + 1];
pds[0] = pd;
pdc.CopyTo(pds, 1);
return new PropertyDescriptorCollection(pds);
}
}
class NameCustomTypeDescriptor : CustomTypeDescriptor
{
public NameCustomTypeDescriptor(ICustomTypeDescriptor parent,Type objectType)
: base(parent)
{
pd = TypeDescriptor.CreateProperty(objectType, "Name", typeof(string), BrowsableAttribute.Yes);
}
//.................
你再看下调用方,有个objectType参数可以直接传递给它的。另外这种方法虽然可以,但是你没有去掉原来的那个Name,实际连隐藏属性一起显示的话,就会看到两个Name(完全同名),太别扭了。
2.显示的时候没有,我觉得就没什么问题了
3.我又发现了一种新方法,可以不自定义类型(ObjectDescriptionProvider,NameCustomTypeDescriptor 都可以不要)
private void propertyGrid1_SelectedObjectsChanged(object sender, EventArgs e)
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(propertyGrid1.SelectedObject.GetType());
PropertyDescriptor pd = pdc.Find("Name", false);
if (pd != null && !pd.IsBrowsable)
{
pdc.GetType().GetField("readOnly", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(pdc, false);
pdc.Add(TypeDescriptor.CreateProperty(propertyGrid1.SelectedObject.GetType(), "Name", typeof(string), BrowsableAttribute.Yes));
}
}但是必须为每一种类型执行一次操作,直接在object或Control类上操作不行,所以我把代码放在SelectedObjectsChanged事件中,每次使用propertyGrid1.SelectedObject.GetType(),但问题是,如果有子项就不好弄了,比如MenuStrip.Items,修改它的子项并不会触发propertyGrid1的SelectedObjectsChanged事件,我分析后发现子项其实是一个VsPropertyGrid类型,但是没法取得Instance,所以没法注册其SelectedObjectsChanged事件
static void Main()
{
foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies())
AddNameProperty(ass);
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);//code static void AddNameProperty(Assembly ass)
{
foreach (Type t in ass.GetTypes())
{
try
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(t);
PropertyDescriptor pd = pdc.Find("Name", false);
if (pd != null && !pd.IsBrowsable)
{
pdc.GetType().GetField("readOnly", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(pdc, false);
pdc.Add(TypeDescriptor.CreateProperty(t, "Name", typeof(string), BrowsableAttribute.Yes));
}
}
catch
{
}
}
}
static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
AddNameProperty(args.LoadedAssembly);
}
把所有满足条件的都添加上,这样不需要处理SelectedObjectsChanged事件了
我前段时间搞这个东西。下载了动态属性的列子。列子好象msdn上也有。
new Name
{
get{retrun base.Name}
set{base.Name=value;}
}上面的搞了那么多复杂的方法干啥
这个兄弟说的很对。
[Browsable(True)]
public new Name
{
get{retrun base.Name}
set{base.Name=value;}
}
AttributeCollection attrs= props["Name"].Attributes;BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic |BindingFlags.CreateInstance;
FieldInfo type = typeof(BrowsableAttribute).GetField("browsable", flags);
filedInfo.SetValue(attrs[typeof(ReadOnlyAttribute)], false/true);以上方法适应于所有的字段属性标签