C# Winform CollectionPropertiesEditor - 如何根据运行时条件隐藏内置 PropertyGrid 中的一些属性
C# Winform CollectionPropertiesEditor - How to hide some properties in the built-in PropertyGrid based on runtime condition
有没有办法隐藏“CollectionPropertiesEditor 的 PropertyGrid”中的显示属性
最近我发现有一种方法可以在 运行 时间更改 PropertyGrid 的 Browsable 属性。
我想知道是否可以对“CollectionPropertiesEditor 的 PropertyGrid”执行此操作,我在 Google 搜索中未能找到相关结果。现在我寄希望于 Whosebug 帮我解决这个问题。
问题:由于新的客户要求,我不得不向 GridColumn 控件添加一些属性。
[Category("Extra")]
[Browsable(true)]
public int? Position { get; set; }
[Category("Extra")]
[Browsable(true)]
public string storedColumn { get; set; }
我希望早点工作:
[Category("Extra")]
[Browsable(matchSomeRunTimeCondition)]
public int? Position { get; set; }
[Category("Extra")]
[Browsable(matchSomeRunTimeCondition)]
public string storedColumn { get; set; }
为什么不起作用?
因为可浏览属性只能接受常量。 matchSomeRunTimeCondition
不是常数。用户可以在应用程序仍处于 运行ning 状态时随时更改它。
在代码中,如果有一个函数可以让我在 运行 时使这些不可见,如果有人能帮我写一个这样的函数或条件语句,我将非常感激:
If (property’s category == “Extra”) {
//Do not show this property in the propertygrid.
//Or in other words, make Browasable Attribute False at run time.
}
在编译时我将 Browsable 属性 设置为 true
因为它需要在某些条件下可见。但是我需要一种机制来根据用户在 运行 时间的选择隐藏它。
这个问题在 属性 网格中通过在加载所选控件时设置它来解决,如 post 所述:
但是在我用来保存我的网格列的 CollectionPropertiesEditor 中没有这种奢侈(至少我不知道如何去做)。
我将网格的所有网格列以 GridColumns 列表的形式存储为 属性。
这就是我目前在网格属性中存储 GridColumns 的方式:
[Browsable(true)]
[Editor(typeof(CollectionPropertiesEditor), typeof(UITypeEditor))]
public List<TGridColumn> Columns { get; set; }
在这里我不知道如何通过我的条件使上述列在运行时间消失。
您应该通过从 CustomTypeDescriptor
派生或实现 ICustomTypeDescriptor
来编写自己的类型描述符。这是一个例子:
我的属性描述符
为 属性 提供自定义描述。在这里,我重写了 Attributes
属性 来为 属性 提供一个新的属性列表。例如我检查 属性 是否有 [Category("Extra")]
,我还在它的属性 collection.
中添加了一个 [Browsable(false)]
using System;
using System.ComponentModel;
using System.Linq;
public class MyPropertyDescriptor : PropertyDescriptor
{
PropertyDescriptor o;
public MyPropertyDescriptor(PropertyDescriptor originalProperty)
: base(originalProperty) { o = originalProperty; }
public override bool CanResetValue(object component)
{ return o.CanResetValue(component); }
public override object GetValue(object component) { return o.GetValue(component); }
public override void ResetValue(object component) { o.ResetValue(component); }
public override void SetValue(object component, object value)
{ o.SetValue(component, value); }
public override bool ShouldSerializeValue(object component)
{ return o.ShouldSerializeValue(component); }
public override AttributeCollection Attributes
{
get
{
var attributes = base.Attributes.Cast<Attribute>().ToList();
var category = attributes.OfType<CategoryAttribute>().FirstOrDefault();
if (category != null && category.Category == "Extra")
attributes.Add(new BrowsableAttribute(false));
return new AttributeCollection(attributes.ToArray());
}
}
public override Type ComponentType { get { return o.ComponentType; } }
public override bool IsReadOnly { get { return o.IsReadOnly; } }
public override Type PropertyType { get { return o.PropertyType; } }
}
MyTypeDescriptor
用于提供类型的自定义 属性 描述符列表。
using System;
using System.ComponentModel;
using System.Linq;
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor original;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor)
: base(originalDescriptor) { original = originalDescriptor; }
public override PropertyDescriptorCollection GetProperties()
{ return this.GetProperties(new Attribute[] { }); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Select(p => new MyPropertyDescriptor(p))
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
MyTypeDescriptionProvider
用于使用 TypeDescriptionProvider
属性将 MyTypeDescriptor
连接到 class。
using System;
using System.ComponentModel;
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type type, object o)
{
ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(type, o);
return new MyTypeDescriptor(baseDescriptor);
}
}
MySampleClass
包含一个用 [Category("Extra")]
修饰的 属性。因此 Property2
在 属性 网格中将不可见。 (在visual studio或collection编辑器甚至run-time属性网格中)
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class MySampleClass
{
public int Property1 { get; set; }
[Category("Extra")]
public string Property2 { get; set; }
}
MyComplexComponent
包含 collection 个 MySampleClass
。所以你可以在 collection 编辑器中看到 MySampleClass
的行为。
using System.Collections.ObjectModel;
using System.ComponentModel;
public class MyComplexComponent:Component
{
public MyComplexComponent()
{
MySampleClasses = new Collection<MySampleClass>();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<MySampleClass> MySampleClasses { get; set; }
}
截图
有没有办法隐藏“CollectionPropertiesEditor 的 PropertyGrid”中的显示属性 最近我发现有一种方法可以在 运行 时间更改 PropertyGrid 的 Browsable 属性。
我想知道是否可以对“CollectionPropertiesEditor 的 PropertyGrid”执行此操作,我在 Google 搜索中未能找到相关结果。现在我寄希望于 Whosebug 帮我解决这个问题。
问题:由于新的客户要求,我不得不向 GridColumn 控件添加一些属性。
[Category("Extra")]
[Browsable(true)]
public int? Position { get; set; }
[Category("Extra")]
[Browsable(true)]
public string storedColumn { get; set; }
我希望早点工作:
[Category("Extra")]
[Browsable(matchSomeRunTimeCondition)]
public int? Position { get; set; }
[Category("Extra")]
[Browsable(matchSomeRunTimeCondition)]
public string storedColumn { get; set; }
为什么不起作用?
因为可浏览属性只能接受常量。 matchSomeRunTimeCondition
不是常数。用户可以在应用程序仍处于 运行ning 状态时随时更改它。
在代码中,如果有一个函数可以让我在 运行 时使这些不可见,如果有人能帮我写一个这样的函数或条件语句,我将非常感激:
If (property’s category == “Extra”) {
//Do not show this property in the propertygrid.
//Or in other words, make Browasable Attribute False at run time.
}
在编译时我将 Browsable 属性 设置为 true
因为它需要在某些条件下可见。但是我需要一种机制来根据用户在 运行 时间的选择隐藏它。
这个问题在 属性 网格中通过在加载所选控件时设置它来解决,如 post 所述:
但是在我用来保存我的网格列的 CollectionPropertiesEditor 中没有这种奢侈(至少我不知道如何去做)。
我将网格的所有网格列以 GridColumns 列表的形式存储为 属性。
这就是我目前在网格属性中存储 GridColumns 的方式:
[Browsable(true)]
[Editor(typeof(CollectionPropertiesEditor), typeof(UITypeEditor))]
public List<TGridColumn> Columns { get; set; }
您应该通过从 CustomTypeDescriptor
派生或实现 ICustomTypeDescriptor
来编写自己的类型描述符。这是一个例子:
我的属性描述符
为 属性 提供自定义描述。在这里,我重写了 Attributes
属性 来为 属性 提供一个新的属性列表。例如我检查 属性 是否有 [Category("Extra")]
,我还在它的属性 collection.
[Browsable(false)]
using System;
using System.ComponentModel;
using System.Linq;
public class MyPropertyDescriptor : PropertyDescriptor
{
PropertyDescriptor o;
public MyPropertyDescriptor(PropertyDescriptor originalProperty)
: base(originalProperty) { o = originalProperty; }
public override bool CanResetValue(object component)
{ return o.CanResetValue(component); }
public override object GetValue(object component) { return o.GetValue(component); }
public override void ResetValue(object component) { o.ResetValue(component); }
public override void SetValue(object component, object value)
{ o.SetValue(component, value); }
public override bool ShouldSerializeValue(object component)
{ return o.ShouldSerializeValue(component); }
public override AttributeCollection Attributes
{
get
{
var attributes = base.Attributes.Cast<Attribute>().ToList();
var category = attributes.OfType<CategoryAttribute>().FirstOrDefault();
if (category != null && category.Category == "Extra")
attributes.Add(new BrowsableAttribute(false));
return new AttributeCollection(attributes.ToArray());
}
}
public override Type ComponentType { get { return o.ComponentType; } }
public override bool IsReadOnly { get { return o.IsReadOnly; } }
public override Type PropertyType { get { return o.PropertyType; } }
}
MyTypeDescriptor
用于提供类型的自定义 属性 描述符列表。
using System;
using System.ComponentModel;
using System.Linq;
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor original;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor)
: base(originalDescriptor) { original = originalDescriptor; }
public override PropertyDescriptorCollection GetProperties()
{ return this.GetProperties(new Attribute[] { }); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Select(p => new MyPropertyDescriptor(p))
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
MyTypeDescriptionProvider
用于使用 TypeDescriptionProvider
属性将 MyTypeDescriptor
连接到 class。
using System;
using System.ComponentModel;
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type type, object o)
{
ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(type, o);
return new MyTypeDescriptor(baseDescriptor);
}
}
MySampleClass
包含一个用 [Category("Extra")]
修饰的 属性。因此 Property2
在 属性 网格中将不可见。 (在visual studio或collection编辑器甚至run-time属性网格中)
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class MySampleClass
{
public int Property1 { get; set; }
[Category("Extra")]
public string Property2 { get; set; }
}
MyComplexComponent
包含 collection 个 MySampleClass
。所以你可以在 collection 编辑器中看到 MySampleClass
的行为。
using System.Collections.ObjectModel;
using System.ComponentModel;
public class MyComplexComponent:Component
{
public MyComplexComponent()
{
MySampleClasses = new Collection<MySampleClass>();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<MySampleClass> MySampleClasses { get; set; }
}
截图