PropertyGrid - 显示特定接口的属性,而不是所有属性
PropertyGrid - Show properties of a specific Interface, not all properties
我目前正面临 PropertyGrid
的(恕我直言)奇怪行为:
我有一个定义了一些属性的接口 (ITest
)。该接口将由 Component
或 Panel
(TestImpl
) 实现。另一部分是一个 Component
(TestComponent
) 有一个 public 属性 的接口类型。默认实现将分配给 属性 并且用户可以将其更改为更具体的实现。如果我将此 TestComponent
添加到 Form
,我希望通过扩展 public-interface-属性,只有接口中声明的属性是可见的 -相反 Panel
或 Component
的所有属性都是可见的...
public interface ITest
{
string AAAAA { get; set; }
}
public class TestImpl: Panel, ITest
{
public string AAAAA { get; set; }
}
public class TestComponent : Component
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public ITest Obj { get; set; }
public TestComponent()
{
Obj = new TestImpl();
}
}
// To reproduce create a simple Form, add a PropertyGrid, create and assign the TestComponent
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
var comp = new TestComponent();
comp.Obj.AAAAA = "Some Text";
propertyGrid1.SelectedObject = comp;
}
}
有没有办法只显示接口属性?
PropertyGrid
默认显示控件的所有 public 可浏览属性的显示名称。它使用您的对象的 TypeDescriptor
来询问其元数据,包括其可浏览的属性及其显示名称。
要自定义此行为,您需要为您的对象注册一个新的 TypeDescriptionProvider
。
例子
在下面的示例中,我创建了一个派生自 Panel
并实现 IMyInterface
的 MyPanel
控件。然后我创建了一个自定义 MyTypeDescriptionProvider<T>
并将 MyTypeDescriptionProvider<IMyInterface>
设置为我的控件的 TypeDescriptionProvider
。
这样,当您将 MyPanel
的实例设置为 PropertyGrid
的 SelectedObject
时,只有 IMyInterface
的属性将显示在 PropertyGrid
中.
using System;
using System.ComponentModel;
using System.Windows.Forms;
public interface IMyInterface
{
string MyProperty1 { get; set; }
string MyProperty2 { get; set; }
}
public class MyTypeDescriptionProvider<T> : TypeDescriptionProvider
{
public MyTypeDescriptionProvider() : base(TypeDescriptor.GetProvider(typeof(T))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType,
object instance)
{
return base.GetTypeDescriptor(typeof(T), instance);
}
}
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider<IMyInterface>))]
public class MyPanel : Panel, IMyInterface
{
public string MyProperty1 { get; set; }
public string MyProperty2 { get; set; }
}
注意: 作为重要说明,请记住此类功能对设计时根本没有用。因为在设计时,您需要在设计器中的 PropertyGrid
中显示控件的属性,并且您需要让设计器知道这些属性以便能够为它们序列化值。
我目前正面临 PropertyGrid
的(恕我直言)奇怪行为:
我有一个定义了一些属性的接口 (ITest
)。该接口将由 Component
或 Panel
(TestImpl
) 实现。另一部分是一个 Component
(TestComponent
) 有一个 public 属性 的接口类型。默认实现将分配给 属性 并且用户可以将其更改为更具体的实现。如果我将此 TestComponent
添加到 Form
,我希望通过扩展 public-interface-属性,只有接口中声明的属性是可见的 -相反 Panel
或 Component
的所有属性都是可见的...
public interface ITest
{
string AAAAA { get; set; }
}
public class TestImpl: Panel, ITest
{
public string AAAAA { get; set; }
}
public class TestComponent : Component
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public ITest Obj { get; set; }
public TestComponent()
{
Obj = new TestImpl();
}
}
// To reproduce create a simple Form, add a PropertyGrid, create and assign the TestComponent
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
var comp = new TestComponent();
comp.Obj.AAAAA = "Some Text";
propertyGrid1.SelectedObject = comp;
}
}
有没有办法只显示接口属性?
PropertyGrid
默认显示控件的所有 public 可浏览属性的显示名称。它使用您的对象的 TypeDescriptor
来询问其元数据,包括其可浏览的属性及其显示名称。
要自定义此行为,您需要为您的对象注册一个新的 TypeDescriptionProvider
。
例子
在下面的示例中,我创建了一个派生自 Panel
并实现 IMyInterface
的 MyPanel
控件。然后我创建了一个自定义 MyTypeDescriptionProvider<T>
并将 MyTypeDescriptionProvider<IMyInterface>
设置为我的控件的 TypeDescriptionProvider
。
这样,当您将 MyPanel
的实例设置为 PropertyGrid
的 SelectedObject
时,只有 IMyInterface
的属性将显示在 PropertyGrid
中.
using System;
using System.ComponentModel;
using System.Windows.Forms;
public interface IMyInterface
{
string MyProperty1 { get; set; }
string MyProperty2 { get; set; }
}
public class MyTypeDescriptionProvider<T> : TypeDescriptionProvider
{
public MyTypeDescriptionProvider() : base(TypeDescriptor.GetProvider(typeof(T))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType,
object instance)
{
return base.GetTypeDescriptor(typeof(T), instance);
}
}
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider<IMyInterface>))]
public class MyPanel : Panel, IMyInterface
{
public string MyProperty1 { get; set; }
public string MyProperty2 { get; set; }
}
注意: 作为重要说明,请记住此类功能对设计时根本没有用。因为在设计时,您需要在设计器中的 PropertyGrid
中显示控件的属性,并且您需要让设计器知道这些属性以便能够为它们序列化值。