我们有一个自定义面板,它继承了Panel,并且具有与SplitContainer Orientation属性类似的Orientation属性。对于我们的自定义面板,DockStyle.Fill永远不会有效,并且根据Orientation属性值,DockStyle需要为Left或Right for Vertical或Top或Bottom for Horizontal。
DockStyleEditor类是密封的,因此我们不能将它子类化为我们自己的自定义UITypeEditor。有没有办法使用TypeDescriptor或其他方式覆盖某些行为?
我们想要为Property Grid中的自定义面板DockStyle编辑器做的是:
1.禁用中心填充按钮或使用红色斜杠圆圈显示它以指示它不可用作为选项
2.当Orientation属性为水平时,禁用顶部和底部按钮
3.当Orientation属性为vertical
答案 0 :(得分:2)
DockEditor
已封存,但您可以根据DockEditor
创建自定义停靠编辑器,而无需继承它。在自定义UITypeEditor
中,您可以创建DockEditor
的实例,并使用反射操作其编辑器控件,然后使用它进行值编辑。
DockEditor
使用DockUI
控件,这是一个私有类。它有一个None
按钮和容器控件的复选框,其中包含Fill
,Top
,Left
,Right
和Bottom
的复选框。
然后,您只需根据您的逻辑更改Enabled
,BackColor
或其他属性。
在下面的代码中,我会找到这些复选框按钮,我将停用Fill
,Top
,Bottom
和None
。用户可用的唯一选项是Left
和Right
:
public class MyDockEditor : UITypeEditor
{
DockEditor editor;
public MyDockEditor()
{
editor = new System.Windows.Forms.Design.DockEditor();
}
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
Type dockUiType = typeof(DockEditor)
.GetNestedType("DockUI", BindingFlags.NonPublic);
var dockUiConstructor = dockUiType.GetConstructors()[0];
var dockUiField = typeof(DockEditor)
.GetField("dockUI", BindingFlags.Instance | BindingFlags.NonPublic);
var dockUiObject = dockUiConstructor.Invoke(new[] { editor }) as Control;
dockUiField.SetValue(editor, dockUiObject);
var container = dockUiObject.Controls[0];
var none = dockUiObject.Controls[1];
var fill= container.Controls[0];
var left= container.Controls[1];
var right= container.Controls[2];
var top = container.Controls[3];
var bottom = container.Controls[4];
none.Enabled = false;
fill.Enabled = false;
top.Enabled = false;
bottom.Enabled = false;
return editor.EditValue(context, provider, value);
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return editor.GetEditStyle(context);
}
}
要使用它,它足以使用Editor属性修饰控件的Dock
属性:
[Editor(typeof(MyDockEditor), typeof(UITypeEditor))]
public override DockStyle Dock
{
get { return base.Dock; }
set { base.Dock = value; }
}
如下图所示,仅左右启用。