如何在PropertyGrid中覆盖DockStyle Editor的行为

时间:2016-03-24 03:00:05

标签: c# winforms custom-controls windows-forms-designer uitypeeditor

我们有一个自定义面板,它继承了Panel,并且具有与SplitContainer Orientation属性类似的Orientation属性。对于我们的自定义面板,DockStyle.Fill永远不会有效,并且根据Orientation属性值,DockStyle需要为Left或Right for Vertical或Top或Bottom for Horizo​​ntal。

DockStyleEditor类是密封的,因此我们不能将它子类化为我们自己的自定义UITypeEditor。有没有办法使用TypeDescriptor或其他方式覆盖某些行为?

我们想要为Property Grid中的自定义面板DockStyle编辑器做的是:
  1.禁用中心填充按钮或使用红色斜杠圆圈显示它以指示它不可用作为选项
  2.当Orientation属性为水平时,禁用顶部和底部按钮   3.当Orientation属性为vertical

时,禁用Left和Right按钮

1 个答案:

答案 0 :(得分:2)

DockEditor已封存,但您可以根据DockEditor创建自定义停靠编辑器,而无需继承它。在自定义UITypeEditor中,您可以创建DockEditor的实例,并使用反射操作其编辑器控件,然后使用它进行值编辑。

DockEditor使用DockUI控件,这是一个私有类。它有一个None按钮和容器控件的复选框,其中包含FillTopLeftRightBottom的复选框。 然后,您只需根据您的逻辑更改EnabledBackColor或其他属性。

在下面的代码中,我会找到这些复选框按钮,我将停用FillTopBottomNone。用户可用的唯一选项是LeftRight

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; }
}

如下图所示,仅左右启用。

enter image description here